raknet_rust/protocol/
ack.rs1use 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}