deepslate_protocol/packet/
play.rs1use crate::types;
7use crate::version::ProtocolVersion;
8
9pub struct PlayPacketIds {
14 pub unsigned_command: i32,
16 pub signed_command: i32,
18 pub start_configuration: i32,
20 pub acknowledge_configuration: i32,
22 pub keep_alive: i32,
24 pub system_chat: i32,
26}
27
28impl PlayPacketIds {
29 #[must_use]
31 pub const fn for_version(version: ProtocolVersion) -> Self {
32 match version {
33 ProtocolVersion::V1_21 => Self {
35 unsigned_command: 0x04,
36 signed_command: 0x05,
37 start_configuration: 0x69,
38 acknowledge_configuration: 0x0C,
39 keep_alive: 0x26,
40 system_chat: 0x6C,
41 },
42 ProtocolVersion::V1_21_2 | ProtocolVersion::V1_21_4 => Self {
44 unsigned_command: 0x05,
45 signed_command: 0x06,
46 start_configuration: 0x70,
47 acknowledge_configuration: 0x0E,
48 keep_alive: 0x27,
49 system_chat: 0x73,
50 },
51 ProtocolVersion::V1_21_5 | ProtocolVersion::V1_21_6 | ProtocolVersion::V1_21_7 => {
53 Self {
54 unsigned_command: 0x05,
55 signed_command: 0x06,
56 start_configuration: 0x6F,
57 acknowledge_configuration: 0x0E,
58 keep_alive: 0x26,
59 system_chat: 0x72,
60 }
61 }
62 ProtocolVersion::V1_21_9 | ProtocolVersion::V1_21_11 => Self {
64 unsigned_command: 0x06,
65 signed_command: 0x07,
66 start_configuration: 0x74,
67 acknowledge_configuration: 0x0F,
68 keep_alive: 0x2B,
69 system_chat: 0x77,
70 },
71 }
72 }
73}
74
75pub struct ConfigPacketIds;
77
78impl ConfigPacketIds {
79 pub const FINISHED_CONFIGURATION_CLIENTBOUND: i32 = 0x03;
82
83 pub const FINISHED_CONFIGURATION_SERVERBOUND: i32 = 0x03;
86
87 pub const DISCONNECT: i32 = 0x02;
90}
91
92#[must_use]
101pub fn parse_command_from_unsigned(payload: &[u8]) -> Option<String> {
102 let mut cursor = payload;
103 types::read_string(&mut cursor).ok()
104}
105
106#[must_use]
115pub fn parse_command_from_signed(payload: &[u8]) -> Option<String> {
116 parse_command_from_unsigned(payload)
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_packet_ids_differ_per_version() {
126 let v121 = PlayPacketIds::for_version(ProtocolVersion::V1_21);
127 let v12111 = PlayPacketIds::for_version(ProtocolVersion::V1_21_11);
128
129 assert_ne!(v121.start_configuration, v12111.start_configuration);
131 assert_ne!(v121.system_chat, v12111.system_chat);
132 }
133
134 #[test]
135 fn test_1_21_6_inherits_from_1_21_5() {
136 let v1215 = PlayPacketIds::for_version(ProtocolVersion::V1_21_5);
137 let v1216 = PlayPacketIds::for_version(ProtocolVersion::V1_21_6);
138
139 assert_eq!(v1215.start_configuration, v1216.start_configuration);
140 assert_eq!(v1215.keep_alive, v1216.keep_alive);
141 assert_eq!(v1215.system_chat, v1216.system_chat);
142 }
143
144 #[test]
145 fn test_1_21_11_inherits_from_1_21_9() {
146 let v1219 = PlayPacketIds::for_version(ProtocolVersion::V1_21_9);
147 let v12111 = PlayPacketIds::for_version(ProtocolVersion::V1_21_11);
148
149 assert_eq!(v1219.unsigned_command, v12111.unsigned_command);
150 assert_eq!(v1219.start_configuration, v12111.start_configuration);
151 assert_eq!(v1219.keep_alive, v12111.keep_alive);
152 assert_eq!(v1219.system_chat, v12111.system_chat);
153 }
154
155 #[test]
156 fn test_parse_command_from_unsigned() {
157 let mut buf = Vec::new();
158 crate::types::write_string(&mut buf, "server lobby");
159 let cmd = parse_command_from_unsigned(&buf).unwrap();
160 assert_eq!(cmd, "server lobby");
161 }
162
163 #[test]
164 fn test_parse_command_from_signed() {
165 let mut buf = Vec::new();
166 crate::types::write_string(&mut buf, "server survival");
167 buf.extend_from_slice(&[0u8; 32]);
168 let cmd = parse_command_from_signed(&buf).unwrap();
169 assert_eq!(cmd, "server survival");
170 }
171}