minetest_protocol/wire/
packet.rs

1use anyhow::bail;
2
3use super::command::Command;
4use super::deser::Deserialize;
5use super::deser::DeserializeError;
6use super::deser::DeserializeResult;
7use super::deser::Deserializer;
8use super::ser::Serialize;
9use super::ser::SerializeResult;
10use super::ser::Serializer;
11
12pub const PROTOCOL_ID: u32 = 0x4f457403;
13
14pub const LATEST_PROTOCOL_VERSION: u16 = 41;
15
16// Serialization format of map data
17pub const SER_FMT_HIGHEST_READ: u8 = 29;
18pub const SER_FMT_HIGHEST_WRITE: u8 = 29;
19pub const SER_FMT_LOWEST_READ: u8 = 28;
20pub const SER_FMT_LOWEST_WRITE: u8 = 29;
21
22pub const MAX_PACKET_SIZE: usize = 512;
23pub const SEQNUM_INITIAL: u16 = 65500;
24pub const PACKET_HEADER_SIZE: usize = 7;
25pub const RELIABLE_HEADER_SIZE: usize = 3;
26pub const SPLIT_HEADER_SIZE: usize = 7;
27pub const MAX_ORIGINAL_BODY_SIZE: usize =
28    MAX_PACKET_SIZE - PACKET_HEADER_SIZE - RELIABLE_HEADER_SIZE;
29pub const MAX_SPLIT_BODY_SIZE: usize = MAX_ORIGINAL_BODY_SIZE - SPLIT_HEADER_SIZE;
30
31pub type PeerId = u16;
32
33#[derive(Debug, Clone, PartialEq)]
34pub struct AckBody {
35    pub seqnum: u16,
36}
37
38impl AckBody {
39    pub fn new(seqnum: u16) -> Self {
40        AckBody { seqnum }
41    }
42    pub fn into_inner(self) -> InnerBody {
43        InnerBody::Control(ControlBody::Ack(self))
44    }
45}
46
47impl Serialize for AckBody {
48    type Input = Self;
49    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
50        u16::serialize(&value.seqnum, ser)
51    }
52}
53
54impl Deserialize for AckBody {
55    type Output = Self;
56    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
57        Ok(Self {
58            seqnum: u16::deserialize(deser)?,
59        })
60    }
61}
62
63#[derive(Debug, Clone, PartialEq)]
64pub struct SetPeerIdBody {
65    pub peer_id: u16,
66}
67
68impl SetPeerIdBody {
69    pub fn new(peer_id: u16) -> Self {
70        Self { peer_id }
71    }
72
73    pub fn into_inner(self) -> InnerBody {
74        InnerBody::Control(ControlBody::SetPeerId(self))
75    }
76}
77
78impl Serialize for SetPeerIdBody {
79    type Input = Self;
80    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
81        u16::serialize(&value.peer_id, ser)
82    }
83}
84
85impl Deserialize for SetPeerIdBody {
86    type Output = Self;
87    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
88        Ok(Self {
89            peer_id: u16::deserialize(deser)?,
90        })
91    }
92}
93
94#[derive(Debug, Clone, PartialEq)]
95pub enum ControlBody {
96    Ack(AckBody),
97    SetPeerId(SetPeerIdBody),
98    Ping,
99    Disconnect,
100}
101
102impl ControlBody {
103    pub fn into_inner(self) -> InnerBody {
104        InnerBody::Control(self)
105    }
106}
107
108impl Serialize for ControlBody {
109    type Input = Self;
110    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
111        use ControlBody::*;
112        let control_type = match value {
113            Ack(_) => 0,
114            SetPeerId(_) => 1,
115            Ping => 2,
116            Disconnect => 3,
117        };
118        u8::serialize(&control_type, ser)?;
119        match value {
120            Ack(body) => AckBody::serialize(body, ser)?,
121            SetPeerId(body) => SetPeerIdBody::serialize(body, ser)?,
122            Ping => (),
123            Disconnect => (),
124        };
125        Ok(())
126    }
127}
128
129impl Deserialize for ControlBody {
130    type Output = Self;
131
132    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
133        use ControlBody::*;
134        let control_type = u8::deserialize(deser)?;
135        match control_type {
136            0 => Ok(Ack(AckBody::deserialize(deser)?)),
137            1 => Ok(SetPeerId(SetPeerIdBody::deserialize(deser)?)),
138            2 => Ok(Ping),
139            3 => Ok(Disconnect),
140            _ => bail!(DeserializeError::InvalidValue(String::from(
141                "Invalid control_type in ControlBody",
142            ))),
143        }
144    }
145}
146
147#[derive(Debug, Clone, PartialEq)]
148pub struct OriginalBody {
149    pub command: Command,
150}
151
152impl Serialize for OriginalBody {
153    type Input = Self;
154    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
155        Command::serialize(&value.command, ser)
156    }
157}
158
159impl Deserialize for OriginalBody {
160    type Output = Self;
161    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
162        Ok(OriginalBody {
163            command: Command::deserialize(deser)?,
164        })
165    }
166}
167
168#[derive(Debug, Clone, PartialEq)]
169pub struct SplitBody {
170    pub seqnum: u16,
171    pub chunk_count: u16,
172    pub chunk_num: u16,
173    pub chunk_data: Vec<u8>,
174}
175
176impl Serialize for SplitBody {
177    type Input = Self;
178    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
179        u16::serialize(&value.seqnum, ser)?;
180        u16::serialize(&value.chunk_count, ser)?;
181        u16::serialize(&value.chunk_num, ser)?;
182        ser.write_bytes(&value.chunk_data)?;
183        Ok(())
184    }
185}
186
187impl Deserialize for SplitBody {
188    type Output = Self;
189
190    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
191        Ok(SplitBody {
192            seqnum: u16::deserialize(deser)?,
193            chunk_count: u16::deserialize(deser)?,
194            chunk_num: u16::deserialize(deser)?,
195            chunk_data: Vec::from(deser.take_all()),
196        })
197    }
198}
199
200#[derive(Debug, Clone, PartialEq)]
201pub struct ReliableBody {
202    pub seqnum: u16,
203    pub inner: InnerBody,
204}
205
206impl Serialize for ReliableBody {
207    type Input = Self;
208    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
209        let packet_type: u8 = 3;
210        u8::serialize(&packet_type, ser)?;
211        u16::serialize(&value.seqnum, ser)?;
212        InnerBody::serialize(&value.inner, ser)?;
213        Ok(())
214    }
215}
216
217impl Deserialize for ReliableBody {
218    type Output = Self;
219    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
220        let packet_type = u8::deserialize(deser)?;
221        if packet_type != 3 {
222            bail!(DeserializeError::InvalidValue(
223                "Invalid packet_type for ReliableBody".to_string(),
224            ))
225        }
226        Ok(ReliableBody {
227            seqnum: u16::deserialize(deser)?,
228            inner: InnerBody::deserialize(deser)?,
229        })
230    }
231}
232
233#[derive(Debug, Clone, PartialEq)]
234pub enum InnerBody {
235    Control(ControlBody),
236    Original(OriginalBody),
237    Split(SplitBody),
238}
239
240impl InnerBody {
241    pub fn command_ref(&self) -> Option<&Command> {
242        match self {
243            InnerBody::Original(body) => Some(&body.command),
244            _ => None,
245        }
246    }
247
248    pub fn into_reliable(self, seqnum: u16) -> PacketBody {
249        PacketBody::Reliable(ReliableBody {
250            seqnum: seqnum,
251            inner: self,
252        })
253    }
254
255    pub fn into_unreliable(self) -> PacketBody {
256        PacketBody::Inner(self)
257    }
258
259    /// Get a reference to the Command this body contains, if any.
260    /// If this is part of a split packet, None will be returned
261    /// even though there is a fragment of a Command inside.
262    pub fn command(&self) -> Option<&Command> {
263        match self {
264            InnerBody::Control(_) => None,
265            InnerBody::Original(body) => Some(&body.command),
266            InnerBody::Split(_) => None,
267        }
268    }
269}
270
271impl Serialize for InnerBody {
272    type Input = Self;
273    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
274        use InnerBody::*;
275        let packet_type: u8 = match value {
276            Control(..) => 0,
277            Original(..) => 1,
278            Split(..) => 2,
279        };
280        u8::serialize(&packet_type, ser)?;
281        match value {
282            Control(b) => ControlBody::serialize(b, ser),
283            Original(b) => OriginalBody::serialize(b, ser),
284            Split(b) => SplitBody::serialize(b, ser),
285        }
286    }
287}
288
289impl Deserialize for InnerBody {
290    type Output = Self;
291
292    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
293        use InnerBody::*;
294        let packet_type = u8::deserialize(deser)?;
295        match packet_type {
296            0 => Ok(Control(ControlBody::deserialize(deser)?)),
297            1 => Ok(Original(OriginalBody::deserialize(deser)?)),
298            2 => Ok(Split(SplitBody::deserialize(deser)?)),
299            _ => bail!(DeserializeError::InvalidPacketKind(packet_type)),
300        }
301    }
302}
303
304#[derive(Debug, Clone, PartialEq)]
305pub enum PacketBody {
306    Reliable(ReliableBody),
307    Inner(InnerBody),
308}
309
310impl PacketBody {
311    pub fn inner(&self) -> &InnerBody {
312        match self {
313            PacketBody::Reliable(body) => &body.inner,
314            PacketBody::Inner(inner) => &inner,
315        }
316    }
317
318    pub fn command_ref(&self) -> Option<&Command> {
319        self.inner().command_ref()
320    }
321}
322
323impl Serialize for PacketBody {
324    type Input = Self;
325    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
326        use PacketBody::*;
327        // Both ReliableBody and InnerBody will emit their own packet type.
328        match value {
329            Reliable(body) => ReliableBody::serialize(body, ser),
330            Inner(inner) => InnerBody::serialize(inner, ser),
331        }
332    }
333}
334
335impl Deserialize for PacketBody {
336    type Output = Self;
337    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
338        use PacketBody::*;
339        // Both ReliableBody and InnerBody expect to consume the packet type tag.
340        // So only peek it.
341        let packet_type = deser.peek(1)?[0];
342        match packet_type {
343            3 => Ok(Reliable(ReliableBody::deserialize(deser)?)),
344            _ => Ok(Inner(InnerBody::deserialize(deser)?)),
345        }
346    }
347}
348
349#[derive(Debug, Clone, PartialEq)]
350pub struct Packet {
351    pub protocol_id: u32,
352    pub sender_peer_id: PeerId,
353    pub channel: u8,
354    pub body: PacketBody,
355}
356
357impl Packet {
358    pub fn new(sender_peer_id: PeerId, channel: u8, body: PacketBody) -> Self {
359        Self {
360            protocol_id: PROTOCOL_ID,
361            sender_peer_id,
362            channel,
363            body,
364        }
365    }
366
367    pub fn inner(&self) -> &InnerBody {
368        self.body.inner()
369    }
370
371    pub fn as_reliable(&self) -> Option<&ReliableBody> {
372        match &self.body {
373            PacketBody::Reliable(rb) => Some(rb),
374            PacketBody::Inner(_) => None,
375        }
376    }
377
378    pub fn as_control(&self) -> Option<&ControlBody> {
379        match self.inner() {
380            InnerBody::Control(control) => Some(&control),
381            InnerBody::Original(_) => None,
382            InnerBody::Split(_) => None,
383        }
384    }
385}
386
387impl Serialize for Packet {
388    type Input = Self;
389    fn serialize<S: Serializer>(value: &Self::Input, ser: &mut S) -> SerializeResult {
390        u32::serialize(&value.protocol_id, ser)?;
391        u16::serialize(&value.sender_peer_id, ser)?;
392        u8::serialize(&value.channel, ser)?;
393        PacketBody::serialize(&value.body, ser)?;
394        Ok(())
395    }
396}
397
398impl Deserialize for Packet {
399    type Output = Self;
400    fn deserialize(deser: &mut Deserializer) -> DeserializeResult<Self> {
401        let pkt = Packet {
402            protocol_id: u32::deserialize(deser)?,
403            sender_peer_id: PeerId::deserialize(deser)?,
404            channel: u8::deserialize(deser)?,
405            body: PacketBody::deserialize(deser)?,
406        };
407        if pkt.protocol_id != PROTOCOL_ID {
408            bail!(DeserializeError::InvalidProtocolId(pkt.protocol_id))
409        }
410        if !(0..=2).contains(&pkt.channel) {
411            bail!(DeserializeError::InvalidChannel(pkt.channel))
412        }
413        Ok(pkt)
414    }
415}