From 284db803f9e75363b1b254bff44a3bd40ca8eab9 Mon Sep 17 00:00:00 2001 From: lukas0008 Date: Mon, 5 Aug 2024 00:55:19 +0200 Subject: [PATCH] Serde serialize for automatic packet serialization --- Cargo.lock | 7 + pumpkin-protocol/Cargo.toml | 3 +- pumpkin-protocol/src/bytebuf/mod.rs | 8 +- pumpkin-protocol/src/bytebuf/packet_id.rs | 46 +++ pumpkin-protocol/src/bytebuf/serializer.rs | 359 +++++++++++++++++++++ pumpkin-protocol/src/client/config/mod.rs | 39 ++- pumpkin-protocol/src/client/login/mod.rs | 21 +- pumpkin-protocol/src/client/play/mod.rs | 42 ++- pumpkin-protocol/src/client/status/mod.rs | 23 +- pumpkin-protocol/src/lib.rs | 6 +- pumpkin-protocol/src/packet_encoder.rs | 5 +- 11 files changed, 508 insertions(+), 51 deletions(-) create mode 100644 pumpkin-protocol/src/bytebuf/packet_id.rs create mode 100644 pumpkin-protocol/src/bytebuf/serializer.rs diff --git a/Cargo.lock b/Cargo.lock index ccade3a28..d26d0fde0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1178,6 +1178,7 @@ dependencies = [ "log", "serde", "serde_json", + "take_mut", "thiserror", "uuid", ] @@ -1644,6 +1645,12 @@ dependencies = [ "libc", ] +[[package]] +name = "take_mut" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" + [[package]] name = "tar" version = "0.4.41" diff --git a/pumpkin-protocol/Cargo.toml b/pumpkin-protocol/Cargo.toml index eccbbff46..34a650b63 100644 --- a/pumpkin-protocol/Cargo.toml +++ b/pumpkin-protocol/Cargo.toml @@ -20,4 +20,5 @@ fastnbt = { git = "https://github.com/owengage/fastnbt.git" } # encryption aes = "0.8.4" -cfb8 = "0.8.1" \ No newline at end of file +cfb8 = "0.8.1" +take_mut = "0.2.2" diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index e4a65a1a4..b242aa3fd 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -1,13 +1,15 @@ use core::str; use std::io::{self, Error, ErrorKind}; - use bytes::{Buf, BufMut, BytesMut}; - use crate::{BitSet, VarInt, VarLong}; +mod serializer; +pub mod packet_id; + const SEGMENT_BITS: u8 = 0x7F; const CONTINUE_BIT: u8 = 0x80; +#[derive(Debug)] pub struct ByteBuffer { buffer: BytesMut, } @@ -130,7 +132,7 @@ impl ByteBuffer { } pub fn put_var_int(&mut self, value: VarInt) { - let mut val = value as u32; + let mut val = value; for _ in 0..5 { let mut b: u8 = val as u8 & 0b01111111; val >>= 7; diff --git a/pumpkin-protocol/src/bytebuf/packet_id.rs b/pumpkin-protocol/src/bytebuf/packet_id.rs new file mode 100644 index 000000000..f684b97b5 --- /dev/null +++ b/pumpkin-protocol/src/bytebuf/packet_id.rs @@ -0,0 +1,46 @@ +use serde::{Serialize, Serializer}; + +use crate::{ClientPacket, VarInt, VarInt32}; + +use super::{serializer, ByteBuffer}; + +impl Serialize for VarInt32 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut val = self.0; + let mut buf: Vec = Vec::new(); + for _ in 0..5 { + let mut b: u8 = val as u8 & 0b01111111; + val >>= 7; + if val != 0 { + b |= 0b10000000; + } + buf.push(b); + if val == 0 { + break; + } + } + serializer.serialize_bytes(&buf) + } +} + +pub trait Packet { + const PACKET_ID: VarInt; +} + +impl

