diff --git a/pumpkin-protocol/src/bytebuf/deserializer.rs b/pumpkin-protocol/src/bytebuf/deserializer.rs new file mode 100644 index 000000000..c2d96839f --- /dev/null +++ b/pumpkin-protocol/src/bytebuf/deserializer.rs @@ -0,0 +1,321 @@ +use std::fmt::Display; + +use serde::de::{self, DeserializeSeed, SeqAccess}; +use thiserror::Error; + +use super::ByteBuffer; + +pub struct Deserializer<'a> { + inner: &'a mut ByteBuffer, +} + +#[derive(Debug, Error)] +pub enum DeserializerError { + #[error("serializer error {0}")] + Message(String), + #[error("Stdio error")] + Stdio(std::io::Error), +} + +impl de::Error for DeserializerError { + fn custom(msg: T) -> Self { + Self::Message(msg.to_string()) + } +} + +impl<'a> Deserializer<'a> { + pub fn new(buf: &'a mut ByteBuffer) -> Self { + Self { inner: buf } + } +} + +impl<'a, 'de> de::Deserializer<'de> for Deserializer<'a> { + type Error = DeserializerError; + + fn deserialize_any(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!( + "This is impossible to do, since you cannot infer the data structure from the packet" + ) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_bool(self.inner.get_bool()) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_i8(self.inner.get_i8()) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_i16(self.inner.get_i16()) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_i32(self.inner.get_i32()) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_i64(self.inner.get_i64()) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_u8(self.inner.get_u8()) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_u16(self.inner.get_u16()) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_u32(self.inner.get_u32()) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_u64(self.inner.get_u64()) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_f32(self.inner.get_f32()) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_f64(self.inner.get_f64()) + } + + fn deserialize_char(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let string = self.inner.get_string().map_err(DeserializerError::Stdio)?; + visitor.visit_str(&string) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let string = self.inner.get_string().map_err(DeserializerError::Stdio)?; + visitor.visit_str(&string) + } + + fn deserialize_bytes(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_byte_buf(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_option(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_unit(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_newtype_struct( + self, + _name: &'static str, + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + struct Access<'a, 'b> { + deserializer: &'a mut Deserializer<'b>, + } + + impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> { + type Error = DeserializerError; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + let value = DeserializeSeed::deserialize( + seed, + Deserializer { + inner: self.deserializer.inner, + }, + )?; + Ok(Some(value)) + } + } + + let value = visitor.visit_seq(Access { + deserializer: &mut self, + }); + + value + } + + fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + struct Access<'a, 'b> { + deserializer: &'a mut Deserializer<'b>, + len: usize, + } + + impl<'de, 'a, 'b: 'a> SeqAccess<'de> for Access<'a, 'b> { + type Error = DeserializerError; + + fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let value = DeserializeSeed::deserialize( + seed, + Deserializer { + inner: self.deserializer.inner, + }, + )?; + Ok(Some(value)) + } else { + Ok(None) + } + } + } + + let value = visitor.visit_seq(Access { + deserializer: &mut self, + len, + }); + + value + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_map(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_struct( + self, + _name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_identifier(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_ignored_any(self, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + unimplemented!() + } +} diff --git a/pumpkin-protocol/src/bytebuf/mod.rs b/pumpkin-protocol/src/bytebuf/mod.rs index 8f4a5fdb0..17268c3fc 100644 --- a/pumpkin-protocol/src/bytebuf/mod.rs +++ b/pumpkin-protocol/src/bytebuf/mod.rs @@ -3,6 +3,8 @@ use bytes::{Buf, BufMut, BytesMut}; use core::str; use std::io::{self, Error, ErrorKind}; +mod deserializer; +pub use deserializer::DeserializerError; pub mod packet_id; mod serializer; @@ -312,3 +314,47 @@ impl ByteBuffer { self.buffer.split() } } + +#[cfg(test)] +mod test { + use serde::{Deserialize, Serialize}; + + use crate::{ + bytebuf::{deserializer, serializer, ByteBuffer}, + VarInt, + }; + + #[test] + fn test_i32_reserialize() { + #[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)] + struct Foo { + bar: i32, + } + let foo = Foo { bar: 69 }; + let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); + foo.serialize(&mut serializer).unwrap(); + + let mut serialized: ByteBuffer = serializer.into(); + let deserialized: Foo = + Foo::deserialize(deserializer::Deserializer::new(&mut serialized)).unwrap(); + + assert_eq!(foo, deserialized); + } + + #[test] + fn test_varint_reserialize() { + #[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq, Debug)] + struct Foo { + bar: VarInt, + } + let foo = Foo { bar: 69.into() }; + let mut serializer = serializer::Serializer::new(ByteBuffer::empty()); + foo.serialize(&mut serializer).unwrap(); + + let mut serialized: ByteBuffer = serializer.into(); + let deserialized: Foo = + Foo::deserialize(deserializer::Deserializer::new(&mut 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 e335eed9b..fe2989514 100644 --- a/pumpkin-protocol/src/bytebuf/packet_id.rs +++ b/pumpkin-protocol/src/bytebuf/packet_id.rs @@ -1,8 +1,11 @@ -use serde::{Serialize, Serializer}; +use serde::{ + de::{self, DeserializeOwned, SeqAccess, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +}; -use crate::{ClientPacket, VarInt, VarIntType}; +use crate::{ClientPacket, ServerPacket, VarInt, VarIntType}; -use super::{serializer, ByteBuffer}; +use super::{deserializer, serializer, ByteBuffer, DeserializerError}; impl Serialize for VarInt { fn serialize(&self, serializer: S) -> Result @@ -26,6 +29,43 @@ impl Serialize for VarInt { } } +impl<'de> Deserialize<'de> for VarInt { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct VarIntVisitor; + + impl<'de> Visitor<'de> for VarIntVisitor { + type Value = VarInt; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a valid VarInt encoded in a byte sequence") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut val = 0; + for i in 0..VarInt::MAX_SIZE { + if let Some(byte) = seq.next_element::()? { + val |= (i32::from(byte) & 0b01111111) << (i * 7); + if byte & 0b10000000 == 0 { + return Ok(VarInt(val)); + } + } else { + break; + } + } + Err(de::Error::custom("VarInt was too large")) + } + } + + deserializer.deserialize_seq(VarIntVisitor) + } +} + pub trait Packet { const PACKET_ID: VarIntType; } @@ -43,3 +83,13 @@ where }); } } + +impl

