cubic_protocol/
packet_primitive.rs1use 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);