From cbf9e63329d886102d23e9920fb9c1808533df5c Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Fri, 13 Dec 2024 15:42:04 +0100 Subject: [PATCH] Remove ByteBuffer struct Replaced trough trait's which implement bytes::Buf and bytes::BufMut. Closes https://github.com/Snowiiii/Pumpkin/issues/396 --- pumpkin-protocol/src/bytebuf/deserializer.rs | 49 +- pumpkin-protocol/src/bytebuf/mod.rs | 635 +++++++++--------- pumpkin-protocol/src/bytebuf/packet_id.rs | 11 +- pumpkin-protocol/src/bytebuf/serializer.rs | 17 +- .../src/client/config/c_known_packs.rs | 5 +- .../src/client/config/c_registry_data.rs | 6 +- .../src/client/login/c_login_success.rs | 5 +- .../src/client/play/c_boss_event.rs | 5 +- .../src/client/play/c_chunk_data.rs | 11 +- .../src/client/play/c_command_suggestions.rs | 5 +- .../src/client/play/c_commands.rs | 25 +- .../src/client/play/c_entity_sound_effect.rs | 5 +- .../src/client/play/c_player_info_update.rs | 5 +- .../src/client/play/c_player_position.rs | 5 +- .../src/client/play/c_sound_effect.rs | 5 +- .../src/client/play/c_teleport_entity.rs | 5 +- .../src/client/play/c_update_objectives.rs | 5 +- pumpkin-protocol/src/lib.rs | 13 +- pumpkin-protocol/src/packet_decoder.rs | 57 +- pumpkin-protocol/src/packet_encoder.rs | 40 +- .../src/server/config/s_cookie_response.rs | 17 +- .../src/server/config/s_plugin_message.rs | 11 +- pumpkin-protocol/src/server/handshake/mod.rs | 13 +- .../src/server/login/s_cookie_response.rs | 17 +- .../src/server/login/s_encryption_response.rs | 13 +- .../src/server/login/s_login_start.rs | 9 +- .../src/server/login/s_plugin_response.rs | 12 +- .../src/server/play/s_chat_message.rs | 16 +- .../src/server/play/s_cookie_response.rs | 17 +- .../src/server/play/s_interact.rs | 31 +- .../src/server/play/s_player_command.rs | 14 +- pumpkin/src/client/mod.rs | 15 +- pumpkin/src/error.rs | 4 +- pumpkin/src/proxy/velocity.rs | 20 +- pumpkin/src/world/mod.rs | 5 +- 35 files changed, 570 insertions(+), 558 deletions(-) diff --git a/pumpkin-protocol/src/bytebuf/deserializer.rs b/pumpkin-protocol/src/bytebuf/deserializer.rs index 433c705aa..3b999e96b 100644 --- a/pumpkin-protocol/src/bytebuf/deserializer.rs +++ b/pumpkin-protocol/src/bytebuf/deserializer.rs @@ -1,34 +1,27 @@ use std::fmt::Display; +use super::{ByteBuf, ReadingError}; +use bytes::Bytes; use serde::de::{self, DeserializeSeed, SeqAccess}; -use thiserror::Error; - -use super::ByteBuffer; pub struct Deserializer<'a> { - inner: &'a mut ByteBuffer, + inner: &'a mut Bytes, } -#[derive(Debug, Error)] -pub enum DeserializerError { - #[error("serializer error {0}")] - Message(String), -} - -impl de::Error for DeserializerError { +impl de::Error for ReadingError { fn custom(msg: T) -> Self { Self::Message(msg.to_string()) } } impl<'a> Deserializer<'a> { - pub fn new(buf: &'a mut ByteBuffer) -> Self { + pub fn new(buf: &'a mut Bytes) -> Self { Self { inner: buf } } } impl<'de> de::Deserializer<'de> for Deserializer<'_> { - type Error = DeserializerError; + type Error = ReadingError; fn deserialize_any(self, _visitor: V) -> Result where @@ -43,77 +36,77 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> { where V: de::Visitor<'de>, { - visitor.visit_bool(self.inner.get_bool()?) + visitor.visit_bool(self.inner.try_get_bool()?) } fn deserialize_i8(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_i8(self.inner.get_i8()?) + visitor.visit_i8(self.inner.try_get_i8()?) } fn deserialize_i16(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_i16(self.inner.get_i16()?) + visitor.visit_i16(self.inner.try_get_i16()?) } fn deserialize_i32(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_i32(self.inner.get_i32()?) + visitor.visit_i32(self.inner.try_get_i32()?) } fn deserialize_i64(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_i64(self.inner.get_i64()?) + visitor.visit_i64(self.inner.try_get_i64()?) } fn deserialize_u8(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_u8(self.inner.get_u8()?) + visitor.visit_u8(self.inner.try_get_u8()?) } fn deserialize_u16(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_u16(self.inner.get_u16()?) + visitor.visit_u16(self.inner.try_get_u16()?) } fn deserialize_u32(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_u32(self.inner.get_u32()?) + visitor.visit_u32(self.inner.try_get_u32()?) } fn deserialize_u64(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_u64(self.inner.get_u64()?) + visitor.visit_u64(self.inner.try_get_u64()?) } fn deserialize_f32(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_f32(self.inner.get_f32()?) + visitor.visit_f32(self.inner.try_get_f32()?) } fn deserialize_f64(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_f64(self.inner.get_f64()?) + visitor.visit_f64(self.inner.try_get_f64()?) } fn deserialize_char(self, _visitor: V) -> Result @@ -127,14 +120,14 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> { where V: de::Visitor<'de>, { - visitor.visit_str(&self.inner.get_string()?) + visitor.visit_str(&self.inner.try_get_string()?) } fn deserialize_string(self, visitor: V) -> Result where V: de::Visitor<'de>, { - visitor.visit_str(&self.inner.get_string()?) + visitor.visit_str(&self.inner.try_get_string()?) } fn deserialize_bytes(self, _visitor: V) -> Result @@ -196,7 +189,7 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> { } impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> { - type Error = DeserializerError; + type Error = ReadingError; fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where @@ -229,7 +222,7 @@ impl<'de> de::Deserializer<'de> for Deserializer<'_> { } impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> { - type Error = DeserializerError; + type Error = ReadingError; fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> where diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index accceb4bb..94e57f529 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -1,376 +1,359 @@ use core::str; use crate::{BitSet, FixedBitSet, VarInt, VarLong}; -use bytes::{Buf, BufMut, BytesMut}; +use bytes::{Buf, BufMut}; mod deserializer; -pub use deserializer::DeserializerError; +use thiserror::Error; pub mod packet_id; mod serializer; -#[derive(Debug)] -pub struct ByteBuffer { - buffer: BytesMut, +use std::mem::size_of; + +#[derive(Debug, Error)] +pub enum ReadingError { + /// End-of-File + #[error("EOF, Tried to read {0} but No bytes left to consume")] + EOF(String), + #[error("{0} is Incomplete")] + Incomplete(String), + #[error("{0} is too Large")] + TooLarge(String), + #[error("{0}")] + Message(String), } -impl ByteBuffer { - pub fn empty() -> Self { - Self { - buffer: BytesMut::new(), - } - } - pub fn new(buffer: BytesMut) -> Self { - Self { buffer } - } +pub trait ByteBuf: Buf { + fn try_get_bool(&mut self) -> Result; - pub fn get_var_int(&mut self) -> Result { - match VarInt::decode(&mut self.buffer) { - Ok(var_int) => Ok(var_int), - Err(error) => match error { - crate::VarIntDecodeError::Incomplete => Err(DeserializerError::Message( - "VarInt is Incomplete".to_string(), - )), - crate::VarIntDecodeError::TooLarge => { - Err(DeserializerError::Message("VarInt is too big".to_string())) - } - }, - } - } + fn try_get_u8(&mut self) -> Result; - pub fn get_var_long(&mut self) -> Result { - match VarLong::decode(&mut self.buffer) { - Ok(var_long) => Ok(var_long), - Err(error) => match error { - crate::VarLongDecodeError::Incomplete => Err(DeserializerError::Message( - "VarLong is Incomplete".to_string(), - )), - crate::VarLongDecodeError::TooLarge => { - Err(DeserializerError::Message("VarLong is too big".to_string())) - } - }, - } - } + fn try_get_i8(&mut self) -> Result; - pub fn get_string(&mut self) -> Result { - self.get_string_len(i16::MAX as i32) - } + fn try_get_u16(&mut self) -> Result; - pub fn get_string_len(&mut self, max_size: i32) -> Result { - let size = self.get_var_int()?.0; - if size > max_size { - return Err(DeserializerError::Message( - "String length is bigger than max size".to_string(), - )); - } + fn try_get_i16(&mut self) -> Result; - let data = self.copy_to_bytes(size as usize)?; - if data.len() as i32 > max_size { - return Err(DeserializerError::Message( - "String is bigger than max size".to_string(), - )); - } - match str::from_utf8(&data) { - Ok(string_result) => Ok(string_result.to_string()), - Err(e) => Err(DeserializerError::Message(e.to_string())), - } - } + fn try_get_u32(&mut self) -> Result; - pub fn get_bool(&mut self) -> Result { - Ok(self.get_u8()? != 0) - } + fn try_get_i32(&mut self) -> Result; - pub fn get_uuid(&mut self) -> Result { - let mut bytes = [0u8; 16]; - self.copy_to_slice(&mut bytes)?; - Ok(uuid::Uuid::from_slice(&bytes).expect("Failed to parse UUID")) - } + fn try_get_u64(&mut self) -> Result; - pub fn get_fixed_bitset(&mut self, bits: usize) -> Result { - self.copy_to_bytes(bits.div_ceil(8)) - } + fn try_get_i64(&mut self) -> Result; - pub fn put_bool(&mut self, v: bool) { - if v { - self.buffer.put_u8(1); - } else { - self.buffer.put_u8(0); - } - } + fn try_get_f32(&mut self) -> Result; - pub fn put_uuid(&mut self, v: &uuid::Uuid) { - // thats the vanilla way - let pair = v.as_u64_pair(); - self.put_u64(pair.0); - self.put_u64(pair.1); - } + fn try_get_f64(&mut self) -> Result; - pub fn put_string(&mut self, val: &str) { - self.put_string_len(val, i16::MAX as i32); - } + fn try_copy_to_bytes(&mut self, len: usize) -> Result; - pub fn put_string_len(&mut self, val: &str, max_size: i32) { - if val.len() as i32 > max_size { - // Should be panic?, I mean its our fault - panic!("String is too big"); - } - self.put_var_int(&val.len().into()); - self.buffer.put(val.as_bytes()); - } + fn try_copy_to_slice(&mut self, dst: &mut [u8]) -> Result<(), ReadingError>; - pub fn put_string_array(&mut self, array: &[String]) { - for string in array { - self.put_string(string) - } - } + fn try_get_var_int(&mut self) -> Result; - pub fn put_var_int(&mut self, value: &VarInt) { - value.encode(&mut self.buffer); - } + fn try_get_var_long(&mut self) -> Result; - pub fn put_bit_set(&mut self, set: &BitSet) { - self.put_var_int(&set.0); - for b in set.1 { - self.put_i64(*b); - } - } + fn try_get_string(&mut self) -> Result; + + fn try_get_string_len(&mut self, max_size: u32) -> Result; /// Reads a boolean. If true, the closure is called, and the returned value is /// wrapped in Some. Otherwise, this returns None. - pub fn get_option( + fn try_get_option( &mut self, - val: impl FnOnce(&mut Self) -> Result, - ) -> Result, DeserializerError> { - if self.get_bool()? { + val: impl FnOnce(&mut Self) -> Result, + ) -> Result, ReadingError>; + + fn get_list( + &mut self, + val: impl Fn(&mut Self) -> Result, + ) -> Result, ReadingError>; + + fn try_get_uuid(&mut self) -> Result; + + fn try_get_fixed_bitset(&mut self, bits: usize) -> Result; +} + +impl ByteBuf for T { + fn try_get_bool(&mut self) -> Result { + Ok(self.try_get_u8()? != 0) + } + + fn try_get_u8(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_u8()) + } else { + Err(ReadingError::EOF("u8".to_string())) + } + } + + fn try_get_i8(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_i8()) + } else { + Err(ReadingError::EOF("i8".to_string())) + } + } + + fn try_get_u16(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_u16()) + } else { + Err(ReadingError::EOF("u16".to_string())) + } + } + + fn try_get_i16(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_i16()) + } else { + Err(ReadingError::EOF("i16".to_string())) + } + } + + fn try_get_u32(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_u32()) + } else { + Err(ReadingError::EOF("u32".to_string())) + } + } + + fn try_get_i32(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_i32()) + } else { + Err(ReadingError::EOF("i32".to_string())) + } + } + + fn try_get_u64(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_u64()) + } else { + Err(ReadingError::EOF("u64".to_string())) + } + } + + fn try_get_i64(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_i64()) + } else { + Err(ReadingError::EOF("i64".to_string())) + } + } + + fn try_get_f32(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_f32()) + } else { + Err(ReadingError::EOF("f32".to_string())) + } + } + + fn try_get_f64(&mut self) -> Result { + if size_of::() <= self.remaining() { + Ok(self.get_f64()) + } else { + Err(ReadingError::EOF("f64".to_string())) + } + } + + fn try_copy_to_bytes(&mut self, len: usize) -> Result { + if self.remaining() >= len { + Ok(self.copy_to_bytes(len)) + } else { + Err(ReadingError::Message("Unable to copy bytes".to_string())) + } + } + + fn try_copy_to_slice(&mut self, dst: &mut [u8]) -> Result<(), ReadingError> { + if self.remaining() >= dst.len() { + self.copy_to_slice(dst); + Ok(()) + } else { + Err(ReadingError::Message("Unable to copy slice".to_string())) + } + } + + fn try_get_var_int(&mut self) -> Result { + match VarInt::decode(self) { + Ok(var_int) => Ok(var_int), + Err(error) => match error { + crate::VarIntDecodeError::Incomplete => { + Err(ReadingError::Incomplete("varint".to_string())) + } + crate::VarIntDecodeError::TooLarge => { + Err(ReadingError::TooLarge("varint".to_string())) + } + }, + } + } + fn try_get_var_long(&mut self) -> Result { + match VarLong::decode(self) { + Ok(var_long) => Ok(var_long), + Err(error) => match error { + crate::VarLongDecodeError::Incomplete => { + Err(ReadingError::Incomplete("varint".to_string())) + } + crate::VarLongDecodeError::TooLarge => { + Err(ReadingError::TooLarge("varlong".to_string())) + } + }, + } + } + + fn try_get_string(&mut self) -> Result { + self.try_get_string_len(i16::MAX as u32) + } + + fn try_get_string_len(&mut self, max_size: u32) -> Result { + let size = self.try_get_var_int()?.0; + if size as u32 > max_size { + return Err(ReadingError::TooLarge("string".to_string())); + } + + let data = self.try_copy_to_bytes(size as usize)?; + if data.len() as u32 > max_size { + return Err(ReadingError::TooLarge("string".to_string())); + } + match str::from_utf8(&data) { + Ok(string_result) => Ok(string_result.to_string()), + Err(e) => Err(ReadingError::Message(e.to_string())), + } + } + + fn try_get_option( + &mut self, + val: impl FnOnce(&mut Self) -> Result, + ) -> Result, ReadingError> { + if self.try_get_bool()? { Ok(Some(val(self)?)) } else { Ok(None) } } - /// Writes `true` if the option is Some, or `false` if None. If the option is - /// some, then it also calls the `write` closure. - pub fn put_option(&mut self, val: &Option, write: impl FnOnce(&mut Self, &T)) { - self.put_bool(val.is_some()); - if let Some(v) = val { - write(self, v) - } - } - pub fn get_list( + fn get_list( &mut self, - val: impl Fn(&mut Self) -> Result, - ) -> Result, DeserializerError> { - let len = self.get_var_int()?.0 as usize; + val: impl Fn(&mut Self) -> Result, + ) -> Result, ReadingError> { + let len = self.try_get_var_int()?.0 as usize; let mut list = Vec::with_capacity(len); for _ in 0..len { list.push(val(self)?); } Ok(list) } - /// Writes a list to the buffer. - pub fn put_list(&mut self, list: &[T], write: impl Fn(&mut Self, &T)) { + + fn try_get_uuid(&mut self) -> Result { + let mut bytes = [0u8; 16]; + self.try_copy_to_slice(&mut bytes)?; + Ok(uuid::Uuid::from_slice(&bytes).expect("Failed to parse UUID")) + } + + fn try_get_fixed_bitset(&mut self, bits: usize) -> Result { + self.try_copy_to_bytes(bits.div_ceil(8)) + } +} + +pub trait ByteBufMut { + fn put_bool(&mut self, v: bool); + + fn put_uuid(&mut self, v: &uuid::Uuid); + + fn put_string(&mut self, val: &str); + + fn put_string_len(&mut self, val: &str, max_size: u32); + + fn put_string_array(&mut self, array: &[String]); + + fn put_bit_set(&mut self, set: &BitSet); + + /// Writes `true` if the option is Some, or `false` if None. If the option is + /// some, then it also calls the `write` closure. + fn put_option(&mut self, val: &Option, write: impl FnOnce(&mut Self, &G)); + + fn put_list(&mut self, list: &[G], write: impl Fn(&mut Self, &G)); + + fn put_var_int(&mut self, value: &VarInt); + + fn put_varint_arr(&mut self, v: &[i32]); +} + +impl ByteBufMut for T { + fn put_bool(&mut self, v: bool) { + if v { + self.put_u8(1); + } else { + self.put_u8(0); + } + } + + fn put_uuid(&mut self, v: &uuid::Uuid) { + // thats the vanilla way + let pair = v.as_u64_pair(); + self.put_u64(pair.0); + self.put_u64(pair.1); + } + + fn put_string(&mut self, val: &str) { + self.put_string_len(val, i16::MAX as u32); + } + + fn put_string_len(&mut self, val: &str, max_size: u32) { + if val.len() as u32 > max_size { + // Should be panic?, I mean its our fault + panic!("String is too big"); + } + self.put_var_int(&val.len().into()); + self.put(val.as_bytes()); + } + + fn put_string_array(&mut self, array: &[String]) { + for string in array { + self.put_string(string) + } + } + + fn put_var_int(&mut self, value: &VarInt) { + value.encode(self); + } + + fn put_bit_set(&mut self, set: &BitSet) { + self.put_var_int(&set.0); + for b in set.1 { + self.put_i64(*b); + } + } + + fn put_option(&mut self, val: &Option, write: impl FnOnce(&mut Self, &G)) { + self.put_bool(val.is_some()); + if let Some(v) = val { + write(self, v) + } + } + + fn put_list(&mut self, list: &[G], write: impl Fn(&mut Self, &G)) { self.put_var_int(&list.len().into()); for v in list { write(self, v); } } - pub fn put_varint_arr(&mut self, v: &[i32]) { + fn put_varint_arr(&mut self, v: &[i32]) { self.put_list(v, |p, &v| p.put_var_int(&v.into())) } - - pub fn buf(&mut self) -> &mut BytesMut { - &mut self.buffer - } - - // Trait equivalents - pub fn get_u8(&mut self) -> Result { - if self.buffer.has_remaining() { - Ok(self.buffer.get_u8()) - } else { - Err(DeserializerError::Message( - "No bytes left to consume".to_string(), - )) - } - } - - pub fn get_i8(&mut self) -> Result { - if self.buffer.has_remaining() { - Ok(self.buffer.get_i8()) - } else { - Err(DeserializerError::Message( - "No bytes left to consume".to_string(), - )) - } - } - - pub fn get_u16(&mut self) -> Result { - if self.buffer.remaining() >= 2 { - Ok(self.buffer.get_u16()) - } else { - Err(DeserializerError::Message( - "Less than 2 bytes left to consume".to_string(), - )) - } - } - - pub fn get_i16(&mut self) -> Result { - if self.buffer.remaining() >= 2 { - Ok(self.buffer.get_i16()) - } else { - Err(DeserializerError::Message( - "Less than 2 bytes left to consume".to_string(), - )) - } - } - - pub fn get_u32(&mut self) -> Result { - if self.buffer.remaining() >= 4 { - Ok(self.buffer.get_u32()) - } else { - Err(DeserializerError::Message( - "Less than 4 bytes left to consume".to_string(), - )) - } - } - - pub fn get_i32(&mut self) -> Result { - if self.buffer.remaining() >= 4 { - Ok(self.buffer.get_i32()) - } else { - Err(DeserializerError::Message( - "Less than 4 bytes left to consume".to_string(), - )) - } - } - - pub fn get_u64(&mut self) -> Result { - if self.buffer.remaining() >= 8 { - Ok(self.buffer.get_u64()) - } else { - Err(DeserializerError::Message( - "Less than 8 bytes left to consume".to_string(), - )) - } - } - - pub fn get_i64(&mut self) -> Result { - if self.buffer.remaining() >= 8 { - Ok(self.buffer.get_i64()) - } else { - Err(DeserializerError::Message( - "Less than 8 bytes left to consume".to_string(), - )) - } - } - - pub fn get_f32(&mut self) -> Result { - if self.buffer.remaining() >= 4 { - Ok(self.buffer.get_f32()) - } else { - Err(DeserializerError::Message( - "Less than 4 bytes left to consume".to_string(), - )) - } - } - - pub fn get_f64(&mut self) -> Result { - if self.buffer.remaining() >= 8 { - Ok(self.buffer.get_f64()) - } else { - Err(DeserializerError::Message( - "Less than 8 bytes left to consume".to_string(), - )) - } - } - - // TODO: SerializerError? - pub fn put_u8(&mut self, n: u8) { - self.buffer.put_u8(n) - } - - pub fn put_i8(&mut self, n: i8) { - self.buffer.put_i8(n) - } - - pub fn put_u16(&mut self, n: u16) { - self.buffer.put_u16(n) - } - - pub fn put_i16(&mut self, n: i16) { - self.buffer.put_i16(n) - } - - pub fn put_u32(&mut self, n: u32) { - self.buffer.put_u32(n) - } - - pub fn put_i32(&mut self, n: i32) { - self.buffer.put_i32(n) - } - - pub fn put_u64(&mut self, n: u64) { - self.buffer.put_u64(n) - } - - pub fn put_i64(&mut self, n: i64) { - self.buffer.put_i64(n) - } - - pub fn put_f32(&mut self, n: f32) { - self.buffer.put_f32(n) - } - - pub fn put_f64(&mut self, n: f64) { - self.buffer.put_f64(n) - } - - pub fn copy_to_bytes(&mut self, len: usize) -> Result { - if self.buffer.len() >= len { - Ok(self.buffer.copy_to_bytes(len)) - } else { - Err(DeserializerError::Message( - "Unable to copy bytes".to_string(), - )) - } - } - - pub fn copy_to_slice(&mut self, dst: &mut [u8]) -> Result<(), DeserializerError> { - if self.buffer.remaining() >= dst.len() { - self.buffer.copy_to_slice(dst); - Ok(()) - } else { - Err(DeserializerError::Message( - "Unable to copy slice".to_string(), - )) - } - } - - pub fn put_slice(&mut self, src: &[u8]) { - self.buffer.put_slice(src) - } - - pub fn put(&mut self, src: T) - where - Self: Sized, - { - self.buffer.put(src) - } - - pub fn reserve(&mut self, additional: usize) { - self.buffer.reserve(additional) - } - - pub fn get_slice(&mut self) -> BytesMut { - self.buffer.split() - } } #[cfg(test)] mod test { + use bytes::{Bytes, BytesMut}; use serde::{Deserialize, Serialize}; use crate::{ - bytebuf::{deserializer, serializer, ByteBuffer}, + bytebuf::{deserializer, serializer}, VarInt, }; @@ -381,12 +364,14 @@ mod test { bar: i32, } let foo = Foo { bar: 69 }; - let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); + let mut serializer = serializer::Serializer::new(BytesMut::new()); foo.serialize(&mut serializer).unwrap(); - let mut serialized: ByteBuffer = serializer.into(); - let deserialized: Foo = - Foo::deserialize(deserializer::Deserializer::new(&mut serialized)).unwrap(); + let serialized: BytesMut = serializer.into(); + let deserialized: Foo = Foo::deserialize(deserializer::Deserializer::new( + &mut Bytes::from(serialized), + )) + .unwrap(); assert_eq!(foo, deserialized); } @@ -398,12 +383,14 @@ mod test { bar: VarInt, } let foo = Foo { bar: 69.into() }; - let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); + let mut serializer = serializer::Serializer::new(BytesMut::new()); foo.serialize(&mut serializer).unwrap(); - let mut serialized: ByteBuffer = serializer.into(); - let deserialized: Foo = - Foo::deserialize(deserializer::Deserializer::new(&mut serialized)).unwrap(); + let serialized: BytesMut = serializer.into(); + let deserialized: Foo = Foo::deserialize(deserializer::Deserializer::new( + &mut Bytes::from(serialized), + )) + .unwrap(); assert_eq!(foo, deserialized); } diff --git a/pumpkin-protocol/src/bytebuf/packet_id.rs b/pumpkin-protocol/src/bytebuf/packet_id.rs index 913889db9..95c8a18ee 100644 --- a/pumpkin-protocol/src/bytebuf/packet_id.rs +++ b/pumpkin-protocol/src/bytebuf/packet_id.rs @@ -1,8 +1,9 @@ +use bytes::{BufMut, Bytes, BytesMut}; use serde::{de::DeserializeOwned, Serialize}; use crate::{ClientPacket, ServerPacket, VarIntType}; -use super::{deserializer, serializer, ByteBuffer, DeserializerError}; +use super::{deserializer, serializer, ReadingError}; pub trait Packet { const PACKET_ID: VarIntType; @@ -12,14 +13,14 @@ impl

