Skip to main content

raknet_rust/protocol/
frame.rs

1use bytes::{Buf, BufMut, Bytes};
2
3use crate::error::{DecodeError, EncodeError};
4
5use super::codec::RaknetCodec;
6use super::constants::MAX_SPLIT_PARTS;
7use super::frame_header::FrameHeader;
8use super::sequence24::Sequence24;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct SplitInfo {
12    pub part_count: u32,
13    pub part_id: u16,
14    pub part_index: u32,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Frame {
19    pub header: FrameHeader,
20    pub bit_length: u16,
21    pub reliable_index: Option<Sequence24>,
22    pub sequence_index: Option<Sequence24>,
23    pub ordering_index: Option<Sequence24>,
24    pub ordering_channel: Option<u8>,
25    pub split: Option<SplitInfo>,
26    pub payload: Bytes,
27}
28
29impl Frame {
30    pub fn payload_len(&self) -> usize {
31        ((self.bit_length as usize) + 7) >> 3
32    }
33
34    pub fn encoded_size(&self) -> usize {
35        let mut size = 3usize;
36        let rel = self.header.reliability;
37
38        if rel.is_reliable() {
39            size += 3;
40        }
41        if rel.is_sequenced() {
42            size += 3;
43        }
44        if rel.is_ordered() || rel.is_sequenced() {
45            size += 4;
46        }
47        if self.header.is_split {
48            size += 10;
49        }
50
51        size + self.payload_len()
52    }
53}
54
55impl RaknetCodec for Frame {
56    fn encode_raknet(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
57        if self.payload_len() != self.payload.len() {
58            return Err(EncodeError::FrameBitLengthMismatch);
59        }
60
61        self.header.encode_raknet(dst)?;
62        self.bit_length.encode_raknet(dst)?;
63
64        let rel = self.header.reliability;
65        if rel.is_reliable() {
66            self.reliable_index
67                .ok_or(EncodeError::MissingReliableIndex)?
68                .encode_raknet(dst)?;
69        }
70        if rel.is_sequenced() {
71            self.sequence_index
72                .ok_or(EncodeError::MissingSequenceIndex)?
73                .encode_raknet(dst)?;
74        }
75        if rel.is_ordered() || rel.is_sequenced() {
76            self.ordering_index
77                .ok_or(EncodeError::MissingOrderingIndex)?
78                .encode_raknet(dst)?;
79            self.ordering_channel
80                .ok_or(EncodeError::MissingOrderingChannel)?
81                .encode_raknet(dst)?;
82        }
83
84        if self.header.is_split {
85            let split = self.split.as_ref().ok_or(EncodeError::MissingSplitInfo)?;
86            split.part_count.encode_raknet(dst)?;
87            split.part_id.encode_raknet(dst)?;
88            split.part_index.encode_raknet(dst)?;
89        }
90
91        dst.put_slice(&self.payload);
92        Ok(())
93    }
94
95    fn decode_raknet(src: &mut impl Buf) -> Result<Self, DecodeError> {
96        let header = FrameHeader::decode_raknet(src)?;
97        let bit_length = u16::decode_raknet(src)?;
98        let payload_len = ((bit_length as usize) + 7) >> 3;
99        if payload_len == 0 {
100            return Err(DecodeError::InvalidFrameBitLength(bit_length));
101        }
102
103        let rel = header.reliability;
104
105        let reliable_index = if rel.is_reliable() {
106            Some(Sequence24::decode_raknet(src)?)
107        } else {
108            None
109        };
110
111        let sequence_index = if rel.is_sequenced() {
112            Some(Sequence24::decode_raknet(src)?)
113        } else {
114            None
115        };
116
117        let (ordering_index, ordering_channel) = if rel.is_ordered() || rel.is_sequenced() {
118            (
119                Some(Sequence24::decode_raknet(src)?),
120                Some(u8::decode_raknet(src)?),
121            )
122        } else {
123            (None, None)
124        };
125
126        let split = if header.is_split {
127            let part_count = u32::decode_raknet(src)?;
128            if part_count == 0 {
129                return Err(DecodeError::SplitCountZero);
130            }
131            if part_count > MAX_SPLIT_PARTS {
132                return Err(DecodeError::SplitIndexOutOfRange);
133            }
134
135            let part_id = u16::decode_raknet(src)?;
136            let part_index = u32::decode_raknet(src)?;
137            if part_index >= part_count {
138                return Err(DecodeError::SplitIndexOutOfRange);
139            }
140
141            Some(SplitInfo {
142                part_count,
143                part_id,
144                part_index,
145            })
146        } else {
147            None
148        };
149
150        if src.remaining() < payload_len {
151            return Err(DecodeError::UnexpectedEof);
152        }
153        let payload = src.copy_to_bytes(payload_len);
154
155        Ok(Self {
156            header,
157            bit_length,
158            reliable_index,
159            sequence_index,
160            ordering_index,
161            ordering_channel,
162            split,
163            payload,
164        })
165    }
166}