cubic_protocol/
packet_primitive.rs

1use cubic_chat::component::ComponentType;
2use cubic_chat::identifier::Identifier;
3use serde::de::DeserializeOwned;
4use serde::Serialize;
5use uuid::Uuid;
6use crate::packet::{CustomError, InputPacketBytes, OutputPacketBytes, PacketReadable, PacketReadableResult, PacketWritable, PacketWritableResult};
7use crate::types::{Angle, BlockPosition, LengthProvidedArray, ProtocolJson, RemainingBytesArray, VarInt, VarLong};
8
9#[async_trait::async_trait]
10impl PacketReadable for u8 {
11    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
12        input.take_byte().await.map_err(|err| err.into())
13    }
14}
15
16#[async_trait::async_trait]
17impl PacketWritable for u8 {
18    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
19        output.write_byte(self).await.map_err(|err| CustomError::Error(err).into())
20    }
21}
22
23#[async_trait::async_trait]
24impl PacketReadable for i8 {
25    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
26        u8::read(input).await.map(|val| val as i8)
27    }
28}
29
30#[async_trait::async_trait]
31impl PacketWritable for i8 {
32    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
33        (self as u8).write(output).await
34    }
35}
36
37#[async_trait::async_trait]
38impl PacketReadable for bool {
39    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
40        u8::read(input).await.map(|val| val != 0)
41    }
42}
43
44#[async_trait::async_trait]
45impl PacketWritable for bool {
46    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
47        match self {
48            true => 1_u8,
49            false => 0_u8
50        }.write(output).await
51    }
52}
53
54#[async_trait::async_trait]
55impl PacketReadable for Angle {
56    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
57        let angle_value = u8::read(input).await? as f32;
58        Ok(Angle::radians(angle_value * std::f32::consts::PI / 256.0))
59    }
60}
61
62#[async_trait::async_trait]
63impl PacketWritable for Angle {
64    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
65        ((self.radians * 256.0 / std::f32::consts::PI) as u8).write(output).await
66    }
67}
68
69const STRING_LIMIT: i32 = 32767;
70const CHAT_LIMIT: i32 = 262144;
71
72async fn read_string_with_limit(input: &mut impl InputPacketBytes, limit: i32) -> PacketReadableResult<String> {
73    let length = i32::from(VarInt::read(input).await?);
74    match length > limit {
75        true => Err(CustomError::StaticStr("String is too big").into()),
76        false => {
77            let mut bytes = Vec::with_capacity(length as usize);
78            unsafe { bytes.set_len(length as usize); }
79            input.take_slice(&mut bytes).await?;
80            Ok(std::str::from_utf8(bytes.as_slice())
81                .map_err(|err| CustomError::Error(Box::new(err)))?
82                .into()
83            )
84        }
85    }
86}
87
88async fn write_string_with_limit(output: &mut impl OutputPacketBytes, str: &str, limit: i32) -> PacketWritableResult {
89    let str_len = str.len() as i32;
90    match str_len > limit {
91        true => Err(CustomError::StaticStr("String is too big").into()),
92        false => {
93            VarInt(str_len).write(output).await?;
94            output.write_bytes(str.as_bytes()).await
95                .map_err(|err| CustomError::Error(err).into())
96        }
97    }
98}
99
100#[async_trait::async_trait]
101impl PacketReadable for String {
102    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
103        read_string_with_limit(input, STRING_LIMIT).await
104    }
105}
106
107#[async_trait::async_trait]
108impl PacketWritable for String {
109    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
110        self.as_str().write(output).await
111    }
112}
113
114#[async_trait::async_trait]
115impl PacketWritable for &str {
116    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
117        write_string_with_limit(output, self, STRING_LIMIT).await
118    }
119}
120
121#[async_trait::async_trait]
122impl PacketReadable for BlockPosition {
123    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
124        let value = u64::read(input).await?;
125        let mut x = (value >> 38) as i32;
126        let mut y = (value & 0xFFF) as i32;
127        let mut z = ((value >> 12) & 0x3FFFFFF) as i32;
128        if x >= 0x2000000 {
129            x -= 0x4000000
130        }
131        if y >= 0x800 {
132            y -= 0x1000
133        }
134        if z >= 0x2000000 {
135            z -= 0x4000000
136        }
137        Ok(Self::new(x, y, z))
138    }
139}
140
141#[async_trait::async_trait]
142impl PacketWritable for BlockPosition {
143    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
144        let x = self.x as i64;
145        let y = self.y as i64;
146        let z = self.z as i64;
147        (((x & 0x3FFFFFF) << 38) |
148            ((z & 0x3FFFFFF) << 12) |
149            (y & 0xFFF)
150        ).write(output).await
151    }
152}
153
154#[async_trait::async_trait]
155impl PacketReadable for Identifier {
156    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
157        Ok(Identifier::from_full(String::read(input).await?)
158            .map_err(|err| CustomError::Error(Box::new(err)))?
159        )
160    }
161}
162
163#[async_trait::async_trait]
164impl PacketWritable for Identifier {
165    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
166        self.to_string().write(output).await
167    }
168}
169
170#[async_trait::async_trait]
171impl PacketReadable for ComponentType {
172    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
173        let str = read_string_with_limit(input, CHAT_LIMIT).await?;
174        serde_json::from_str(str.as_str())
175            .map_err(|err| CustomError::Error(Box::new(err)).into())
176    }
177}
178
179#[async_trait::async_trait]
180impl PacketWritable for ComponentType {
181    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
182        let str = serde_json::to_string(&self)
183            .map_err(|err| CustomError::Error(Box::new(err)))?;
184        write_string_with_limit(output, &str, CHAT_LIMIT).await
185    }
186}
187
188#[async_trait::async_trait]
189impl<T: DeserializeOwned> PacketReadable for ProtocolJson<T> {
190    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
191        serde_json::from_str(String::read(input).await?.as_str())
192            .map_err(|err| CustomError::Error(Box::new(err)).into())
193            .map(|val| ProtocolJson::new(val))
194    }
195}
196
197#[async_trait::async_trait]
198impl<T: Serialize + Send + Sync> PacketWritable for ProtocolJson<T> {
199    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
200        let str = serde_json::to_string(self.get())
201            .map_err(|err| CustomError::Error(Box::new(err)))?;
202        str.write(output).await
203    }
204}
205
206#[async_trait::async_trait]
207impl PacketReadable for Uuid {
208    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
209        let mut bytes = [0_u8; std::mem::size_of::<u128>()];
210        input.take_slice(&mut bytes).await?;
211        Uuid::from_slice(&bytes)
212            .map_err(|err| CustomError::Error(Box::new(err)).into())
213    }
214}
215
216#[async_trait::async_trait]
217impl PacketWritable for Uuid {
218    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
219        output.write_bytes(self.as_bytes()).await
220            .map_err(|err| CustomError::Error(err).into())
221    }
222}
223
224#[async_trait::async_trait]
225impl<T: PacketReadable> PacketReadable for Option<T> {
226    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
227        let present = bool::read(input).await?;
228        match present {
229            true => Ok(Some(T::read(input).await?)),
230            false => Ok(None),
231        }
232    }
233}
234
235#[async_trait::async_trait]
236impl<T: PacketWritable + Send + Sync> PacketWritable for Option<T> {
237    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
238        match self {
239            Some(val) => {
240                true.write(output).await?;
241                val.write(output).await
242            }
243            None => false.write(output).await
244        }
245    }
246}
247
248pub async fn read_vec<T: PacketReadable>(
249    length: usize, input: &mut impl InputPacketBytes) -> PacketReadableResult<Vec<T>> {
250    let mut result = Vec::with_capacity(length);
251    for _ in 0..length {
252        result.push(T::read(input).await?);
253    }
254    Ok(result)
255}
256
257pub async fn write_vec<T: PacketWritable>(
258    vec: Vec<T>, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
259    for value in vec {
260        value.write(output).await?
261    }
262    Ok(())
263}
264
265#[async_trait::async_trait]
266impl<T: PacketReadable + Send + Sync> PacketReadable for RemainingBytesArray<T> {
267    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
268        let length = input.remaining_bytes();
269        Ok(RemainingBytesArray::new(read_vec(length, input).await?))
270    }
271}
272
273#[async_trait::async_trait]
274impl<T: PacketWritable + Send + Sync> PacketWritable for RemainingBytesArray<T> {
275    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
276        write_vec(self.value, output).await?;
277        Ok(())
278    }
279}
280
281pub trait USizePossible {
282    fn into_usize(self) -> usize;
283
284    fn from_usize(value: usize) -> Self;
285}
286
287#[async_trait::async_trait]
288impl<T: PacketReadable + Send + Sync, S: PacketReadable + USizePossible> PacketReadable for LengthProvidedArray<T, S> {
289    async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
290        let length = S::read(input).await?.into_usize();
291        Ok(LengthProvidedArray::new(read_vec(length, input).await?))
292    }
293}
294
295#[async_trait::async_trait]
296impl<T: PacketWritable + Send + Sync,
297    S: PacketWritable + USizePossible + Send + Sync> PacketWritable for LengthProvidedArray<T, S> {
298    async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
299        S::from_usize(self.value.len()).write(output).await?;
300        write_vec(self.value, output).await
301    }
302}
303
304macro_rules! num {
305    ($type: ty) => {
306        impl USizePossible for $type {
307            fn into_usize(self) -> usize {
308                self as usize
309            }
310
311            fn from_usize(value: usize) -> Self {
312                value as Self
313            }
314        }
315
316        #[async_trait::async_trait]
317        impl PacketReadable for $type {
318            async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
319                let mut bytes = [0_u8; std::mem::size_of::<Self>()];
320                input.take_slice(&mut bytes).await?;
321                Ok(Self::from_be_bytes(bytes))
322            }
323        }
324
325        #[async_trait::async_trait]
326        impl PacketWritable for $type {
327            async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
328                output.write_bytes(&self.to_be_bytes()).await
329                    .map_err(|err| CustomError::Error(err).into())
330            }
331        }
332    };
333    ($($type: ty$(,)*)*) => {
334        $(num!($type);)*
335    }
336}
337
338macro_rules! var_num {
339    ($var_num_type: ty, $num_type: ty, $unsigned_num_type: ty) => {
340        impl USizePossible for $var_num_type {
341            fn into_usize(self) -> usize {
342                <$num_type>::from(self) as usize
343            }
344
345            fn from_usize(value: usize) -> Self {
346                <$var_num_type>::from(value as $num_type)
347            }
348        }
349
350        #[async_trait::async_trait]
351        impl PacketReadable for $var_num_type {
352            async fn read(input: &mut impl InputPacketBytes) -> PacketReadableResult<Self> {
353                const BITS: u8 = (std::mem::size_of::<$num_type>() * 8) as u8;
354                let mut result: $num_type = 0;
355                let mut position: u8 = 0;
356                loop {
357                    let current_byte = input.take_byte().await?;
358                    result |= ((current_byte & 0x7F) as $num_type) << position;
359                    if ((current_byte & 0x80) == 0) {
360                        break;
361                    }
362                    position += 7;
363                    if (position >= BITS) {
364                        return Err(CustomError::StaticStr("Var num is too big").into());
365                    }
366                }
367                Ok(<$var_num_type>::from(result))
368            }
369        }
370
371        #[async_trait::async_trait]
372        impl PacketWritable for $var_num_type {
373            async fn write(self, output: &mut impl OutputPacketBytes) -> PacketWritableResult {
374                let mut u_self = <$num_type>::from(self) as $unsigned_num_type;
375                loop {
376                    if ((u_self & !0x7F) == 0) {
377                        (u_self as u8).write(output).await?;
378                        break;
379                    }
380                    (((u_self as u8) & 0x7F) | 0x80).write(output).await?;
381                    u_self >>= 7;
382                }
383                Ok(())
384            }
385        }
386    }
387}
388
389num!(u16 i16 u32 i32 u64 i64 u128 i128 f32 f64);
390var_num!(VarInt, i32, u32);
391var_num!(VarLong, i64, u64);