ClientPacket for P where P: Packet + Serialize, { - fn write(&self, bytebuf: &mut ByteBuffer) { - let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); + fn write(&self, bytebuf: &mut BytesMut) { + let mut serializer = serializer::Serializer::new(BytesMut::new()); self.serialize(&mut serializer) .expect("Could not serialize packet"); // We write the packet in an empty bytebuffer and then put it into our current one. // In the future we may do packet batching thats the reason i don't let every packet create a new bytebuffer and use // an existing instead - bytebuf.put(serializer.output.buf()); + bytebuf.put(serializer.output); } } @@ -27,7 +28,7 @@ impl

ServerPacket for P where P: Packet + DeserializeOwned, { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { let deserializer = deserializer::Deserializer::new(bytebuf); P::deserialize(deserializer) } diff --git a/pumpkin-protocol/src/bytebuf/serializer.rs b/pumpkin-protocol/src/bytebuf/serializer.rs index d683bb035..cace3c6a7 100644 --- a/pumpkin-protocol/src/bytebuf/serializer.rs +++ b/pumpkin-protocol/src/bytebuf/serializer.rs @@ -1,37 +1,38 @@ use std::fmt::Display; +use bytes::{BufMut, BytesMut}; use serde::{ ser::{self}, Serialize, }; use thiserror::Error; -use super::ByteBuffer; +use super::ByteBufMut; pub struct Serializer { - pub output: ByteBuffer, + pub output: BytesMut, } impl Serializer { - pub fn new(buf: ByteBuffer) -> Self { + pub fn new(buf: BytesMut) -> Self { Self { output: buf } } } -impl From for ByteBuffer { +impl From for BytesMut { fn from(val: Serializer) -> Self { val.output } } -impl AsRef for Serializer { - fn as_ref(&self) -> &ByteBuffer { +impl AsRef for Serializer { + fn as_ref(&self) -> &BytesMut { &self.output } } -impl AsMut for Serializer { - fn as_mut(&mut self) -> &mut ByteBuffer { +impl AsMut for Serializer { + fn as_mut(&mut self) -> &mut BytesMut { &mut self.output } } diff --git a/pumpkin-protocol/src/client/config/c_known_packs.rs b/pumpkin-protocol/src/client/config/c_known_packs.rs index 80b375808..467143e25 100644 --- a/pumpkin-protocol/src/client/config/c_known_packs.rs +++ b/pumpkin-protocol/src/client/config/c_known_packs.rs @@ -1,6 +1,7 @@ +use bytes::BytesMut; use pumpkin_macros::client_packet; -use crate::{bytebuf::ByteBuffer, ClientPacket, KnownPack}; +use crate::{bytebuf::ByteBufMut, ClientPacket, KnownPack}; #[client_packet("config:select_known_packs")] pub struct CKnownPacks<'a> { @@ -14,7 +15,7 @@ impl<'a> CKnownPacks<'a> { } impl ClientPacket for CKnownPacks<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_list::(self.known_packs, |p, v| { p.put_string(v.namespace); p.put_string(v.id); diff --git a/pumpkin-protocol/src/client/config/c_registry_data.rs b/pumpkin-protocol/src/client/config/c_registry_data.rs index d346ca45e..001769d56 100644 --- a/pumpkin-protocol/src/client/config/c_registry_data.rs +++ b/pumpkin-protocol/src/client/config/c_registry_data.rs @@ -1,7 +1,7 @@ -use bytes::BytesMut; +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; -use crate::{bytebuf::ByteBuffer, ClientPacket}; +use crate::{bytebuf::ByteBufMut, ClientPacket}; #[client_packet("config:registry_data")] pub struct CRegistryData<'a> { @@ -24,7 +24,7 @@ pub struct RegistryEntry<'a> { } impl ClientPacket for CRegistryData<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_string(self.registry_id); bytebuf.put_list::(self.entries, |p, v| { p.put_string(v.entry_id); diff --git a/pumpkin-protocol/src/client/login/c_login_success.rs b/pumpkin-protocol/src/client/login/c_login_success.rs index 462fcce5a..8c6f311a9 100644 --- a/pumpkin-protocol/src/client/login/c_login_success.rs +++ b/pumpkin-protocol/src/client/login/c_login_success.rs @@ -1,6 +1,7 @@ +use bytes::BytesMut; use pumpkin_macros::client_packet; -use crate::{bytebuf::ByteBuffer, ClientPacket, Property}; +use crate::{bytebuf::ByteBufMut, ClientPacket, Property}; #[client_packet("login:login_finished")] pub struct CLoginSuccess<'a> { @@ -20,7 +21,7 @@ impl<'a> CLoginSuccess<'a> { } impl ClientPacket for CLoginSuccess<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_uuid(self.uuid); bytebuf.put_string(self.username); bytebuf.put_list::(self.properties, |p, v| { diff --git a/pumpkin-protocol/src/client/play/c_boss_event.rs b/pumpkin-protocol/src/client/play/c_boss_event.rs index 0100c154e..449f18e1a 100644 --- a/pumpkin-protocol/src/client/play/c_boss_event.rs +++ b/pumpkin-protocol/src/client/play/c_boss_event.rs @@ -1,6 +1,7 @@ -use crate::bytebuf::ByteBuffer; +use crate::bytebuf::ByteBufMut; use crate::client::play::bossevent_action::BosseventAction; use crate::{ClientPacket, VarInt}; +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; #[client_packet("play:boss_event")] @@ -16,7 +17,7 @@ impl<'a> CBossEvent<'a> { } impl ClientPacket for CBossEvent<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_uuid(&self.uuid); let action = &self.action; match action { diff --git a/pumpkin-protocol/src/client/play/c_chunk_data.rs b/pumpkin-protocol/src/client/play/c_chunk_data.rs index 919dcc2fc..f655c00c4 100644 --- a/pumpkin-protocol/src/client/play/c_chunk_data.rs +++ b/pumpkin-protocol/src/client/play/c_chunk_data.rs @@ -1,5 +1,6 @@ -use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt}; +use crate::{bytebuf::ByteBufMut, BitSet, ClientPacket, VarInt}; +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS}; @@ -7,7 +8,7 @@ use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS}; pub struct CChunkData<'a>(pub &'a ChunkData); impl ClientPacket for CChunkData<'_> { - fn write(&self, buf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, buf: &mut BytesMut) { // Chunk X buf.put_i32(self.0.position.x); // Chunk Z @@ -18,7 +19,7 @@ impl ClientPacket for CChunkData<'_> { // Heightmaps buf.put_slice(&heightmap_nbt); - let mut data_buf = ByteBuffer::empty(); + let mut data_buf = BytesMut::new(); self.0.blocks.iter_subchunks().for_each(|chunk| { let block_count = chunk.len() as i16; // Block count @@ -102,9 +103,9 @@ impl ClientPacket for CChunkData<'_> { }); // Size - buf.put_var_int(&VarInt(data_buf.buf().len() as i32)); + buf.put_var_int(&VarInt(data_buf.len() as i32)); // Data - buf.put_slice(data_buf.buf()); + buf.put_slice(&data_buf); // TODO: block entities buf.put_var_int(&VarInt(0)); diff --git a/pumpkin-protocol/src/client/play/c_command_suggestions.rs b/pumpkin-protocol/src/client/play/c_command_suggestions.rs index fae9b04f3..d3592ce37 100644 --- a/pumpkin-protocol/src/client/play/c_command_suggestions.rs +++ b/pumpkin-protocol/src/client/play/c_command_suggestions.rs @@ -1,7 +1,8 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_core::text::TextComponent; use pumpkin_macros::client_packet; -use crate::{ClientPacket, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, VarInt}; #[client_packet("play:command_suggestions")] pub struct CCommandSuggestions<'a> { @@ -28,7 +29,7 @@ impl<'a> CCommandSuggestions<'a> { } impl ClientPacket for CCommandSuggestions<'_> { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_var_int(&self.id); bytebuf.put_var_int(&self.start); bytebuf.put_var_int(&self.length); diff --git a/pumpkin-protocol/src/client/play/c_commands.rs b/pumpkin-protocol/src/client/play/c_commands.rs index bfd885562..d3b54d6f8 100644 --- a/pumpkin-protocol/src/client/play/c_commands.rs +++ b/pumpkin-protocol/src/client/play/c_commands.rs @@ -1,6 +1,7 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; -use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, VarInt}; #[client_packet("play:commands")] pub struct CCommands<'a> { @@ -18,7 +19,7 @@ impl<'a> CCommands<'a> { } impl ClientPacket for CCommands<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_list(&self.nodes, |bytebuf, node: &ProtoNode| { node.write_to(bytebuf) }); @@ -51,7 +52,7 @@ impl ProtoNode<'_> { const FLAG_HAS_REDIRECT: u8 = 8; const FLAG_HAS_SUGGESTION_TYPE: u8 = 16; - pub fn write_to(&self, bytebuf: &mut ByteBuffer) { + pub fn write_to(&self, bytebuf: &mut BytesMut) { // flags let flags = match self.node_type { ProtoNodeType::Root => 0, @@ -187,7 +188,7 @@ impl ProtoCmdArgParser<'_> { pub const SCORE_HOLDER_FLAG_ALLOW_MULTIPLE: u8 = 1; - pub fn write_to_buffer(&self, bytebuf: &mut ByteBuffer) { + pub fn write_to_buffer(&self, bytebuf: &mut BytesMut) { match self { Self::Bool => bytebuf.put_var_int(&0.into()), Self::Float { min, max } => Self::write_number_arg(&1.into(), *min, *max, bytebuf), @@ -269,7 +270,7 @@ impl ProtoCmdArgParser<'_> { id: &VarInt, min: Option, max: Option, - bytebuf: &mut ByteBuffer, + bytebuf: &mut BytesMut, ) { let mut flags: u8 = 0; if min.is_some() { @@ -290,13 +291,13 @@ impl ProtoCmdArgParser<'_> { } } - fn write_with_flags(id: &VarInt, flags: u8, bytebuf: &mut ByteBuffer) { + fn write_with_flags(id: &VarInt, flags: u8, bytebuf: &mut BytesMut) { bytebuf.put_var_int(id); bytebuf.put_u8(flags); } - fn write_with_identifier(id: &VarInt, extra_identifier: &str, bytebuf: &mut ByteBuffer) { + fn write_with_identifier(id: &VarInt, extra_identifier: &str, bytebuf: &mut BytesMut) { bytebuf.put_var_int(id); bytebuf.put_string(extra_identifier); @@ -312,29 +313,29 @@ pub enum StringProtoArgBehavior { } trait NumberCmdArg { - fn write(self, bytebuf: &mut ByteBuffer); + fn write(self, bytebuf: &mut BytesMut); } impl NumberCmdArg for f32 { - fn write(self, bytebuf: &mut ByteBuffer) { + fn write(self, bytebuf: &mut BytesMut) { bytebuf.put_f32(self); } } impl NumberCmdArg for f64 { - fn write(self, bytebuf: &mut ByteBuffer) { + fn write(self, bytebuf: &mut BytesMut) { bytebuf.put_f64(self); } } impl NumberCmdArg for i32 { - fn write(self, bytebuf: &mut ByteBuffer) { + fn write(self, bytebuf: &mut BytesMut) { bytebuf.put_i32(self); } } impl NumberCmdArg for i64 { - fn write(self, bytebuf: &mut ByteBuffer) { + fn write(self, bytebuf: &mut BytesMut) { bytebuf.put_i64(self); } } diff --git a/pumpkin-protocol/src/client/play/c_entity_sound_effect.rs b/pumpkin-protocol/src/client/play/c_entity_sound_effect.rs index 62afd46d2..37848de87 100644 --- a/pumpkin-protocol/src/client/play/c_entity_sound_effect.rs +++ b/pumpkin-protocol/src/client/play/c_entity_sound_effect.rs @@ -1,6 +1,7 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; -use crate::{ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt}; #[client_packet("play:sound_entity")] pub struct CEntitySoundEffect { @@ -38,7 +39,7 @@ impl CEntitySoundEffect { } impl ClientPacket for CEntitySoundEffect { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_var_int(&self.sound_event.id); if self.sound_event.id.0 == 0 { if let Some(test) = &self.sound_event.sound_event { diff --git a/pumpkin-protocol/src/client/play/c_player_info_update.rs b/pumpkin-protocol/src/client/play/c_player_info_update.rs index 09fbff949..5626b3877 100644 --- a/pumpkin-protocol/src/client/play/c_player_info_update.rs +++ b/pumpkin-protocol/src/client/play/c_player_info_update.rs @@ -1,6 +1,7 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; -use crate::{bytebuf::ByteBuffer, ClientPacket, Property}; +use crate::{bytebuf::ByteBufMut, ClientPacket, Property}; use super::PlayerAction; @@ -22,7 +23,7 @@ impl<'a> CPlayerInfoUpdate<'a> { } impl ClientPacket for CPlayerInfoUpdate<'_> { - fn write(&self, bytebuf: &mut ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_i8(self.actions); bytebuf.put_list::(self.players, |p, v| { p.put_uuid(&v.uuid); diff --git a/pumpkin-protocol/src/client/play/c_player_position.rs b/pumpkin-protocol/src/client/play/c_player_position.rs index 0a99a9e09..96a6bc594 100644 --- a/pumpkin-protocol/src/client/play/c_player_position.rs +++ b/pumpkin-protocol/src/client/play/c_player_position.rs @@ -1,7 +1,8 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_core::math::vector3::Vector3; use pumpkin_macros::client_packet; -use crate::{ClientPacket, PositionFlag, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, PositionFlag, VarInt}; #[client_packet("play:player_position")] pub struct CPlayerPosition<'a> { @@ -34,7 +35,7 @@ impl<'a> CPlayerPosition<'a> { } impl ClientPacket for CPlayerPosition<'_> { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_var_int(&self.teleport_id); bytebuf.put_f64(self.position.x); bytebuf.put_f64(self.position.y); diff --git a/pumpkin-protocol/src/client/play/c_sound_effect.rs b/pumpkin-protocol/src/client/play/c_sound_effect.rs index 14e92ec94..d2f7f3445 100644 --- a/pumpkin-protocol/src/client/play/c_sound_effect.rs +++ b/pumpkin-protocol/src/client/play/c_sound_effect.rs @@ -1,6 +1,7 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_macros::client_packet; -use crate::{ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, IDOrSoundEvent, SoundCategory, SoundEvent, VarInt}; #[client_packet("play:sound")] pub struct CSoundEffect { @@ -44,7 +45,7 @@ impl CSoundEffect { } impl ClientPacket for CSoundEffect { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_var_int(&self.sound_event.id); if self.sound_event.id.0 == 0 { if let Some(test) = &self.sound_event.sound_event { diff --git a/pumpkin-protocol/src/client/play/c_teleport_entity.rs b/pumpkin-protocol/src/client/play/c_teleport_entity.rs index b5bc2151c..02029373e 100644 --- a/pumpkin-protocol/src/client/play/c_teleport_entity.rs +++ b/pumpkin-protocol/src/client/play/c_teleport_entity.rs @@ -1,7 +1,8 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_core::math::vector3::Vector3; use pumpkin_macros::client_packet; -use crate::{ClientPacket, PositionFlag, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, PositionFlag, VarInt}; #[client_packet("play:teleport_entity")] pub struct CTeleportEntity<'a> { @@ -37,7 +38,7 @@ impl<'a> CTeleportEntity<'a> { } impl ClientPacket for CTeleportEntity<'_> { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_var_int(&self.entity_id); bytebuf.put_f64(self.position.x); bytebuf.put_f64(self.position.y); diff --git a/pumpkin-protocol/src/client/play/c_update_objectives.rs b/pumpkin-protocol/src/client/play/c_update_objectives.rs index e5ae2e2d1..12fcefc3e 100644 --- a/pumpkin-protocol/src/client/play/c_update_objectives.rs +++ b/pumpkin-protocol/src/client/play/c_update_objectives.rs @@ -1,7 +1,8 @@ +use bytes::{BufMut, BytesMut}; use pumpkin_core::text::TextComponent; use pumpkin_macros::client_packet; -use crate::{ClientPacket, NumberFormat, VarInt}; +use crate::{bytebuf::ByteBufMut, ClientPacket, NumberFormat, VarInt}; #[client_packet("play:set_objective")] pub struct CUpdateObjectives<'a> { @@ -31,7 +32,7 @@ impl<'a> CUpdateObjectives<'a> { } impl ClientPacket for CUpdateObjectives<'_> { - fn write(&self, bytebuf: &mut crate::bytebuf::ByteBuffer) { + fn write(&self, bytebuf: &mut BytesMut) { bytebuf.put_string(self.objective_name); bytebuf.put_u8(self.mode); if self.mode == 0 || self.mode == 2 { diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 0143abe48..336e86f01 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -1,4 +1,5 @@ -use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError}; +use bytebuf::{packet_id::Packet, ReadingError}; +use bytes::{Bytes, BytesMut}; use pumpkin_core::text::{style::Style, TextComponent}; use serde::{Deserialize, Serialize, Serializer}; @@ -22,8 +23,10 @@ pub const CURRENT_MC_PROTOCOL: u32 = 769; pub const MAX_PACKET_SIZE: i32 = 2097152; -/// usually uses a namespace like "minecraft:thing" +/// usally uses a namespace like "minecraft:thing" pub type Identifier = String; +pub type VarIntType = i32; +pub type VarLongType = i64; pub type FixedBitSet = bytes::Bytes; pub struct BitSet<'a>(pub VarInt, pub &'a [i64]); @@ -90,15 +93,15 @@ pub struct SoundEvent { pub struct RawPacket { pub id: VarInt, - pub bytebuf: ByteBuffer, + pub bytebuf: Bytes, } pub trait ClientPacket: Packet { - fn write(&self, bytebuf: &mut ByteBuffer); + fn write(&self, bytebuf: &mut BytesMut); } pub trait ServerPacket: Packet + Sized { - fn read(bytebuf: &mut ByteBuffer) -> Result; + fn read(bytebuf: &mut Bytes) -> Result; } #[derive(Serialize)] diff --git a/pumpkin-protocol/src/packet_decoder.rs b/pumpkin-protocol/src/packet_decoder.rs index 9472c28ee..f40db1bbf 100644 --- a/pumpkin-protocol/src/packet_decoder.rs +++ b/pumpkin-protocol/src/packet_decoder.rs @@ -1,9 +1,9 @@ use aes::cipher::{generic_array::GenericArray, BlockDecryptMut, BlockSizeUser, KeyIvInit}; -use bytes::{Buf, BytesMut}; +use bytes::{Buf, Bytes, BytesMut}; use libdeflater::{DecompressionError, Decompressor}; use thiserror::Error; -use crate::{bytebuf::ByteBuffer, RawPacket, VarInt, VarIntDecodeError, MAX_PACKET_SIZE}; +use crate::{RawPacket, VarInt, VarIntDecodeError, MAX_PACKET_SIZE}; type Cipher = cfb8::Decryptor; @@ -113,7 +113,7 @@ impl PacketDecoder { data.advance(data.len() - r.len()); Ok(Some(RawPacket { id: packet_id, - bytebuf: ByteBuffer::new(data), + bytebuf: Bytes::from(data), })) } @@ -201,8 +201,11 @@ impl From for PacketDecodeError { #[cfg(test)] mod tests { + use crate::bytebuf::ByteBufMut; + use super::*; use aes::Aes128; + use bytes::BufMut; use cfb8::cipher::AsyncStreamCipher; use cfb8::Encryptor as Cfb8Encryptor; use libdeflater::{CompressionLvl, Compressor}; @@ -232,18 +235,18 @@ mod tests { key: Option<&[u8; 16]>, iv: Option<&[u8; 16]>, ) -> Vec { - let mut buffer = ByteBuffer::empty(); + let mut buffer = BytesMut::new(); if compress { // Create a buffer that includes packet_id_varint and payload - let mut data_to_compress = ByteBuffer::empty(); + let mut data_to_compress = BytesMut::new(); let packet_id_varint = VarInt(packet_id); data_to_compress.put_var_int(&packet_id_varint); data_to_compress.put_slice(payload); // Compress the combined data - let compressed_payload = compress_zlib(data_to_compress.buf()); - let data_len = data_to_compress.buf().len() as i32; // 1 + payload.len() + let compressed_payload = compress_zlib(&data_to_compress); + let data_len = data_to_compress.len() as i32; // 1 + payload.len() let data_len_varint = VarInt(data_len); buffer.put_var_int(&data_len_varint); buffer.put_slice(&compressed_payload); @@ -255,7 +258,7 @@ mod tests { } // Calculate packet length: length of buffer - let packet_len = buffer.buf().len() as i32; + let packet_len = buffer.len() as i32; let packet_len_varint = VarInt(packet_len); let mut packet_length_encoded = Vec::new(); { @@ -265,7 +268,7 @@ mod tests { // Create a new buffer for the entire packet let mut packet = Vec::new(); packet.extend_from_slice(&packet_length_encoded); - packet.extend_from_slice(buffer.buf()); + packet.extend_from_slice(&buffer); // Encrypt if key and iv are provided if let (Some(k), Some(v)) = (key, iv) { @@ -297,9 +300,9 @@ mod tests { let result = decoder.decode().expect("Decoding failed"); assert!(result.is_some()); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!(raw_packet.id.0, packet_id); - assert_eq!(raw_packet.bytebuf.buf().as_ref(), payload); + assert_eq!(raw_packet.bytebuf.as_ref(), payload); } /// Test decoding with compression @@ -323,9 +326,9 @@ mod tests { let result = decoder.decode().expect("Decoding failed"); assert!(result.is_some()); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!(raw_packet.id.0, packet_id); - assert_eq!(raw_packet.bytebuf.buf().as_ref(), payload); + assert_eq!(raw_packet.bytebuf.as_ref(), payload); } /// Test decoding with encryption @@ -354,9 +357,9 @@ mod tests { let result = decoder.decode().expect("Decoding failed"); assert!(result.is_some()); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!(raw_packet.id.0, packet_id); - assert_eq!(raw_packet.bytebuf.buf().as_ref(), payload); + assert_eq!(raw_packet.bytebuf.as_ref(), payload); } /// Test decoding with both compression and encryption @@ -385,9 +388,9 @@ mod tests { let result = decoder.decode().expect("Decoding failed"); assert!(result.is_some()); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!(raw_packet.id.0, packet_id); - assert_eq!(raw_packet.bytebuf.buf().as_ref(), payload); + assert_eq!(raw_packet.bytebuf.as_ref(), payload); } /// Test decoding with invalid compressed data @@ -398,28 +401,28 @@ mod tests { let invalid_compressed_data = vec![0xFF, 0xFF, 0xFF]; // Invalid Zlib data // Build the packet with compression enabled but invalid compressed data - let mut buffer = ByteBuffer::empty(); + let mut buffer = BytesMut::new(); let data_len_varint = VarInt(data_len); buffer.put_var_int(&data_len_varint); buffer.put_slice(&invalid_compressed_data); // Calculate packet length: VarInt(data_len) + invalid compressed data - let packet_len = buffer.buf().len() as i32; + let packet_len = buffer.len() as i32; let packet_len_varint = VarInt(packet_len); // Create a new buffer for the entire packet - let mut packet_buffer = ByteBuffer::empty(); + let mut packet_buffer = BytesMut::new(); packet_buffer.put_var_int(&packet_len_varint); - packet_buffer.put_slice(buffer.buf()); + packet_buffer.put_slice(&buffer); - let packet_bytes = packet_buffer.buf(); + let packet_bytes = packet_buffer; // Initialize the decoder with compression enabled let mut decoder = PacketDecoder::default(); decoder.set_compression(true); // Feed the invalid compressed packet to the decoder - decoder.queue_slice(packet_bytes); + decoder.queue_slice(&packet_bytes); // Attempt to decode and expect a decompression error let result = decoder.decode(); @@ -450,9 +453,9 @@ mod tests { let result = decoder.decode().expect("Decoding failed"); assert!(result.is_some()); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!(raw_packet.id.0, packet_id); - assert_eq!(raw_packet.bytebuf.buf().as_ref(), payload); + assert_eq!(raw_packet.bytebuf.as_ref(), payload); } /// Test decoding with maximum length packet @@ -484,13 +487,13 @@ mod tests { "Decoder returned None when it should have decoded a packet" ); - let mut raw_packet = result.unwrap(); + let raw_packet = result.unwrap(); assert_eq!( raw_packet.id.0, packet_id, "Decoded packet_id does not match" ); assert_eq!( - raw_packet.bytebuf.buf().as_ref(), + raw_packet.bytebuf.as_ref(), &payload[..], "Decoded payload does not match" ); diff --git a/pumpkin-protocol/src/packet_encoder.rs b/pumpkin-protocol/src/packet_encoder.rs index 0df2b1570..3ce1f3b41 100644 --- a/pumpkin-protocol/src/packet_encoder.rs +++ b/pumpkin-protocol/src/packet_encoder.rs @@ -5,7 +5,7 @@ use thiserror::Error; use libdeflater::{CompressionLvl, Compressor}; -use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt, MAX_PACKET_SIZE}; +use crate::{ClientPacket, VarInt, MAX_PACKET_SIZE}; type Cipher = cfb8::Encryptor; @@ -39,10 +39,8 @@ impl PacketEncoder { let start_len = self.buf.len(); // Write the Packet ID first VarInt(P::PACKET_ID).encode(&mut self.buf); - let mut packet_buf = ByteBuffer::empty(); // Now write the packet into an empty buffer - packet.write(&mut packet_buf); - self.buf.put(packet_buf.buf()); + packet.write(&mut self.buf); let data_len = self.buf.len() - start_len; @@ -274,10 +272,10 @@ mod tests { // Remaining buffer is the payload // We need to obtain the expected payload - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); - assert_eq!(buffer, expected_payload.buf()); + assert_eq!(buffer, expected_payload); } /// Test encoding with compression @@ -308,10 +306,10 @@ mod tests { // Read data length VarInt (uncompressed data length) let data_length = decode_varint(&mut buffer).expect("Failed to decode data length"); - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); let uncompressed_data_length = - VarInt(CStatusResponse::PACKET_ID).written_size() + expected_payload.buf().len(); + VarInt(CStatusResponse::PACKET_ID).written_size() + expected_payload.len(); assert_eq!(data_length as usize, uncompressed_data_length); // Remaining buffer is the compressed data @@ -330,7 +328,7 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload - assert_eq!(decompressed_buffer, expected_payload.buf()); + assert_eq!(decompressed_buffer, expected_payload); } /// Test encoding with encryption @@ -364,10 +362,10 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); - assert_eq!(buffer, expected_payload.buf()); + assert_eq!(buffer, expected_payload); } /// Test encoding with both compression and encryption @@ -405,10 +403,10 @@ mod tests { // Read data length VarInt (uncompressed data length) let data_length = decode_varint(&mut buffer).expect("Failed to decode data length"); - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); let uncompressed_data_length = - VarInt(CStatusResponse::PACKET_ID).written_size() + expected_payload.buf().len(); + VarInt(CStatusResponse::PACKET_ID).written_size() + expected_payload.len(); assert_eq!(data_length as usize, uncompressed_data_length); // Remaining buffer is the compressed data @@ -427,7 +425,7 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload - assert_eq!(decompressed_buffer, expected_payload.buf()); + assert_eq!(decompressed_buffer, expected_payload); } /// Test encoding with zero-length payload @@ -455,15 +453,15 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload (empty) - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); assert_eq!( buffer.len(), - expected_payload.buf().len(), + expected_payload.len(), "Payload length mismatch" ); - assert_eq!(buffer, expected_payload.buf()); + assert_eq!(buffer, expected_payload); } /// Test encoding with maximum length payload @@ -500,10 +498,10 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); - assert_eq!(buffer, expected_payload.buf()); + assert_eq!(buffer, expected_payload); } /// Test encoding a packet that exceeds MAX_PACKET_SIZE @@ -557,9 +555,9 @@ mod tests { assert_eq!(decoded_packet_id, CStatusResponse::PACKET_ID); // Remaining buffer is the payload - let mut expected_payload = ByteBuffer::empty(); + let mut expected_payload = BytesMut::new(); packet.write(&mut expected_payload); - assert_eq!(buffer, expected_payload.buf()); + assert_eq!(buffer, expected_payload); } } diff --git a/pumpkin-protocol/src/server/config/s_cookie_response.rs b/pumpkin-protocol/src/server/config/s_cookie_response.rs index 69440254b..ec3f4da05 100644 --- a/pumpkin-protocol/src/server/config/s_cookie_response.rs +++ b/pumpkin-protocol/src/server/config/s_cookie_response.rs @@ -1,8 +1,11 @@ +use bytes::Bytes; use pumpkin_macros::server_packet; use serde::de; -use crate::bytebuf::{ByteBuffer, DeserializerError}; -use crate::{Identifier, ServerPacket, VarInt}; +use crate::{ + bytebuf::{ByteBuf, ReadingError}, + Identifier, ServerPacket, VarInt, +}; #[server_packet("config:cookie_response")] /// Response to a Cookie Request (configuration) from the server. @@ -17,9 +20,9 @@ pub struct SCookieResponse { const MAX_PAYLOAD_SIZE: i32 = 5120; impl ServerPacket for SCookieResponse { - fn read(bytebuf: &mut ByteBuffer) -> Result { - let key = bytebuf.get_string()?; - let has_payload = bytebuf.get_bool()?; + fn read(bytebuf: &mut Bytes) -> Result { + let key = bytebuf.try_get_string()?; + let has_payload = bytebuf.try_get_bool()?; if !has_payload { return Ok(Self { @@ -30,7 +33,7 @@ impl ServerPacket for SCookieResponse { }); } - let payload_length = bytebuf.get_var_int()?; + let payload_length = bytebuf.try_get_var_int()?; let length = payload_length.0; if length > MAX_PAYLOAD_SIZE { @@ -39,7 +42,7 @@ impl ServerPacket for SCookieResponse { )); } - let payload = bytebuf.copy_to_bytes(length as usize)?; + let payload = bytebuf.try_copy_to_bytes(length as usize)?; Ok(Self { key, diff --git a/pumpkin-protocol/src/server/config/s_plugin_message.rs b/pumpkin-protocol/src/server/config/s_plugin_message.rs index d5770139c..259187614 100644 --- a/pumpkin-protocol/src/server/config/s_plugin_message.rs +++ b/pumpkin-protocol/src/server/config/s_plugin_message.rs @@ -1,21 +1,22 @@ +use bytes::Bytes; use pumpkin_macros::server_packet; use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, Identifier, ServerPacket, }; #[server_packet("config:custom_payload")] pub struct SPluginMessage { pub channel: Identifier, - pub data: bytes::BytesMut, + pub data: bytes::Bytes, } impl ServerPacket for SPluginMessage { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - channel: bytebuf.get_string()?, - data: bytebuf.get_slice(), + channel: bytebuf.try_get_string()?, + data: bytebuf.split_to(bytebuf.len()), }) } } diff --git a/pumpkin-protocol/src/server/handshake/mod.rs b/pumpkin-protocol/src/server/handshake/mod.rs index a1d743528..0e8a15aee 100644 --- a/pumpkin-protocol/src/server/handshake/mod.rs +++ b/pumpkin-protocol/src/server/handshake/mod.rs @@ -1,7 +1,8 @@ +use bytes::Bytes; use pumpkin_macros::server_packet; use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, ConnectionState, ServerPacket, VarInt, }; @@ -14,12 +15,12 @@ pub struct SHandShake { } impl ServerPacket for SHandShake { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - protocol_version: bytebuf.get_var_int()?, - server_address: bytebuf.get_string_len(255)?, - server_port: bytebuf.get_u16()?, - next_state: bytebuf.get_var_int()?.into(), + protocol_version: bytebuf.try_get_var_int()?, + server_address: bytebuf.try_get_string_len(255)?, + server_port: bytebuf.try_get_u16()?, + next_state: bytebuf.try_get_var_int()?.into(), }) } } diff --git a/pumpkin-protocol/src/server/login/s_cookie_response.rs b/pumpkin-protocol/src/server/login/s_cookie_response.rs index 8f70bfb52..833ae7887 100644 --- a/pumpkin-protocol/src/server/login/s_cookie_response.rs +++ b/pumpkin-protocol/src/server/login/s_cookie_response.rs @@ -1,5 +1,8 @@ -use crate::bytebuf::{ByteBuffer, DeserializerError}; -use crate::{Identifier, ServerPacket, VarInt}; +use crate::{ + bytebuf::{ByteBuf, ReadingError}, + Identifier, ServerPacket, VarInt, +}; +use bytes::Bytes; use pumpkin_macros::server_packet; use serde::de; @@ -16,9 +19,9 @@ pub struct SCookieResponse { const MAX_PAYLOAD_SIZE: i32 = 5120; impl ServerPacket for SCookieResponse { - fn read(bytebuf: &mut ByteBuffer) -> Result { - let key = bytebuf.get_string()?; - let has_payload = bytebuf.get_bool()?; + fn read(bytebuf: &mut Bytes) -> Result { + let key = bytebuf.try_get_string()?; + let has_payload = bytebuf.try_get_bool()?; if !has_payload { return Ok(Self { @@ -29,7 +32,7 @@ impl ServerPacket for SCookieResponse { }); } - let payload_length = bytebuf.get_var_int()?; + let payload_length = bytebuf.try_get_var_int()?; let length = payload_length.0; if length > MAX_PAYLOAD_SIZE { @@ -38,7 +41,7 @@ impl ServerPacket for SCookieResponse { )); } - let payload = bytebuf.copy_to_bytes(length as usize)?; + let payload = bytebuf.try_copy_to_bytes(length as usize)?; Ok(Self { key, diff --git a/pumpkin-protocol/src/server/login/s_encryption_response.rs b/pumpkin-protocol/src/server/login/s_encryption_response.rs index 64be02b4c..300ada9c0 100644 --- a/pumpkin-protocol/src/server/login/s_encryption_response.rs +++ b/pumpkin-protocol/src/server/login/s_encryption_response.rs @@ -1,7 +1,8 @@ +use bytes::Bytes; use pumpkin_macros::server_packet; use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, ServerPacket, VarInt, }; @@ -14,11 +15,11 @@ pub struct SEncryptionResponse { } impl ServerPacket for SEncryptionResponse { - fn read(bytebuf: &mut ByteBuffer) -> Result { - let shared_secret_length = bytebuf.get_var_int()?; - let shared_secret = bytebuf.copy_to_bytes(shared_secret_length.0 as usize)?; - let verify_token_length = bytebuf.get_var_int()?; - let verify_token = bytebuf.copy_to_bytes(shared_secret_length.0 as usize)?; + fn read(bytebuf: &mut Bytes) -> Result { + let shared_secret_length = bytebuf.try_get_var_int()?; + let shared_secret = bytebuf.try_copy_to_bytes(shared_secret_length.0 as usize)?; + let verify_token_length = bytebuf.try_get_var_int()?; + let verify_token = bytebuf.try_copy_to_bytes(shared_secret_length.0 as usize)?; Ok(Self { shared_secret_length, shared_secret, diff --git a/pumpkin-protocol/src/server/login/s_login_start.rs b/pumpkin-protocol/src/server/login/s_login_start.rs index 7a4a724da..44347dc73 100644 --- a/pumpkin-protocol/src/server/login/s_login_start.rs +++ b/pumpkin-protocol/src/server/login/s_login_start.rs @@ -1,7 +1,8 @@ +use bytes::Bytes; use pumpkin_macros::server_packet; use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, ServerPacket, }; @@ -12,10 +13,10 @@ pub struct SLoginStart { } impl ServerPacket for SLoginStart { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - name: bytebuf.get_string_len(16)?, - uuid: bytebuf.get_uuid()?, + name: bytebuf.try_get_string_len(16)?, + uuid: bytebuf.try_get_uuid()?, }) } } diff --git a/pumpkin-protocol/src/server/login/s_plugin_response.rs b/pumpkin-protocol/src/server/login/s_plugin_response.rs index 24656471e..d96b796ee 100644 --- a/pumpkin-protocol/src/server/login/s_plugin_response.rs +++ b/pumpkin-protocol/src/server/login/s_plugin_response.rs @@ -1,21 +1,21 @@ use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, ServerPacket, VarInt, }; -use bytes::BytesMut; +use bytes::Bytes; use pumpkin_macros::server_packet; #[server_packet("login:custom_query_answer")] pub struct SLoginPluginResponse { pub message_id: VarInt, - pub data: Option, + pub data: Option, } impl ServerPacket for SLoginPluginResponse { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - message_id: bytebuf.get_var_int()?, - data: bytebuf.get_option(|v| Ok(v.get_slice()))?, + message_id: bytebuf.try_get_var_int()?, + data: bytebuf.try_get_option(|v| Ok(v.split_to(v.len())))?, }) } } diff --git a/pumpkin-protocol/src/server/play/s_chat_message.rs b/pumpkin-protocol/src/server/play/s_chat_message.rs index a8e61d746..9fd65df39 100644 --- a/pumpkin-protocol/src/server/play/s_chat_message.rs +++ b/pumpkin-protocol/src/server/play/s_chat_message.rs @@ -2,7 +2,7 @@ use bytes::Bytes; use pumpkin_macros::server_packet; use crate::{ - bytebuf::{ByteBuffer, DeserializerError}, + bytebuf::{ByteBuf, ReadingError}, FixedBitSet, ServerPacket, VarInt, }; @@ -19,14 +19,14 @@ pub struct SChatMessage { // TODO impl ServerPacket for SChatMessage { - fn read(bytebuf: &mut ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - message: bytebuf.get_string()?, - timestamp: bytebuf.get_i64()?, - salt: bytebuf.get_i64()?, - signature: bytebuf.get_option(|v| v.copy_to_bytes(256))?, - message_count: bytebuf.get_var_int()?, - acknowledged: bytebuf.get_fixed_bitset(20)?, + message: bytebuf.try_get_string()?, + timestamp: bytebuf.try_get_i64()?, + salt: bytebuf.try_get_i64()?, + signature: bytebuf.try_get_option(|v| v.try_copy_to_bytes(256))?, + message_count: bytebuf.try_get_var_int()?, + acknowledged: bytebuf.try_get_fixed_bitset(20)?, }) } } diff --git a/pumpkin-protocol/src/server/play/s_cookie_response.rs b/pumpkin-protocol/src/server/play/s_cookie_response.rs index b7ad9b703..f3127fb47 100644 --- a/pumpkin-protocol/src/server/play/s_cookie_response.rs +++ b/pumpkin-protocol/src/server/play/s_cookie_response.rs @@ -1,5 +1,8 @@ -use crate::bytebuf::{ByteBuffer, DeserializerError}; -use crate::{Identifier, ServerPacket, VarInt}; +use crate::{ + bytebuf::{ByteBuf, ReadingError}, + Identifier, ServerPacket, VarInt, +}; +use bytes::Bytes; use pumpkin_macros::server_packet; use serde::de; @@ -16,9 +19,9 @@ pub struct SCookieResponse { const MAX_PAYLOAD_SIZE: i32 = 5120; impl ServerPacket for SCookieResponse { - fn read(bytebuf: &mut ByteBuffer) -> Result { - let key = bytebuf.get_string()?; - let has_payload = bytebuf.get_bool()?; + fn read(bytebuf: &mut Bytes) -> Result { + let key = bytebuf.try_get_string()?; + let has_payload = bytebuf.try_get_bool()?; if !has_payload { return Ok(Self { @@ -29,7 +32,7 @@ impl ServerPacket for SCookieResponse { }); } - let payload_length = bytebuf.get_var_int()?; + let payload_length = bytebuf.try_get_var_int()?; let length = payload_length.0; if length > MAX_PAYLOAD_SIZE { @@ -38,7 +41,7 @@ impl ServerPacket for SCookieResponse { )); } - let payload = bytebuf.copy_to_bytes(length as usize)?; + let payload = bytebuf.try_copy_to_bytes(length as usize)?; Ok(Self { key, diff --git a/pumpkin-protocol/src/server/play/s_interact.rs b/pumpkin-protocol/src/server/play/s_interact.rs index f283f0487..c7371502e 100644 --- a/pumpkin-protocol/src/server/play/s_interact.rs +++ b/pumpkin-protocol/src/server/play/s_interact.rs @@ -1,9 +1,13 @@ +use bytes::Bytes; use num_derive::FromPrimitive; use num_traits::FromPrimitive; use pumpkin_core::math::vector3::Vector3; use pumpkin_macros::server_packet; -use crate::{bytebuf::DeserializerError, ServerPacket, VarInt}; +use crate::{ + bytebuf::{ByteBuf, ReadingError}, + ServerPacket, VarInt, +}; #[server_packet("play:interact")] pub struct SInteract { @@ -16,27 +20,24 @@ pub struct SInteract { // Great job Mojang ;D impl ServerPacket for SInteract { - fn read( - bytebuf: &mut crate::bytebuf::ByteBuffer, - ) -> Result { - let entity_id = bytebuf.get_var_int()?; - let typ = bytebuf.get_var_int()?; - let action = ActionType::from_i32(typ.0).ok_or(DeserializerError::Message( - "invalid action type".to_string(), - ))?; + fn read(bytebuf: &mut Bytes) -> Result { + let entity_id = bytebuf.try_get_var_int()?; + let typ = bytebuf.try_get_var_int()?; + let action = ActionType::from_i32(typ.0) + .ok_or(ReadingError::Message("invalid action type".to_string()))?; let target_position: Option> = match action { ActionType::Interact => None, ActionType::Attack => None, ActionType::InteractAt => Some(Vector3::new( - bytebuf.get_f32()?, - bytebuf.get_f32()?, - bytebuf.get_f32()?, + bytebuf.try_get_f32()?, + bytebuf.try_get_f32()?, + bytebuf.try_get_f32()?, )), }; let hand = match action { - ActionType::Interact => Some(bytebuf.get_var_int()?), + ActionType::Interact => Some(bytebuf.try_get_var_int()?), ActionType::Attack => None, - ActionType::InteractAt => Some(bytebuf.get_var_int()?), + ActionType::InteractAt => Some(bytebuf.try_get_var_int()?), }; Ok(Self { @@ -44,7 +45,7 @@ impl ServerPacket for SInteract { typ, target_position, hand, - sneaking: bytebuf.get_bool()?, + sneaking: bytebuf.try_get_bool()?, }) } } diff --git a/pumpkin-protocol/src/server/play/s_player_command.rs b/pumpkin-protocol/src/server/play/s_player_command.rs index aeafcf153..8b2c7055d 100644 --- a/pumpkin-protocol/src/server/play/s_player_command.rs +++ b/pumpkin-protocol/src/server/play/s_player_command.rs @@ -1,7 +1,11 @@ +use bytes::Bytes; use num_derive::FromPrimitive; use pumpkin_macros::server_packet; -use crate::{bytebuf::DeserializerError, ServerPacket, VarInt}; +use crate::{ + bytebuf::{ByteBuf, ReadingError}, + ServerPacket, VarInt, +}; #[server_packet("play:player_command")] pub struct SPlayerCommand { @@ -23,11 +27,11 @@ pub enum Action { } impl ServerPacket for SPlayerCommand { - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Result { + fn read(bytebuf: &mut Bytes) -> Result { Ok(Self { - entity_id: bytebuf.get_var_int()?, - action: bytebuf.get_var_int()?, - jump_boost: bytebuf.get_var_int()?, + entity_id: bytebuf.try_get_var_int()?, + action: bytebuf.try_get_var_int()?, + jump_boost: bytebuf.try_get_var_int()?, }) } } diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 6c260447a..9fd6fed04 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -17,7 +17,7 @@ use crossbeam::atomic::AtomicCell; use pumpkin_config::compression::CompressionInfo; use pumpkin_core::text::TextComponent; use pumpkin_protocol::{ - bytebuf::{packet_id::Packet, DeserializerError}, + bytebuf::{packet_id::Packet, ReadingError}, client::{config::CConfigDisconnect, login::CLoginDisconnect, play::CPlayDisconnect}, packet_decoder::PacketDecoder, packet_encoder::{PacketEncodeError, PacketEncoder}, @@ -343,7 +343,7 @@ impl Client { &self, server: &Arc, packet: &mut RawPacket, - ) -> Result<(), DeserializerError> { + ) -> Result<(), ReadingError> { match self.connection_state.load() { pumpkin_protocol::ConnectionState::HandShake => { self.handle_handshake_packet(packet).await @@ -366,10 +366,7 @@ impl Client { } } - async fn handle_handshake_packet( - &self, - packet: &mut RawPacket, - ) -> Result<(), DeserializerError> { + async fn handle_handshake_packet(&self, packet: &mut RawPacket) -> Result<(), ReadingError> { log::debug!("Handling handshake group"); let bytebuf = &mut packet.bytebuf; match packet.id.0 { @@ -390,7 +387,7 @@ impl Client { &self, server: &Arc, packet: &mut RawPacket, - ) -> Result<(), DeserializerError> { + ) -> Result<(), ReadingError> { log::debug!("Handling status group"); let bytebuf = &mut packet.bytebuf; match packet.id.0 { @@ -416,7 +413,7 @@ impl Client { &self, server: &Arc, packet: &mut RawPacket, - ) -> Result<(), DeserializerError> { + ) -> Result<(), ReadingError> { log::debug!("Handling login group for id"); let bytebuf = &mut packet.bytebuf; match packet.id.0 { @@ -452,7 +449,7 @@ impl Client { &self, server: &Arc, packet: &mut RawPacket, - ) -> Result<(), DeserializerError> { + ) -> Result<(), ReadingError> { log::debug!("Handling config group"); let bytebuf = &mut packet.bytebuf; match packet.id.0 { diff --git a/pumpkin/src/error.rs b/pumpkin/src/error.rs index d83e9a3e1..10cd79ca3 100644 --- a/pumpkin/src/error.rs +++ b/pumpkin/src/error.rs @@ -1,6 +1,6 @@ use log::log; use pumpkin_inventory::InventoryError; -use pumpkin_protocol::bytebuf::DeserializerError; +use pumpkin_protocol::bytebuf::ReadingError; use std::fmt::Display; pub trait PumpkinError: Send + std::error::Error + Display { @@ -52,7 +52,7 @@ impl PumpkinError for InventoryError { } } -impl PumpkinError for DeserializerError { +impl PumpkinError for ReadingError { fn is_kick(&self) -> bool { true } diff --git a/pumpkin/src/proxy/velocity.rs b/pumpkin/src/proxy/velocity.rs index 95f9aa07f..68f7d4e9e 100644 --- a/pumpkin/src/proxy/velocity.rs +++ b/pumpkin/src/proxy/velocity.rs @@ -7,7 +7,7 @@ use bytes::{BufMut, BytesMut}; use hmac::{Hmac, Mac}; use pumpkin_config::proxy::VelocityConfig; use pumpkin_protocol::{ - bytebuf::ByteBuffer, client::login::CLoginPluginRequest, server::login::SLoginPluginResponse, + bytebuf::ByteBuf, client::login::CLoginPluginRequest, server::login::SLoginPluginResponse, Property, }; use rand::Rng; @@ -68,19 +68,19 @@ pub fn check_integrity(data: (&[u8], &[u8]), secret: &str) -> bool { mac.verify_slice(signature).is_ok() } -fn read_game_profile(buf: &mut ByteBuffer) -> Result { +fn read_game_profile(buf: &mut BytesMut) -> Result { let id = buf - .get_uuid() + .try_get_uuid() .map_err(|_| VelocityError::FailedReadProfileUUID)?; let name = buf - .get_string() + .try_get_string() .map_err(|_| VelocityError::FailedReadProfileName)?; let properties = buf .get_list(|data| { - let name = data.get_string()?; - let value = data.get_string()?; - let signature = data.get_option(pumpkin_protocol::bytebuf::ByteBuffer::get_string)?; + let name = data.try_get_string()?; + let value = data.try_get_string()?; + let signature = data.try_get_option(ByteBuf::try_get_string)?; Ok(Property { name, @@ -109,12 +109,12 @@ pub fn receive_velocity_plugin_response( if !check_integrity((signature, data_without_signature), &config.secret) { return Err(VelocityError::FailedVerifyIntegrity); } - let mut buf = ByteBuffer::new(BytesMut::new()); + let mut buf = BytesMut::new(); buf.put_slice(data_without_signature); // check velocity version let version = buf - .get_var_int() + .try_get_var_int() .map_err(|_| VelocityError::FailedReadForwardVersion)?; let version = version.0 as u8; if version > MAX_SUPPORTED_FORWARDING_VERSION { @@ -124,7 +124,7 @@ pub fn receive_velocity_plugin_response( )); } let addr = buf - .get_string() + .try_get_string() .map_err(|_| VelocityError::FailedReadAddress)?; let socket_addr: SocketAddr = SocketAddr::new( diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 0f9b5bb92..35d7383e9 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -575,10 +575,9 @@ impl World { let packet = CChunkData(&chunk_data); #[cfg(debug_assertions)] if chunk_data.position == (0, 0).into() { - use pumpkin_protocol::bytebuf::ByteBuffer; - let mut test = ByteBuffer::empty(); + let mut test = bytes::BytesMut::new(); packet.write(&mut test); - let len = test.buf().len(); + let len = test.len(); log::debug!( "Chunk packet size: {}B {}KB {}MB", len,