ClientPacket for P +where + P: Packet + Serialize, +{ + fn write(&self, bytebuf: &mut ByteBuffer) { + dbg!(P::PACKET_ID); + take_mut::take(bytebuf, |bytebuf| { + let mut serializer = serializer::Serializer::new(bytebuf); + self.serialize(&mut serializer) + .expect("Could not serialize packet"); + serializer.into() + }); + } +} diff --git a/pumpkin-protocol/src/bytebuf/serializer.rs b/pumpkin-protocol/src/bytebuf/serializer.rs new file mode 100644 index 000000000..9f8b3047f --- /dev/null +++ b/pumpkin-protocol/src/bytebuf/serializer.rs @@ -0,0 +1,359 @@ +use std::fmt::Display; + +use serde::{ser, Serialize}; +use thiserror::Error; + +use super::ByteBuffer; + +pub struct Serializer { + output: ByteBuffer, +} + +impl Serializer { + pub fn new(buf: ByteBuffer) -> Self { + Self { output: buf } + } +} + +impl Into for Serializer { + fn into(self) -> ByteBuffer { + self.output + } +} + +impl AsRef for Serializer { + fn as_ref(&self) -> &ByteBuffer { + &self.output + } +} + +impl AsMut for Serializer { + fn as_mut(&mut self) -> &mut ByteBuffer { + &mut self.output + } +} + +#[derive(Debug, Error)] +pub enum SerializerError { + #[error("serializer error {0}")] + Message(String), +} + +impl ser::Error for SerializerError { + fn custom(msg: T) -> Self { + Self::Message(msg.to_string()) + } +} + +impl<'a> ser::Serializer for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = Self; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, v: bool) -> Result { + self.output.put_bool(v); + Ok(()) + } + fn serialize_bytes(self, v: &[u8]) -> Result { + self.output.put_slice(v); + Ok(()) + } + fn serialize_char(self, v: char) -> Result { + todo!() + } + fn serialize_f32(self, v: f32) -> Result { + todo!() + } + fn serialize_f64(self, v: f64) -> Result { + todo!() + } + fn serialize_i128(self, v: i128) -> Result { + todo!() + } + fn serialize_i16(self, v: i16) -> Result { + todo!() + } + fn serialize_i32(self, v: i32) -> Result { + todo!() + } + fn serialize_i64(self, v: i64) -> Result { + self.output.put_i64(v); + Ok(()) + } + fn serialize_i8(self, v: i8) -> Result { + todo!() + } + fn serialize_map(self, len: Option) -> Result { + todo!() + } + fn serialize_newtype_struct( + self, + name: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + todo!() + } + fn serialize_newtype_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + todo!() + } + fn serialize_none(self) -> Result { + todo!() + } + fn serialize_seq(self, len: Option) -> Result { + todo!() + } + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + todo!() + } + fn serialize_str(self, v: &str) -> Result { + self.output.put_string(v); + Ok(()) + } + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + Ok(self) + } + fn serialize_struct_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + todo!() + } + fn serialize_tuple(self, len: usize) -> Result { + todo!() + } + fn serialize_tuple_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + todo!() + } + fn serialize_tuple_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + todo!() + } + fn serialize_u128(self, v: u128) -> Result { + todo!() + } + fn serialize_u16(self, v: u16) -> Result { + todo!() + } + fn serialize_u32(self, v: u32) -> Result { + todo!() + } + fn serialize_u64(self, v: u64) -> Result { + todo!() + } + fn serialize_u8(self, v: u8) -> Result { + todo!() + } + fn serialize_unit(self) -> Result { + todo!() + } + fn serialize_unit_struct(self, name: &'static str) -> Result { + todo!() + } + fn serialize_unit_variant( + self, + name: &'static str, + variant_index: u32, + variant: &'static str, + ) -> Result { + todo!() + } +} + +impl<'a> ser::SerializeSeq for &'a mut Serializer { + // Must match the `Ok` type of the serializer. + type Ok = (); + // Must match the `Error` type of the serializer. + type Error = SerializerError; + + // Serialize a single element of the sequence. + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + // Close the sequence. + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} + +impl<'a> ser::SerializeTuple for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} + +// Same thing but for tuple structs. +impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} + +// Tuple variants are a little different. Refer back to the +// `serialize_tuple_variant` method above: +// +// self.output += "{"; +// variant.serialize(&mut *self)?; +// self.output += ":["; +// +// So the `end` method in this impl is responsible for closing both the `]` and +// the `}`. +impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} + +// Some `Serialize` types are not able to hold a key and value in memory at the +// same time so `SerializeMap` implementations are required to support +// `serialize_key` and `serialize_value` individually. +// +// There is a third optional method on the `SerializeMap` trait. The +// `serialize_entry` method allows serializers to optimize for the case where +// key and value are both available simultaneously. In JSON it doesn't make a +// difference so the default behavior for `serialize_entry` is fine. +impl<'a> ser::SerializeMap for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + // The Serde data model allows map keys to be any serializable type. JSON + // only allows string keys so the implementation below will produce invalid + // JSON if the key serializes as something other than a string. + // + // A real JSON serializer would need to validate that map keys are strings. + // This can be done by using a different Serializer to serialize the key + // (instead of `&mut **self`) and having that other serializer only + // implement `serialize_str` and return an error on any other data type. + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + // It doesn't make a difference whether the colon is printed at the end of + // `serialize_key` or at the beginning of `serialize_value`. In this case + // the code is a bit simpler having it here. + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} + +// Structs are like maps in which the keys are constrained to be compile-time +// constant strings. +impl<'a> ser::SerializeStruct for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + value.serialize(&mut **self) + } + + fn end(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { + let _ = key; + Ok(()) + } +} + +// Similar to `SerializeTupleVariant`, here the `end` method is responsible for +// closing both of the curly braces opened by `serialize_struct_variant`. +impl<'a> ser::SerializeStructVariant for &'a mut Serializer { + type Ok = (); + type Error = SerializerError; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> + where + T: ?Sized + Serialize, + { + todo!() + } + + fn end(self) -> Result<(), Self::Error> { + todo!() + } +} diff --git a/pumpkin-protocol/src/client/config/mod.rs b/pumpkin-protocol/src/client/config/mod.rs index 112b7e87b..f4ebb26f4 100644 --- a/pumpkin-protocol/src/client/config/mod.rs +++ b/pumpkin-protocol/src/client/config/mod.rs @@ -1,12 +1,17 @@ -use crate::{bytebuf::ByteBuffer, ClientPacket, Identifier, KnownPack, VarInt}; +use crate::{ + bytebuf::{packet_id::Packet, ByteBuffer}, + ClientPacket, Identifier, KnownPack, VarInt, +}; pub struct CCookieRequest { key: Identifier, } -impl ClientPacket for CCookieRequest { +impl Packet for CCookieRequest { const PACKET_ID: VarInt = 0x00; +} +impl ClientPacket for CCookieRequest { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(&self.key); } @@ -23,33 +28,33 @@ impl<'a> CPluginMessage<'a> { } } -impl<'a> ClientPacket for CPluginMessage<'a> { +impl<'a> Packet for CPluginMessage<'a> { const PACKET_ID: VarInt = 0x01; +} +impl<'a> ClientPacket for CPluginMessage<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.channel); bytebuf.put_slice(self.data); } } +#[derive(serde::Serialize)] pub struct CConfigDisconnect<'a> { reason: &'a str, } +impl<'a> Packet for CConfigDisconnect<'a> { + const PACKET_ID: i32 = 0x02; +} + impl<'a> CConfigDisconnect<'a> { pub fn new(reason: &'a str) -> Self { Self { reason } } } -impl<'a> ClientPacket for CConfigDisconnect<'a> { - const PACKET_ID: VarInt = 0x02; - - fn write(&self, bytebuf: &mut ByteBuffer) { - bytebuf.put_string(self.reason); - } -} - +#[derive(serde::Serialize)] pub struct CFinishConfig {} impl Default for CFinishConfig { @@ -64,10 +69,8 @@ impl CFinishConfig { } } -impl ClientPacket for CFinishConfig { +impl Packet for CFinishConfig { const PACKET_ID: VarInt = 0x03; - - fn write(&self, _bytebuf: &mut ByteBuffer) {} } pub struct CKnownPacks<'a> { @@ -80,9 +83,11 @@ impl<'a> CKnownPacks<'a> { } } -impl<'a> ClientPacket for CKnownPacks<'a> { +impl<'a> Packet for CKnownPacks<'a> { const PACKET_ID: VarInt = 0x0E; +} +impl<'a> ClientPacket for CKnownPacks<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_list::(self.known_packs, |p, v| { p.put_string(v.namespace); @@ -111,9 +116,11 @@ pub struct RegistryEntry<'a> { pub data: Vec, } -impl<'a> ClientPacket for CRegistryData<'a> { +impl<'a> Packet for CRegistryData<'a> { const PACKET_ID: VarInt = 0x07; +} +impl<'a> ClientPacket for CRegistryData<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.registry_id); bytebuf.put_list::(self.entries, |p, v| { diff --git a/pumpkin-protocol/src/client/login/mod.rs b/pumpkin-protocol/src/client/login/mod.rs index 7e7342ba6..e4e4ca4a6 100644 --- a/pumpkin-protocol/src/client/login/mod.rs +++ b/pumpkin-protocol/src/client/login/mod.rs @@ -1,4 +1,7 @@ -use crate::{bytebuf::ByteBuffer, ClientPacket, Property, VarInt}; +use crate::{ + bytebuf::{packet_id::Packet, ByteBuffer}, + ClientPacket, Property, VarInt, +}; pub struct CLoginDisconnect<'a> { reason: &'a str, @@ -10,9 +13,11 @@ impl<'a> CLoginDisconnect<'a> { } } -impl<'a> ClientPacket for CLoginDisconnect<'a> { +impl<'a> Packet for CLoginDisconnect<'a> { const PACKET_ID: VarInt = 0x00; +} +impl<'a> ClientPacket for CLoginDisconnect<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(&serde_json::to_string_pretty(&self.reason).unwrap()); } @@ -41,9 +46,11 @@ impl<'a> CEncryptionRequest<'a> { } } -impl<'a> ClientPacket for CEncryptionRequest<'a> { +impl<'a> Packet for CEncryptionRequest<'a> { const PACKET_ID: VarInt = 0x01; +} +impl<'a> ClientPacket for CEncryptionRequest<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.server_id); bytebuf.put_var_int(self.public_key.len() as VarInt); @@ -81,9 +88,11 @@ impl<'a> CLoginSuccess<'a> { } } -impl<'a> ClientPacket for CLoginSuccess<'a> { +impl<'a> Packet for CLoginSuccess<'a> { const PACKET_ID: VarInt = 0x02; +} +impl<'a> ClientPacket for CLoginSuccess<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_uuid(self.uuid); bytebuf.put_string(&self.username); @@ -105,9 +114,11 @@ impl CSetCompression { } } -impl ClientPacket for CSetCompression { +impl Packet for CSetCompression { const PACKET_ID: VarInt = 0x03; +} +impl ClientPacket for CSetCompression { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_var_int(self.threshold); } diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index a2ffb5760..ce79e81dd 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -1,4 +1,8 @@ -use crate::{bytebuf::ByteBuffer, text::TextComponent, BitSet, ClientPacket, Property, VarInt}; +use crate::{ + bytebuf::{packet_id::Packet, ByteBuffer}, + text::Text, + BitSet, ClientPacket, Property, VarInt, +}; pub struct SetHeldItem { slot: i8, @@ -10,9 +14,11 @@ impl SetHeldItem { } } -impl ClientPacket for SetHeldItem { +impl Packet for SetHeldItem { const PACKET_ID: VarInt = 0x53; +} +impl ClientPacket for SetHeldItem { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_i8(self.slot); } @@ -48,9 +54,11 @@ impl<'a> CPlayerInfoUpdate<'a> { } } -impl<'a> ClientPacket for CPlayerInfoUpdate<'a> { +impl<'a> Packet for CPlayerInfoUpdate<'a> { const PACKET_ID: VarInt = 0x3E; +} +impl<'a> ClientPacket for CPlayerInfoUpdate<'a> { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_i8(self.actions); bytebuf.put_list::(self.players, |p, v| { @@ -95,9 +103,11 @@ impl CPlayerAbilities { } } -impl ClientPacket for CPlayerAbilities { +impl Packet for CPlayerAbilities { const PACKET_ID: VarInt = 0x38; +} +impl ClientPacket for CPlayerAbilities { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_i8(self.flags); bytebuf.put_f32(self.flying_speed); @@ -115,9 +125,11 @@ impl CPlayDisconnect { } } -impl ClientPacket for CPlayDisconnect { +impl Packet for CPlayDisconnect { const PACKET_ID: VarInt = 0x1D; +} +impl ClientPacket for CPlayDisconnect { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_slice(&self.reason.encode()); } @@ -154,9 +166,11 @@ impl CChangeDifficulty { } } -impl ClientPacket for CChangeDifficulty { +impl Packet for CChangeDifficulty { const PACKET_ID: VarInt = 0x0B; +} +impl ClientPacket for CChangeDifficulty { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_u8(self.difficulty); bytebuf.put_bool(self.locked); @@ -237,9 +251,11 @@ impl CLogin { } } -impl ClientPacket for CLogin { +impl Packet for CLogin { const PACKET_ID: VarInt = 0x2B; +} +impl ClientPacket for CLogin { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_i32(self.entity_id); bytebuf.put_bool(self.is_hardcore); @@ -278,9 +294,11 @@ impl CGameEvent { } } -impl ClientPacket for CGameEvent { +impl Packet for CGameEvent { const PACKET_ID: VarInt = 0x22; +} +impl ClientPacket for CGameEvent { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_u8(self.event); bytebuf.put_f32(self.value); @@ -319,9 +337,11 @@ impl CSyncPlayerPostion { } } -impl ClientPacket for CSyncPlayerPostion { +impl Packet for CSyncPlayerPostion { const PACKET_ID: VarInt = 0x40; +} +impl ClientPacket for CSyncPlayerPostion { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_f64(self.x); bytebuf.put_f64(self.y); @@ -375,9 +395,11 @@ impl CChunkDataUpdateLight { } } -impl ClientPacket for CChunkDataUpdateLight { +impl Packet for CChunkDataUpdateLight { const PACKET_ID: VarInt = 0x27; +} +impl ClientPacket for CChunkDataUpdateLight { fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_i32(self.chunk_x); bytebuf.put_i32(self.chunk_y); diff --git a/pumpkin-protocol/src/client/status/mod.rs b/pumpkin-protocol/src/client/status/mod.rs index d358e4967..70515f13b 100644 --- a/pumpkin-protocol/src/client/status/mod.rs +++ b/pumpkin-protocol/src/client/status/mod.rs @@ -1,23 +1,23 @@ -use crate::{bytebuf::ByteBuffer, ClientPacket, VarInt}; +use crate::{ + bytebuf::{packet_id::Packet, ByteBuffer}, + ClientPacket, VarInt, +}; +#[derive(serde::Serialize)] pub struct CPingResponse { payload: i64, // must responde with the same as in `SPingRequest` } +impl Packet for CPingResponse { + const PACKET_ID: VarInt = 0x01; +} + impl CPingResponse { pub fn new(payload: i64) -> Self { Self { payload } } } -impl ClientPacket for CPingResponse { - const PACKET_ID: VarInt = 0x01; - - fn write(&self, bytebuf: &mut ByteBuffer) { - bytebuf.put_i64(self.payload); - } -} - pub struct CStatusResponse<'a> { json_response: &'a str, // 32767 } @@ -27,10 +27,11 @@ impl<'a> CStatusResponse<'a> { Self { json_response } } } +impl<'a> Packet for CStatusResponse<'a> { + const PACKET_ID: VarInt = 0x00; +} impl<'a> ClientPacket for CStatusResponse<'a> { - const PACKET_ID: VarInt = 0x00; - fn write(&self, bytebuf: &mut ByteBuffer) { bytebuf.put_string(self.json_response); } diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 32b973cd3..6c5ac8191 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -1,6 +1,6 @@ use std::io::{self, Write}; -use bytebuf::ByteBuffer; +use bytebuf::{packet_id::Packet, ByteBuffer}; use bytes::Buf; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -146,9 +146,7 @@ pub struct RawPacket { pub bytebuf: ByteBuffer, } -pub trait ClientPacket { - const PACKET_ID: VarInt; - +pub trait ClientPacket: Packet { fn write(&self, bytebuf: &mut ByteBuffer); } diff --git a/pumpkin-protocol/src/packet_encoder.rs b/pumpkin-protocol/src/packet_encoder.rs index bd0831c0f..3ced218c5 100644 --- a/pumpkin-protocol/src/packet_encoder.rs +++ b/pumpkin-protocol/src/packet_encoder.rs @@ -3,7 +3,10 @@ use std::io::Write; use aes::cipher::{generic_array::GenericArray, BlockEncryptMut, BlockSizeUser, KeyIvInit}; use bytes::{BufMut, BytesMut}; -use crate::{bytebuf::ByteBuffer, ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE}; +use crate::{ + bytebuf::{packet_id::Packet, ByteBuffer}, + ClientPacket, PacketError, VarInt32, MAX_PACKET_SIZE, +}; type Cipher = cfb8::Encryptor;