ServerPacket for P +where + P: Packet + DeserializeOwned, +{ + fn read(bytebuf: &mut ByteBuffer) -> Result { + let deserializer = deserializer::Deserializer::new(bytebuf); + P::deserialize(deserializer) + } +} diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 733c1c23c..fe2eec998 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -1,6 +1,6 @@ use std::io::{self, Write}; -use bytebuf::{packet_id::Packet, ByteBuffer}; +use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError}; use bytes::Buf; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -24,7 +24,7 @@ pub type VarLongType = i64; pub struct BitSet(pub VarInt, pub Vec); -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct VarInt(pub VarIntType); impl VarInt { @@ -181,10 +181,8 @@ pub trait ClientPacket: Packet { fn write(&self, bytebuf: &mut ByteBuffer); } -pub trait ServerPacket { - const PACKET_ID: VarInt; - - fn read(bytebuf: &mut ByteBuffer) -> Self; +pub trait ServerPacket: Packet + Sized { + fn read(bytebuf: &mut ByteBuffer) -> Result; } #[derive(Serialize)] diff --git a/pumpkin-protocol/src/server/config/mod.rs b/pumpkin-protocol/src/server/config/mod.rs index 59806c86a..164c8e60a 100644 --- a/pumpkin-protocol/src/server/config/mod.rs +++ b/pumpkin-protocol/src/server/config/mod.rs @@ -1,70 +1,9 @@ -use crate::{bytebuf::ByteBuffer, Identifier, ServerPacket, VarInt}; - -pub struct SClientInformation { - pub locale: String, // 16 - pub view_distance: i8, - pub chat_mode: VarInt, // Varint - pub chat_colors: bool, - pub skin_parts: u8, - pub main_hand: VarInt, - pub text_filtering: bool, - pub server_listing: bool, -} - -impl ServerPacket for SClientInformation { - const PACKET_ID: VarInt = VarInt(0x00); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - locale: bytebuf.get_string_len(16).unwrap(), - view_distance: bytebuf.get_i8(), - chat_mode: bytebuf.get_var_int(), - chat_colors: bytebuf.get_bool(), - skin_parts: bytebuf.get_u8(), - main_hand: bytebuf.get_var_int(), - text_filtering: bytebuf.get_bool(), - server_listing: bytebuf.get_bool(), - } - } -} - -pub struct SPluginMessage { - pub channel: Identifier, - pub data: Vec, -} - -impl ServerPacket for SPluginMessage { - const PACKET_ID: VarInt = VarInt(0x02); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - channel: bytebuf.get_string().unwrap(), - data: bytebuf.get_slice().to_vec(), - } - } -} - -pub struct SAcknowledgeFinishConfig {} - -impl ServerPacket for SAcknowledgeFinishConfig { - const PACKET_ID: VarInt = VarInt(0x03); - - fn read(_bytebuf: &mut ByteBuffer) -> Self { - Self {} - } -} - -pub struct SKnownPacks { - pub known_pack_count: VarInt, - // known_packs: &'a [KnownPack] -} - -impl ServerPacket for SKnownPacks { - const PACKET_ID: VarInt = VarInt(0x07); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - known_pack_count: bytebuf.get_var_int(), - } - } -} +mod s_acknowledge_finish_config; +mod s_client_information; +mod s_known_packs; +mod s_plugin_message; + +pub use s_acknowledge_finish_config::*; +pub use s_client_information::*; +pub use s_known_packs::*; +pub use s_plugin_message::*; diff --git a/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs b/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs new file mode 100644 index 000000000..c540a25c4 --- /dev/null +++ b/pumpkin-protocol/src/server/config/s_acknowledge_finish_config.rs @@ -0,0 +1,5 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x03)] +pub struct SAcknowledgeFinishConfig {} diff --git a/pumpkin-protocol/src/server/config/s_client_information.rs b/pumpkin-protocol/src/server/config/s_client_information.rs new file mode 100644 index 000000000..b5d2cdf73 --- /dev/null +++ b/pumpkin-protocol/src/server/config/s_client_information.rs @@ -0,0 +1,16 @@ +use pumpkin_macros::packet; + +use crate::VarInt; + +#[derive(serde::Deserialize)] +#[packet(0x00)] +pub struct SClientInformation { + pub locale: String, // 16 + pub view_distance: i8, + pub chat_mode: VarInt, // Varint + pub chat_colors: bool, + pub skin_parts: u8, + pub main_hand: VarInt, + pub text_filtering: bool, + pub server_listing: bool, +} diff --git a/pumpkin-protocol/src/server/config/s_known_packs.rs b/pumpkin-protocol/src/server/config/s_known_packs.rs new file mode 100644 index 000000000..48670f0b5 --- /dev/null +++ b/pumpkin-protocol/src/server/config/s_known_packs.rs @@ -0,0 +1,10 @@ +use pumpkin_macros::packet; + +use crate::VarInt; + +#[derive(serde::Deserialize)] +#[packet(0x07)] +pub struct SKnownPacks { + pub known_pack_count: VarInt, + // known_packs: &'a [KnownPack] +} diff --git a/pumpkin-protocol/src/server/config/s_plugin_message.rs b/pumpkin-protocol/src/server/config/s_plugin_message.rs new file mode 100644 index 000000000..19e06c853 --- /dev/null +++ b/pumpkin-protocol/src/server/config/s_plugin_message.rs @@ -0,0 +1,21 @@ +use pumpkin_macros::packet; + +use crate::{ + bytebuf::{ByteBuffer, DeserializerError}, + Identifier, ServerPacket, +}; + +#[packet(0x02)] +pub struct SPluginMessage { + pub channel: Identifier, + pub data: Vec, +} + +impl ServerPacket for SPluginMessage { + fn read(bytebuf: &mut ByteBuffer) -> Result { + Ok(Self { + channel: bytebuf.get_string().unwrap(), + data: bytebuf.get_slice().to_vec(), + }) + } +} diff --git a/pumpkin-protocol/src/server/handshake/mod.rs b/pumpkin-protocol/src/server/handshake/mod.rs index 9894ac9fd..100e67fd0 100644 --- a/pumpkin-protocol/src/server/handshake/mod.rs +++ b/pumpkin-protocol/src/server/handshake/mod.rs @@ -1,5 +1,11 @@ -use crate::{bytebuf::ByteBuffer, ConnectionState, ServerPacket, VarInt}; +use pumpkin_macros::packet; +use crate::{ + bytebuf::{ByteBuffer, DeserializerError}, + ConnectionState, ServerPacket, VarInt, +}; + +#[packet(0x00)] pub struct SHandShake { pub protocol_version: VarInt, pub server_address: String, // 255 @@ -8,14 +14,12 @@ pub struct SHandShake { } impl ServerPacket for SHandShake { - const PACKET_ID: VarInt = VarInt(0x00); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { + fn read(bytebuf: &mut ByteBuffer) -> Result { + Ok(Self { protocol_version: bytebuf.get_var_int(), server_address: bytebuf.get_string_len(255).unwrap(), server_port: bytebuf.get_u16(), next_state: bytebuf.get_var_int().into(), - } + }) } } diff --git a/pumpkin-protocol/src/server/login/mod.rs b/pumpkin-protocol/src/server/login/mod.rs index 36862cedf..872f74bbc 100644 --- a/pumpkin-protocol/src/server/login/mod.rs +++ b/pumpkin-protocol/src/server/login/mod.rs @@ -1,72 +1,9 @@ -use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt}; - -pub struct SLoginStart { - pub name: String, // 16 - pub uuid: uuid::Uuid, -} - -impl ServerPacket for SLoginStart { - const PACKET_ID: VarInt = VarInt(0x00); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - name: bytebuf.get_string_len(16).unwrap(), - uuid: bytebuf.get_uuid(), - } - } -} - -pub struct SEncryptionResponse { - pub shared_secret_length: VarInt, - pub shared_secret: Vec, - pub verify_token_length: VarInt, - pub verify_token: Vec, -} - -impl ServerPacket for SEncryptionResponse { - const PACKET_ID: VarInt = VarInt(0x01); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - 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); - Self { - shared_secret_length, - shared_secret: shared_secret.to_vec(), - verify_token_length, - verify_token: verify_token.to_vec(), - } - } -} - -pub struct SLoginPluginResponse<'a> { - pub message_id: VarInt, - pub successful: bool, - pub data: Option<&'a [u8]>, -} - -impl<'a> ServerPacket for SLoginPluginResponse<'a> { - const PACKET_ID: VarInt = VarInt(0x02); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - message_id: bytebuf.get_var_int(), - successful: bytebuf.get_bool(), - data: None, // TODO - } - } -} - -// Acknowledgement to the Login Success packet sent to the server. -pub struct SLoginAcknowledged { - // empty -} - -impl ServerPacket for SLoginAcknowledged { - const PACKET_ID: VarInt = VarInt(0x03); - - fn read(_bytebuf: &mut ByteBuffer) -> Self { - Self {} - } -} +mod s_encryption_response; +mod s_login_response; +mod s_login_start; +mod s_plugin_response; + +pub use s_encryption_response::*; +pub use s_login_response::*; +pub use s_login_start::*; +pub use s_plugin_response::*; diff --git a/pumpkin-protocol/src/server/login/s_encryption_response.rs b/pumpkin-protocol/src/server/login/s_encryption_response.rs new file mode 100644 index 000000000..980e54b20 --- /dev/null +++ b/pumpkin-protocol/src/server/login/s_encryption_response.rs @@ -0,0 +1,29 @@ +use pumpkin_macros::packet; + +use crate::{ + bytebuf::{ByteBuffer, DeserializerError}, + ServerPacket, VarInt, +}; + +#[packet(0x01)] +pub struct SEncryptionResponse { + pub shared_secret_length: VarInt, + pub shared_secret: Vec, + pub verify_token_length: VarInt, + pub verify_token: Vec, +} + +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); + Ok(Self { + shared_secret_length, + shared_secret: shared_secret.to_vec(), + verify_token_length, + verify_token: verify_token.to_vec(), + }) + } +} diff --git a/pumpkin-protocol/src/server/login/s_login_response.rs b/pumpkin-protocol/src/server/login/s_login_response.rs new file mode 100644 index 000000000..d1f302327 --- /dev/null +++ b/pumpkin-protocol/src/server/login/s_login_response.rs @@ -0,0 +1,6 @@ +use pumpkin_macros::packet; + +// Acknowledgement to the Login Success packet sent to the server. +#[derive(serde::Deserialize)] +#[packet(0x03)] +pub struct SLoginAcknowledged {} diff --git a/pumpkin-protocol/src/server/login/s_login_start.rs b/pumpkin-protocol/src/server/login/s_login_start.rs new file mode 100644 index 000000000..96bbbac70 --- /dev/null +++ b/pumpkin-protocol/src/server/login/s_login_start.rs @@ -0,0 +1,21 @@ +use pumpkin_macros::packet; + +use crate::{ + bytebuf::{ByteBuffer, DeserializerError}, + ServerPacket, +}; + +#[packet(0x00)] +pub struct SLoginStart { + pub name: String, // 16 + pub uuid: uuid::Uuid, +} + +impl ServerPacket for SLoginStart { + fn read(bytebuf: &mut ByteBuffer) -> Result { + Ok(Self { + name: bytebuf.get_string_len(16).unwrap(), + uuid: bytebuf.get_uuid(), + }) + } +} diff --git a/pumpkin-protocol/src/server/login/s_plugin_response.rs b/pumpkin-protocol/src/server/login/s_plugin_response.rs new file mode 100644 index 000000000..3b8ccf3d1 --- /dev/null +++ b/pumpkin-protocol/src/server/login/s_plugin_response.rs @@ -0,0 +1,23 @@ +use pumpkin_macros::packet; + +use crate::{ + bytebuf::{ByteBuffer, DeserializerError}, + ServerPacket, VarInt, +}; + +#[packet(0x02)] +pub struct SLoginPluginResponse<'a> { + pub message_id: VarInt, + pub successful: bool, + pub data: Option<&'a [u8]>, +} + +impl<'a> ServerPacket for SLoginPluginResponse<'a> { + fn read(bytebuf: &mut ByteBuffer) -> Result { + Ok(Self { + message_id: bytebuf.get_var_int(), + successful: bytebuf.get_bool(), + data: None, // TODO + }) + } +} diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs index 76193a3c5..820f45a2a 100644 --- a/pumpkin-protocol/src/server/play/mod.rs +++ b/pumpkin-protocol/src/server/play/mod.rs @@ -1,137 +1,15 @@ -use num_derive::FromPrimitive; -use num_traits::FromPrimitive; - -use crate::{ServerPacket, VarInt}; - -pub struct SConfirmTeleport { - pub teleport_id: VarInt, -} - -impl ServerPacket for SConfirmTeleport { - const PACKET_ID: VarInt = VarInt(0x00); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - teleport_id: bytebuf.get_var_int(), - } - } -} - -pub struct SChatCommand { - pub command: String, -} - -impl ServerPacket for SChatCommand { - const PACKET_ID: VarInt = VarInt(0x04); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - command: bytebuf.get_string().unwrap(), - } - } -} - -pub struct SPlayerPosition { - pub x: f64, - pub feet_y: f64, - pub z: f64, - pub ground: bool, -} - -impl ServerPacket for SPlayerPosition { - const PACKET_ID: VarInt = VarInt(0x1A); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - x: bytebuf.get_f64(), - feet_y: bytebuf.get_f64(), - z: bytebuf.get_f64(), - ground: bytebuf.get_bool(), - } - } -} - -pub struct SSwingArm { - pub hand: VarInt, -} - -impl ServerPacket for SSwingArm { - const PACKET_ID: VarInt = VarInt(0x36); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - hand: bytebuf.get_var_int(), - } - } -} - -pub struct SPlayerCommand { - pub entitiy_id: VarInt, - pub action: Action, - pub jump_boost: VarInt, -} -#[derive(FromPrimitive)] -pub enum Action { - StartSneaking = 0, - StopSneaking, - LeaveBed, - StartSprinting, - StopSprinting, - StartHourseJump, - OpenVehicleInventory, - StartFlyingElytra, -} - -impl ServerPacket for SPlayerCommand { - const PACKET_ID: VarInt = VarInt(0x25); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - entitiy_id: bytebuf.get_var_int(), - action: Action::from_i32(bytebuf.get_var_int().into()).unwrap(), - jump_boost: bytebuf.get_var_int(), - } - } -} - -pub struct SPlayerPositionRotation { - pub x: f64, - pub feet_y: f64, - pub z: f64, - pub yaw: f32, - pub pitch: f32, - pub ground: bool, -} - -impl ServerPacket for SPlayerPositionRotation { - const PACKET_ID: VarInt = VarInt(0x1B); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - x: bytebuf.get_f64(), - feet_y: bytebuf.get_f64(), - z: bytebuf.get_f64(), - yaw: bytebuf.get_f32(), - pitch: bytebuf.get_f32(), - ground: bytebuf.get_bool(), - } - } -} - -pub struct SPlayerRotation { - pub yaw: f32, - pub pitch: f32, - pub ground: bool, -} - -impl ServerPacket for SPlayerRotation { - const PACKET_ID: VarInt = VarInt(0x1C); - - fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self { - Self { - yaw: bytebuf.get_f32(), - pitch: bytebuf.get_f32(), - ground: bytebuf.get_bool(), - } - } -} +mod s_chat_command; +mod s_confirm_teleport; +mod s_player_command; +mod s_player_position; +mod s_player_position_rotation; +mod s_player_rotation; +mod s_swing_arm; + +pub use s_chat_command::*; +pub use s_confirm_teleport::*; +pub use s_player_command::*; +pub use s_player_position::*; +pub use s_player_position_rotation::*; +pub use s_player_rotation::*; +pub use s_swing_arm::*; diff --git a/pumpkin-protocol/src/server/play/s_chat_command.rs b/pumpkin-protocol/src/server/play/s_chat_command.rs new file mode 100644 index 000000000..31d07698f --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_chat_command.rs @@ -0,0 +1,7 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x04)] +pub struct SChatCommand { + pub command: String, +} diff --git a/pumpkin-protocol/src/server/play/s_confirm_teleport.rs b/pumpkin-protocol/src/server/play/s_confirm_teleport.rs new file mode 100644 index 000000000..2ac360011 --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_confirm_teleport.rs @@ -0,0 +1,9 @@ +use pumpkin_macros::packet; + +use crate::VarInt; + +#[derive(serde::Deserialize)] +#[packet(0x00)] +pub struct SConfirmTeleport { + pub teleport_id: VarInt, +} diff --git a/pumpkin-protocol/src/server/play/s_player_command.rs b/pumpkin-protocol/src/server/play/s_player_command.rs new file mode 100644 index 000000000..f480766b4 --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_player_command.rs @@ -0,0 +1,33 @@ +use num_derive::FromPrimitive; +use num_traits::FromPrimitive; +use pumpkin_macros::packet; + +use crate::{bytebuf::DeserializerError, ServerPacket, VarInt}; + +#[packet(0x25)] +pub struct SPlayerCommand { + pub entitiy_id: VarInt, + pub action: Action, + pub jump_boost: VarInt, +} +#[derive(FromPrimitive)] +pub enum Action { + StartSneaking = 0, + StopSneaking, + LeaveBed, + StartSprinting, + StopSprinting, + StartHourseJump, + OpenVehicleInventory, + StartFlyingElytra, +} + +impl ServerPacket for SPlayerCommand { + fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Result { + Ok(Self { + entitiy_id: bytebuf.get_var_int(), + action: Action::from_i32(bytebuf.get_var_int().into()).unwrap(), + jump_boost: bytebuf.get_var_int(), + }) + } +} diff --git a/pumpkin-protocol/src/server/play/s_player_position.rs b/pumpkin-protocol/src/server/play/s_player_position.rs new file mode 100644 index 000000000..dd9f6cd6f --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_player_position.rs @@ -0,0 +1,10 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x1A)] +pub struct SPlayerPosition { + pub x: f64, + pub feet_y: f64, + pub z: f64, + pub ground: bool, +} diff --git a/pumpkin-protocol/src/server/play/s_player_position_rotation.rs b/pumpkin-protocol/src/server/play/s_player_position_rotation.rs new file mode 100644 index 000000000..1239c22f2 --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_player_position_rotation.rs @@ -0,0 +1,12 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x1B)] +pub struct SPlayerPositionRotation { + pub x: f64, + pub feet_y: f64, + pub z: f64, + pub yaw: f32, + pub pitch: f32, + pub ground: bool, +} diff --git a/pumpkin-protocol/src/server/play/s_player_rotation.rs b/pumpkin-protocol/src/server/play/s_player_rotation.rs new file mode 100644 index 000000000..6f6827e5d --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_player_rotation.rs @@ -0,0 +1,9 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x1C)] +pub struct SPlayerRotation { + pub yaw: f32, + pub pitch: f32, + pub ground: bool, +} diff --git a/pumpkin-protocol/src/server/play/s_swing_arm.rs b/pumpkin-protocol/src/server/play/s_swing_arm.rs new file mode 100644 index 000000000..ea0690630 --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_swing_arm.rs @@ -0,0 +1,8 @@ +use crate::VarInt; +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x36)] +pub struct SSwingArm { + pub hand: VarInt, +} diff --git a/pumpkin-protocol/src/server/status/mod.rs b/pumpkin-protocol/src/server/status/mod.rs index a9f7f7987..fb6b04ab5 100644 --- a/pumpkin-protocol/src/server/status/mod.rs +++ b/pumpkin-protocol/src/server/status/mod.rs @@ -1,27 +1,5 @@ -use crate::{bytebuf::ByteBuffer, ServerPacket, VarInt}; +mod s_ping_request; +mod s_status_request; -pub struct SStatusRequest { - // empty -} - -impl ServerPacket for SStatusRequest { - const PACKET_ID: VarInt = VarInt(0x00); - - fn read(_bytebuf: &mut ByteBuffer) -> Self { - Self {} - } -} - -pub struct SPingRequest { - pub payload: i64, -} - -impl ServerPacket for SPingRequest { - const PACKET_ID: VarInt = VarInt(0x01); - - fn read(bytebuf: &mut ByteBuffer) -> Self { - Self { - payload: bytebuf.get_i64(), - } - } -} +pub use s_ping_request::*; +pub use s_status_request::*; diff --git a/pumpkin-protocol/src/server/status/s_ping_request.rs b/pumpkin-protocol/src/server/status/s_ping_request.rs new file mode 100644 index 000000000..c73f8536a --- /dev/null +++ b/pumpkin-protocol/src/server/status/s_ping_request.rs @@ -0,0 +1,7 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x01)] +pub struct SPingRequest { + pub payload: i64, +} diff --git a/pumpkin-protocol/src/server/status/s_status_request.rs b/pumpkin-protocol/src/server/status/s_status_request.rs new file mode 100644 index 000000000..5d5f64475 --- /dev/null +++ b/pumpkin-protocol/src/server/status/s_status_request.rs @@ -0,0 +1,7 @@ +use pumpkin_macros::packet; + +#[derive(serde::Deserialize)] +#[packet(0x00)] +pub struct SStatusRequest { + // empty +} diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 90da622b2..a9997b44b 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -14,6 +14,7 @@ use authentication::GameProfile; use mio::{event::Event, net::TcpStream, Token}; use num_traits::ToPrimitive; use pumpkin_protocol::{ + bytebuf::packet_id::Packet, client::{ config::CConfigDisconnect, login::CLoginDisconnect, @@ -166,57 +167,59 @@ impl Client { /// Handles an incoming decoded Packet pub fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) { + // TODO: handle each packet's Error instead of calling .unwrap() let bytebuf = &mut packet.bytebuf; match self.connection_state { - pumpkin_protocol::ConnectionState::HandShake => match packet.id { - SHandShake::PACKET_ID => self.handle_handshake(server, SHandShake::read(bytebuf)), + pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 { + SHandShake::PACKET_ID => { + self.handle_handshake(server, SHandShake::read(bytebuf).unwrap()) + } _ => log::error!( "Failed to handle packet id {} while in Handshake state", packet.id.0 ), }, - pumpkin_protocol::ConnectionState::Status => match packet.id { + pumpkin_protocol::ConnectionState::Status => match packet.id.0 { SStatusRequest::PACKET_ID => { - self.handle_status_request(server, SStatusRequest::read(bytebuf)) + self.handle_status_request(server, SStatusRequest::read(bytebuf).unwrap()) } SPingRequest::PACKET_ID => { - self.handle_ping_request(server, SPingRequest::read(bytebuf)) + self.handle_ping_request(server, SPingRequest::read(bytebuf).unwrap()) } _ => log::error!( "Failed to handle packet id {} while in Status state", packet.id.0 ), }, - pumpkin_protocol::ConnectionState::Login => match packet.id { + pumpkin_protocol::ConnectionState::Login => match packet.id.0 { SLoginStart::PACKET_ID => { - self.handle_login_start(server, SLoginStart::read(bytebuf)) - } - SEncryptionResponse::PACKET_ID => { - self.handle_encryption_response(server, SEncryptionResponse::read(bytebuf)) - } - SLoginPluginResponse::PACKET_ID => { - self.handle_plugin_response(server, SLoginPluginResponse::read(bytebuf)) - } - SLoginAcknowledged::PACKET_ID => { - self.handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf)) + self.handle_login_start(server, SLoginStart::read(bytebuf).unwrap()) } + SEncryptionResponse::PACKET_ID => self.handle_encryption_response( + server, + SEncryptionResponse::read(bytebuf).unwrap(), + ), + SLoginPluginResponse::PACKET_ID => self + .handle_plugin_response(server, SLoginPluginResponse::read(bytebuf).unwrap()), + SLoginAcknowledged::PACKET_ID => self + .handle_login_acknowledged(server, SLoginAcknowledged::read(bytebuf).unwrap()), _ => log::error!( "Failed to handle packet id {} while in Login state", packet.id.0 ), }, - pumpkin_protocol::ConnectionState::Config => match packet.id { - SClientInformation::PACKET_ID => { - self.handle_client_information(server, SClientInformation::read(bytebuf)) - } + pumpkin_protocol::ConnectionState::Config => match packet.id.0 { + SClientInformation::PACKET_ID => self + .handle_client_information(server, SClientInformation::read(bytebuf).unwrap()), SPluginMessage::PACKET_ID => { - self.handle_plugin_message(server, SPluginMessage::read(bytebuf)) - } - SAcknowledgeFinishConfig::PACKET_ID => { - self.handle_config_acknowledged(server, SAcknowledgeFinishConfig::read(bytebuf)) + self.handle_plugin_message(server, SPluginMessage::read(bytebuf).unwrap()) } + SAcknowledgeFinishConfig::PACKET_ID => self.handle_config_acknowledged( + server, + SAcknowledgeFinishConfig::read(bytebuf).unwrap(), + ), SKnownPacks::PACKET_ID => { - self.handle_known_packs(server, SKnownPacks::read(bytebuf)) + self.handle_known_packs(server, SKnownPacks::read(bytebuf).unwrap()) } _ => log::error!( "Failed to handle packet id {} while in Config state", @@ -237,26 +240,25 @@ impl Client { pub fn handle_play_packet(&mut self, server: &mut Server, packet: &mut RawPacket) { let bytebuf = &mut packet.bytebuf; - match packet.id { + match packet.id.0 { SConfirmTeleport::PACKET_ID => { - self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf)) + self.handle_confirm_teleport(server, SConfirmTeleport::read(bytebuf).unwrap()) } SChatCommand::PACKET_ID => { - self.handle_chat_command(server, SChatCommand::read(bytebuf)) + self.handle_chat_command(server, SChatCommand::read(bytebuf).unwrap()) } SPlayerPosition::PACKET_ID => { - self.handle_position(server, SPlayerPosition::read(bytebuf)) - } - SPlayerPositionRotation::PACKET_ID => { - self.handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf)) + self.handle_position(server, SPlayerPosition::read(bytebuf).unwrap()) } + SPlayerPositionRotation::PACKET_ID => self + .handle_position_rotation(server, SPlayerPositionRotation::read(bytebuf).unwrap()), SPlayerRotation::PACKET_ID => { - self.handle_rotation(server, SPlayerRotation::read(bytebuf)) + self.handle_rotation(server, SPlayerRotation::read(bytebuf).unwrap()) } SPlayerCommand::PACKET_ID => { - self.handle_player_command(server, SPlayerCommand::read(bytebuf)) + self.handle_player_command(server, SPlayerCommand::read(bytebuf).unwrap()) } - SSwingArm::PACKET_ID => self.handle_swing_arm(server, SSwingArm::read(bytebuf)), + SSwingArm::PACKET_ID => self.handle_swing_arm(server, SSwingArm::read(bytebuf).unwrap()), _ => log::error!("Failed to handle player packet id {}", packet.id.0), } }