Skip to main content

raknet_rust/protocol/
ack.rs

1use bytes::{Buf, BufMut};
2
3use crate::error::{DecodeError, EncodeError};
4
5use super::codec::RaknetCodec;
6use super::constants::MAX_ACK_SEQUENCES;
7use super::sequence24::Sequence24;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct SequenceRange {
11    pub start: Sequence24,
12    pub end: Sequence24,
13}
14
15impl SequenceRange {
16    pub fn wraps(self) -> bool {
17        self.start != self.end && self.start.value() > self.end.value()
18    }
19
20    pub fn split_wrapping(self) -> Option<(SequenceRange, SequenceRange)> {
21        if !self.wraps() {
22            return None;
23        }
24
25        let tail = SequenceRange {
26            start: self.start,
27            end: Sequence24::new(0x00FF_FFFF),
28        };
29
30        let head = SequenceRange {
31            start: Sequence24::new(0),
32            end: self.end,
33        };
34
35        Some((tail, head))
36    }
37
38    pub fn record_count(self) -> usize {
39        if self.wraps() { 2 } else { 1 }
40    }
41
42    pub fn encoded_size(self) -> usize {
43        if self.start == self.end {
44            1 + 3
45        } else {
46            1 + 3 + 3
47        }
48    }
49}
50
51impl RaknetCodec for SequenceRange {
52    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
53        let singleton = self.start == self.end;
54        singleton.encode_raknet(dst)?;
55        self.start.encode_raknet(dst)?;
56        if !singleton {
57            self.end.encode_raknet(dst)?;
58        }
59        Ok(())
60    }
61
62    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
63        let singleton = bool::decode_raknet(src)?;
64        let start = Sequence24::decode_raknet(src)?;
65        let end = if singleton {
66            start
67        } else {
68            Sequence24::decode_raknet(src)?
69        };
70
71        Ok(Self { start, end })
72    }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Default)]
76pub struct AckNackPayload {
77    pub ranges: Vec<SequenceRange>,
78}
79
80impl AckNackPayload {
81    pub fn encoded_size(&self) -> usize {
82        let mut size = 2usize;
83        for r in &self.ranges {
84            if let Some((a, b)) = r.split_wrapping() {
85                size += a.encoded_size() + b.encoded_size();
86            } else {
87                size += r.encoded_size();
88            }
89        }
90        size
91    }
92}
93
94impl RaknetCodec for AckNackPayload {
95    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
96        let record_count: usize = self.ranges.iter().map(|r| r.record_count()).sum();
97        if record_count > MAX_ACK_SEQUENCES as usize {
98            return Err(EncodeError::AckRecordOverflow(record_count));
99        }
100
101        (record_count as u16).encode_raknet(dst)?;
102        for range in &self.ranges {
103            if let Some((left, right)) = range.split_wrapping() {
104                left.encode_raknet(dst)?;
105                right.encode_raknet(dst)?;
106            } else {
107                range.encode_raknet(dst)?;
108            }
109        }
110        Ok(())
111    }
112
113    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
114        let count = u16::decode_raknet(src)?;
115        if count > MAX_ACK_SEQUENCES {
116            return Err(DecodeError::InvalidAckRangeCount(count));
117        }
118
119        let mut ranges = Vec::with_capacity(count as usize);
120        for _ in 0..count {
121            ranges.push(SequenceRange::decode_raknet(src)?);
122        }
123
124        Ok(Self { ranges })
125    }
126}