luanti_protocol/wire/
packet.rs

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