use core::str; use std::io::{Read, Write}; use crate::{ FixedBitSet, codec::{ bit_set::BitSet, var_int::VarInt, var_long::VarLong, var_uint::VarUInt, var_ulong::VarULong, }, }; pub mod deserializer; use pumpkin_nbt::{serializer::WriteAdaptor, tag::NbtTag}; use pumpkin_util::math::position::BlockPos; use thiserror::Error; pub mod serializer; #[derive(Debug, Error)] pub enum ReadingError { #[error("EOF, Tried to read {0} but No bytes left to consume")] CleanEOF(String), #[error("incomplete: {0}")] Incomplete(String), #[error("too large: {0}")] TooLarge(String), #[error("{0}")] Message(String), } #[derive(Debug, Error)] pub enum WritingError { #[error("IO error: {0}")] IoError(std::io::Error), #[error("Serde failure: {0}")] Serde(String), #[error("Failed to serialize packet: {0}")] Message(String), } pub trait NetworkReadExt { fn get_i8(&mut self) -> Result; fn get_u8(&mut self) -> Result; fn get_i16_be(&mut self) -> Result; fn get_u16_be(&mut self) -> Result; fn get_i32_be(&mut self) -> Result; fn get_u32_be(&mut self) -> Result; fn get_i64_be(&mut self) -> Result; fn get_u64_be(&mut self) -> Result; fn get_f32_be(&mut self) -> Result; fn get_f64_be(&mut self) -> Result; fn get_i128_be(&mut self) -> Result; fn get_u128_be(&mut self) -> Result; fn read_boxed_slice(&mut self, count: usize) -> Result, ReadingError>; fn read_remaining_to_boxed_slice(&mut self, bound: usize) -> Result, ReadingError>; fn get_bool(&mut self) -> Result; fn get_var_int(&mut self) -> Result; fn get_var_uint(&mut self) -> Result; fn get_var_long(&mut self) -> Result; fn get_var_ulong(&mut self) -> Result; fn get_string_bounded(&mut self, bound: usize) -> Result; fn get_string(&mut self) -> Result; fn get_uuid(&mut self) -> Result; fn get_fixed_bitset(&mut self, bits: usize) -> Result; fn get_option( &mut self, parse: impl FnOnce(&mut Self) -> Result, ) -> Result, ReadingError>; fn get_list( &mut self, parse: impl Fn(&mut Self) -> Result, ) -> Result, ReadingError>; } macro_rules! get_number_be { ($name:ident, $type:ty) => { fn $name(&mut self) -> Result<$type, ReadingError> { let mut buf = [0u8; std::mem::size_of::<$type>()]; self.read_exact(&mut buf) .map_err(|err| ReadingError::Incomplete(err.to_string()))?; Ok(<$type>::from_be_bytes(buf)) } }; } impl NetworkReadExt for R { get_number_be!(get_u8, u8); get_number_be!(get_i8, i8); get_number_be!(get_i16_be, i16); get_number_be!(get_u16_be, u16); get_number_be!(get_i32_be, i32); get_number_be!(get_u32_be, u32); get_number_be!(get_i64_be, i64); get_number_be!(get_u64_be, u64); get_number_be!(get_i128_be, i128); get_number_be!(get_u128_be, u128); get_number_be!(get_f32_be, f32); get_number_be!(get_f64_be, f64); fn read_boxed_slice(&mut self, count: usize) -> Result, ReadingError> { let mut buf = vec![0u8; count]; self.read_exact(&mut buf) .map_err(|err| ReadingError::Incomplete(err.to_string()))?; Ok(buf.into()) } fn read_remaining_to_boxed_slice(&mut self, bound: usize) -> Result, ReadingError> { let mut return_buf = Vec::new(); // Take one extra byte to check for exceeding bound self.take(bound as u64 + 1) .read_to_end(&mut return_buf) .map_err(|err| ReadingError::Incomplete(err.to_string()))?; if return_buf.len() > bound { return Err(ReadingError::TooLarge( "Read remaining too long".to_string(), )); } Ok(return_buf.into_boxed_slice()) } fn get_bool(&mut self) -> Result { let byte = self.get_u8()?; Ok(byte != 0) } fn get_var_int(&mut self) -> Result { VarInt::decode(self) } fn get_var_uint(&mut self) -> Result { VarUInt::decode(self) } fn get_var_long(&mut self) -> Result { VarLong::decode(self) } fn get_var_ulong(&mut self) -> Result { VarULong::decode(self) } fn get_string_bounded(&mut self, bound: usize) -> Result { let size = self.get_var_uint()?.0 as usize; if size > bound { return Err(ReadingError::TooLarge("string".to_string())); } let data = self.read_boxed_slice(size)?; String::from_utf8(data.into()).map_err(|e| ReadingError::Message(e.to_string())) } fn get_string(&mut self) -> Result { self.get_string_bounded(i32::MAX as usize) } fn get_uuid(&mut self) -> Result { let mut bytes = [0u8; 16]; self.read_exact(&mut bytes) .map_err(|err| ReadingError::Incomplete(err.to_string()))?; Ok(uuid::Uuid::from_slice(&bytes).expect("Failed to parse UUID")) } fn get_fixed_bitset(&mut self, bits: usize) -> Result { let bytes = self.read_boxed_slice(bits.div_ceil(8))?; Ok(bytes) } fn get_option( &mut self, parse: impl FnOnce(&mut Self) -> Result, ) -> Result, ReadingError> { if self.get_bool()? { Ok(Some(parse(self)?)) } else { Ok(None) } } fn get_list( &mut self, parse: impl Fn(&mut Self) -> Result, ) -> Result, ReadingError> { let len = self.get_var_int()?.0 as usize; let mut list = Vec::with_capacity(len); for _ in 0..len { list.push(parse(self)?); } Ok(list) } } pub trait NetworkWriteExt { fn write_i8(&mut self, data: i8) -> Result<(), WritingError>; fn write_u8(&mut self, data: u8) -> Result<(), WritingError>; fn write_i16_be(&mut self, data: i16) -> Result<(), WritingError>; fn write_u16_be(&mut self, data: u16) -> Result<(), WritingError>; fn write_i32_be(&mut self, data: i32) -> Result<(), WritingError>; fn write_u32_be(&mut self, data: u32) -> Result<(), WritingError>; fn write_i64_be(&mut self, data: i64) -> Result<(), WritingError>; fn write_u64_be(&mut self, data: u64) -> Result<(), WritingError>; fn write_f32_be(&mut self, data: f32) -> Result<(), WritingError>; fn write_f64_be(&mut self, data: f64) -> Result<(), WritingError>; fn write_slice(&mut self, data: &[u8]) -> Result<(), WritingError>; fn write_bool(&mut self, data: bool) -> Result<(), WritingError> { if data { self.write_u8(1) } else { self.write_u8(0) } } fn write_fixed_bitset(&mut self, bits: usize, bit_set: FixedBitSet) -> Result<(), WritingError>; fn write_var_int(&mut self, data: &VarInt) -> Result<(), WritingError>; fn write_var_uint(&mut self, data: &VarUInt) -> Result<(), WritingError>; fn write_var_long(&mut self, data: &VarLong) -> Result<(), WritingError>; fn write_string_bounded(&mut self, data: &str, bound: usize) -> Result<(), WritingError>; fn write_string(&mut self, data: &str) -> Result<(), WritingError>; fn write_block_pos(&mut self, pos: &BlockPos) -> Result<(), WritingError>; fn write_uuid(&mut self, data: &uuid::Uuid) -> Result<(), WritingError> { let (first, second) = data.as_u64_pair(); self.write_u64_be(first)?; self.write_u64_be(second) } fn write_bitset(&mut self, bitset: &BitSet) -> Result<(), WritingError>; fn write_option( &mut self, data: &Option, writer: impl FnOnce(&mut Self, &G) -> Result<(), WritingError>, ) -> Result<(), WritingError> { if let Some(data) = data { self.write_bool(true)?; writer(self, data) } else { self.write_bool(false) } } fn write_list( &mut self, list: &[G], writer: impl Fn(&mut Self, &G) -> Result<(), WritingError>, ) -> Result<(), WritingError> { self.write_var_int(&list.len().try_into().map_err(|_| { WritingError::Message(format!("{} isn't representable as a VarInt", list.len())) })?)?; for data in list { writer(self, data)?; } Ok(()) } fn write_nbt(&mut self, data: NbtTag) -> Result<(), WritingError>; } macro_rules! write_number_be { ($name:ident, $type:ty) => { fn $name(&mut self, data: $type) -> Result<(), WritingError> { self.write_all(&data.to_be_bytes()) .map_err(WritingError::IoError) } }; } impl NetworkWriteExt for W { fn write_i8(&mut self, data: i8) -> Result<(), WritingError> { self.write_all(&data.to_be_bytes()) .map_err(WritingError::IoError) } fn write_u8(&mut self, data: u8) -> Result<(), WritingError> { self.write_all(&data.to_be_bytes()) .map_err(WritingError::IoError) } write_number_be!(write_i16_be, i16); write_number_be!(write_u16_be, u16); write_number_be!(write_i32_be, i32); write_number_be!(write_u32_be, u32); write_number_be!(write_i64_be, i64); write_number_be!(write_u64_be, u64); write_number_be!(write_f32_be, f32); write_number_be!(write_f64_be, f64); fn write_slice(&mut self, data: &[u8]) -> Result<(), WritingError> { self.write_all(data).map_err(WritingError::IoError) } fn write_fixed_bitset( &mut self, bits: usize, bit_set: FixedBitSet, ) -> Result<(), WritingError> { let new_length = bits.div_ceil(8); let mut new_vec = vec![0u8; new_length]; let bytes_to_copy = std::cmp::min(bit_set.len(), new_length); new_vec[..bytes_to_copy].copy_from_slice(&bit_set[..bytes_to_copy]); self.write_slice(&new_vec)?; Ok(()) } fn write_var_int(&mut self, data: &VarInt) -> Result<(), WritingError> { data.encode(self) } fn write_var_uint(&mut self, data: &VarUInt) -> Result<(), WritingError> { data.encode(self) } fn write_var_long(&mut self, data: &VarLong) -> Result<(), WritingError> { data.encode(self) } fn write_string_bounded(&mut self, data: &str, bound: usize) -> Result<(), WritingError> { assert!(data.len() <= bound); self.write_var_int(&data.len().try_into().map_err(|_| { WritingError::Message(format!("{} isn't representable as a VarInt", data.len())) })?)?; self.write_all(data.as_bytes()) .map_err(WritingError::IoError) } fn write_string(&mut self, data: &str) -> Result<(), WritingError> { self.write_string_bounded(data, i16::MAX as usize) } fn write_block_pos(&mut self, pos: &BlockPos) -> Result<(), WritingError> { self.write_i64_be(pos.as_long()) } fn write_bitset(&mut self, data: &BitSet) -> Result<(), WritingError> { data.encode(self) } fn write_option( &mut self, data: &Option, writer: impl FnOnce(&mut Self, &G) -> Result<(), WritingError>, ) -> Result<(), WritingError> { if let Some(data) = data { self.write_bool(true)?; writer(self, data) } else { self.write_bool(false) } } fn write_list( &mut self, list: &[G], writer: impl Fn(&mut Self, &G) -> Result<(), WritingError>, ) -> Result<(), WritingError> { self.write_var_int(&(list.len() as i32).into())?; for data in list { writer(self, data)?; } Ok(()) } fn write_nbt(&mut self, data: NbtTag) -> Result<(), WritingError> { let mut write_adaptor = WriteAdaptor::new(self); data.serialize(&mut write_adaptor) .map_err(|e| WritingError::Message(e.to_string()))?; Ok(()) } } #[cfg(test)] mod test { use std::io::Cursor; use serde::{Deserialize, Serialize}; use crate::{ VarInt, ser::{deserializer, serializer}, }; #[test] fn i32_reserialize() { #[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)] struct Foo { bar: i32, } let foo = Foo { bar: 69 }; let mut bytes = Vec::new(); let mut serializer = serializer::Serializer::new(&mut bytes); foo.serialize(&mut serializer).unwrap(); let cursor = Cursor::new(bytes); let deserialized: Foo = Foo::deserialize(&mut deserializer::Deserializer::new(cursor)).unwrap(); assert_eq!(foo, deserialized); } #[test] fn varint_reserialize() { #[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)] struct Foo { bar: VarInt, } let foo = Foo { bar: 69.into() }; let mut bytes = Vec::new(); let mut serializer = serializer::Serializer::new(&mut bytes); foo.serialize(&mut serializer).unwrap(); let cursor = Cursor::new(bytes); let deserialized: Foo = Foo::deserialize(&mut deserializer::Deserializer::new(cursor)).unwrap(); assert_eq!(foo, deserialized); } #[test] fn char_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct CharStruct { c: char, } // Test with normal char let original = CharStruct { c: 'A' }; let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); original.serialize(&mut ser).unwrap(); assert_eq!(bytes, vec![0, 0, 0, 0x41]); let de_cursor = Cursor::new(bytes); let deserialized: CharStruct = CharStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); // Test with complex char let original_complex = CharStruct { c: 'Ω' }; // Greek Omega, U+03A9 let mut bytes_complex = Vec::new(); let mut ser_complex = serializer::Serializer::new(&mut bytes_complex); original_complex.serialize(&mut ser_complex).unwrap(); assert_eq!(bytes_complex, vec![0, 0, 0x03, 0xA9]); let de_cursor_complex = Cursor::new(bytes_complex); let deserialized_complex: CharStruct = CharStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor_complex)) .unwrap(); assert_eq!(original_complex, deserialized_complex); // Test with an emoji let original_emoji = CharStruct { c: '\u{1F383}' }; // Pumpkin emoji, U+1F383 let mut bytes_emoji = Vec::new(); let mut ser_emoji = serializer::Serializer::new(&mut bytes_emoji); original_emoji.serialize(&mut ser_emoji).unwrap(); assert_eq!(bytes_emoji, vec![0, 0x01, 0xF3, 0x83]); let de_cursor_emoji = Cursor::new(bytes_emoji); let deserialized_emoji: CharStruct = CharStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor_emoji)).unwrap(); assert_eq!(original_emoji, deserialized_emoji); } #[test] fn i128_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct I128Struct { val: i128, } let original = I128Struct { val: 12345678901234567890123456789012345678, }; let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); original.serialize(&mut ser).unwrap(); assert_eq!(bytes, original.val.to_be_bytes()); let de_cursor = Cursor::new(bytes); let deserialized: I128Struct = I128Struct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); let original_neg = I128Struct { val: -12345678901234567890123456789012345678, }; let mut bytes_neg = Vec::new(); let mut ser_neg = serializer::Serializer::new(&mut bytes_neg); original_neg.serialize(&mut ser_neg).unwrap(); assert_eq!(bytes_neg, original_neg.val.to_be_bytes()); let de_cursor_neg = Cursor::new(bytes_neg); let deserialized_neg: I128Struct = I128Struct::deserialize(&mut deserializer::Deserializer::new(de_cursor_neg)).unwrap(); assert_eq!(original_neg, deserialized_neg); } #[test] fn u128_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct U128Struct { val: u128, } let original = U128Struct { val: 123456789012345678901234567890123456789, }; let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); original.serialize(&mut ser).unwrap(); assert_eq!(bytes, original.val.to_be_bytes()); let de_cursor = Cursor::new(bytes); let deserialized: U128Struct = U128Struct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); } #[test] fn unit_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct UnitStruct; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct StructWithUnit { a: i32, b: UnitStruct, c: i32, } let original = UnitStruct; let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); original.serialize(&mut ser).unwrap(); assert!(bytes.is_empty()); let de_cursor = Cursor::new(bytes); let deserialized: UnitStruct = UnitStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); let original_with_unit = StructWithUnit { a: 1, b: UnitStruct, c: 2, }; let mut bytes_with_unit = Vec::new(); let mut ser_with_unit = serializer::Serializer::new(&mut bytes_with_unit); original_with_unit.serialize(&mut ser_with_unit).unwrap(); // Check that only a and c were serialized let mut expected_bytes = Vec::new(); expected_bytes.extend_from_slice(&1i32.to_be_bytes()); expected_bytes.extend_from_slice(&2i32.to_be_bytes()); assert_eq!(bytes_with_unit, expected_bytes); let de_cursor_with_unit = Cursor::new(bytes_with_unit); let deserialized_with_unit: StructWithUnit = StructWithUnit::deserialize(&mut deserializer::Deserializer::new(de_cursor_with_unit)) .unwrap(); assert_eq!(original_with_unit, deserialized_with_unit); } #[test] fn enum_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] enum MyEnum { A, B(i32), C { x: i32, y: String }, } let original_a = MyEnum::A; let mut bytes_a = Vec::new(); let mut ser_a = serializer::Serializer::new(&mut bytes_a); original_a.serialize(&mut ser_a).unwrap(); // VarInt for index 0 assert_eq!(bytes_a, vec![0x00]); let de_cursor_a = Cursor::new(bytes_a); let deserialized_a: MyEnum = MyEnum::deserialize(&mut deserializer::Deserializer::new(de_cursor_a)).unwrap(); assert_eq!(original_a, deserialized_a); let original_b = MyEnum::B(123); let mut bytes_b = Vec::new(); let mut ser_b = serializer::Serializer::new(&mut bytes_b); original_b.serialize(&mut ser_b).unwrap(); // VarInt for index 1, then i32 for 123 let mut expected_bytes_b = vec![0x01]; expected_bytes_b.extend_from_slice(&123i32.to_be_bytes()); assert_eq!(bytes_b, expected_bytes_b); let de_cursor_b = Cursor::new(bytes_b); let deserialized_b: MyEnum = MyEnum::deserialize(&mut deserializer::Deserializer::new(de_cursor_b)).unwrap(); assert_eq!(original_b, deserialized_b); let original_c = MyEnum::C { x: 456, y: "hello".to_string(), }; let mut bytes_c = Vec::new(); let mut ser_c = serializer::Serializer::new(&mut bytes_c); original_c.serialize(&mut ser_c).unwrap(); // VarInt for index 2, then i32 for 456, then string "hello" let mut expected_bytes_c = vec![0x02]; expected_bytes_c.extend_from_slice(&456i32.to_be_bytes()); expected_bytes_c.push(0x05); // VarInt for string length 5 expected_bytes_c.extend_from_slice(b"hello"); assert_eq!(bytes_c, expected_bytes_c); let de_cursor_c = Cursor::new(bytes_c); let deserialized_c: MyEnum = MyEnum::deserialize(&mut deserializer::Deserializer::new(de_cursor_c)).unwrap(); assert_eq!(original_c, deserialized_c); } #[test] fn tuple_struct_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct MyTupleStruct(i32, String); let original = MyTupleStruct(789, "world".to_string()); let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); original.serialize(&mut ser).unwrap(); let mut expected_bytes = Vec::new(); expected_bytes.extend_from_slice(&789i32.to_be_bytes()); expected_bytes.push(0x05); // VarInt for string length 5 expected_bytes.extend_from_slice(b"world"); assert_eq!(bytes, expected_bytes); let de_cursor = Cursor::new(bytes); let deserialized: MyTupleStruct = MyTupleStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); } #[test] fn map_reserialize() { use std::collections::HashMap; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct MyMapStruct { map: HashMap, } let mut map = HashMap::new(); map.insert("one".to_string(), 1); map.insert("two".to_string(), 2); let original = MyMapStruct { map }; let mut bytes = Vec::new(); let mut serializer = serializer::Serializer::new(&mut bytes); original.serialize(&mut serializer).unwrap(); // Expected bytes: VarInt for map length (2), then key1, value1, key2, value2 // Order of elements in HashMap is not guaranteed, so we check deserialized content let de_cursor = Cursor::new(bytes.clone()); // Clone bytes for potential debug let deserialized: MyMapStruct = MyMapStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original.map.len(), deserialized.map.len()); for (k, v) in original.map { assert_eq!(deserialized.map.get(&k), Some(&v)); } // Test with an empty map let empty_map_original = MyMapStruct { map: HashMap::new(), }; let mut empty_map_bytes = Vec::new(); let mut empty_map_ser = serializer::Serializer::new(&mut empty_map_bytes); empty_map_original.serialize(&mut empty_map_ser).unwrap(); assert_eq!(empty_map_bytes, vec![0x00]); // VarInt for length 0 let empty_map_de_cursor = Cursor::new(empty_map_bytes); let empty_map_deserialized: MyMapStruct = MyMapStruct::deserialize(&mut deserializer::Deserializer::new(empty_map_de_cursor)) .unwrap(); assert_eq!(empty_map_original, empty_map_deserialized); } }