Skip to main content

classicube_relay/packet/
start.rs

1use std::io::{Read, Write};
2
3use byteorder::{NetworkEndian, ReadBytesExt, WriteBytesExt};
4
5use super::{FlagsError, Packet, ScopeError, flags::Flags, scope::Scope};
6
7#[derive(Debug, thiserror::Error)]
8pub enum StartPacketError {
9    #[error("wrong data_part len")]
10    DataPartLength,
11
12    #[error("couldn't read full data_part")]
13    ReadFullDataPart,
14
15    #[error(transparent)]
16    Flags(#[from] FlagsError),
17
18    #[error(transparent)]
19    Scope(#[from] ScopeError),
20
21    #[error(transparent)]
22    Io(#[from] std::io::Error),
23}
24type Result<T> = std::result::Result<T, StartPacketError>;
25
26#[derive(Debug, PartialEq, Eq)]
27pub struct StartPacket {
28    pub stream_id: u8,
29    // this is always Player if sending from server
30    pub scope: Scope,
31    pub data_length: u16,
32    // [u8; 64 - 2 * 2 - 1]
33    pub data_part: Vec<u8>,
34}
35impl StartPacket {
36    pub const DATA_PART_LENGTH: usize = 64 - 2 * 2 - 1;
37
38    pub fn new<S: Into<Scope>>(
39        stream_id: u8,
40        scope: S,
41        data_length: u16,
42        data_part: Vec<u8>,
43    ) -> Result<Self> {
44        if data_part.len() != Self::DATA_PART_LENGTH {
45            return Err(StartPacketError::DataPartLength);
46        }
47
48        Ok(Self {
49            stream_id,
50            scope: scope.into(),
51            data_length,
52            data_part,
53        })
54    }
55
56    pub fn new_reader<S: Into<Scope>>(
57        stream_id: u8,
58        scope: S,
59        data_length: u16,
60        data_stream: &mut impl Read,
61    ) -> Result<Self> {
62        let mut data_part = Vec::with_capacity(Packet::DATA_LENGTH);
63
64        let mut buf = [0; Self::DATA_PART_LENGTH];
65        let n = data_stream.read(&mut buf)?;
66
67        data_part.write_all(&buf[..n])?;
68        data_part.resize(Self::DATA_PART_LENGTH, 0);
69
70        Self::new(stream_id, scope, data_length, data_part)
71    }
72
73    pub fn encode(&self) -> Result<Vec<u8>> {
74        let mut data = Vec::with_capacity(Packet::DATA_LENGTH);
75
76        data.write_all(
77            &Flags {
78                is_packet_start: true,
79                stream_id: self.stream_id,
80            }
81            .encode()?,
82        )?;
83        data.write_all(&self.scope.encode()?)?;
84        data.write_u16::<NetworkEndian>(self.data_length)?;
85        data.write_all(&self.data_part)?;
86
87        Ok(data)
88    }
89
90    pub(crate) fn decode(stream_id: u8, data_stream: &mut impl Read) -> Result<Self> {
91        let scope = Scope::decode(data_stream)?;
92        let data_length = data_stream.read_u16::<NetworkEndian>()?;
93
94        let mut data_part = [0; Self::DATA_PART_LENGTH];
95        let n = data_stream.read(&mut data_part)?;
96
97        if n != Self::DATA_PART_LENGTH {
98            return Err(StartPacketError::ReadFullDataPart);
99        }
100
101        Ok(Self {
102            stream_id,
103            scope,
104            data_length,
105            data_part: data_part.to_vec(),
106        })
107    }
108}