diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8697fef --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.dat binary diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index a8bb427..4347cd1 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -28,6 +28,7 @@ pub const PROTOCOL_VERSION: usize = 498; const STRING_MAX_LENGTH: u32 = 32_768; /// Possible errors while encoding packet. +#[derive(Debug)] pub enum EncodeError { /// String length can't be more than provided value. StringTooLong { @@ -57,6 +58,7 @@ impl From for EncodeError { } /// Possible errors while decoding packet. +#[derive(Debug)] pub enum DecodeError { /// Packet was not recognized. Invalid data or wrong protocol version. UnknownPacketType { @@ -171,7 +173,7 @@ impl PacketRead for R { } fn read_string(&mut self, max_length: u32) -> Result { - let length = self.read_var_u32()?; + let length = self.read_var_i32()? as u32; if length > max_length as u32 { return Err(DecodeError::StringTooLong { length, max_length }); @@ -229,7 +231,7 @@ impl PacketWrite for W { return Err(EncodeError::StringTooLong { length, max_length }); } - self.write_var_u32(value.len() as u32)?; + self.write_var_i32(value.len() as i32)?; self.write_all(value.as_bytes())?; Ok(()) diff --git a/protocol/src/login.rs b/protocol/src/login.rs index 46d9872..8891408 100644 --- a/protocol/src/login.rs +++ b/protocol/src/login.rs @@ -106,7 +106,6 @@ impl LoginClientBoundPacket { } } -#[derive(minecraft_protocol_derive::MinecraftPacket)] pub struct LoginStart { pub name: String, } @@ -119,6 +118,20 @@ impl LoginStart { } } +impl Packet for LoginStart { + type Output = Self; + + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + writer.write_string(&self.name, LOGIN_MAX_LENGTH) + } + + fn decode(reader: &mut R) -> Result { + let name = reader.read_string(LOGIN_MAX_LENGTH)?; + + Ok(LoginStart { name }) + } +} + pub struct EncryptionResponse { pub shared_secret: Vec, pub verify_token: Vec, @@ -379,3 +392,66 @@ impl Packet for LoginPluginRequest { }) } } + +#[cfg(test)] +mod tests { + use crate::login::LoginPluginResponse; + use crate::login::LoginStart; + use crate::Packet; + use std::io::Cursor; + + #[test] + fn test_login_start_packet_encode() { + let login_start = LoginStart { + name: String::from("Username"), + }; + + let mut vec = Vec::new(); + login_start.encode(&mut vec).unwrap(); + + assert_eq!( + vec, + include_bytes!("../test/packet/login/login_start.dat").to_vec() + ); + } + + #[test] + fn test_login_start_packet_decode() { + let mut cursor = + Cursor::new(include_bytes!("../test/packet/login/login_start.dat").to_vec()); + let login_start = LoginStart::decode(&mut cursor).unwrap(); + + assert_eq!(login_start.name, String::from("Username")); + } + + #[test] + fn test_login_plugin_response_encode() { + let login_plugin_response = LoginPluginResponse { + message_id: 55, + successful: true, + data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + }; + + let mut vec = Vec::new(); + login_plugin_response.encode(&mut vec).unwrap(); + + assert_eq!( + vec, + include_bytes!("../test/packet/login/login_plugin_response.dat").to_vec() + ); + } + + #[test] + fn test_login_plugin_response_decode() { + let mut cursor = + Cursor::new(include_bytes!("../test/packet/login/login_plugin_response.dat").to_vec()); + let login_plugin_response = LoginPluginResponse::decode(&mut cursor).unwrap(); + + assert_eq!(login_plugin_response.message_id, 55); + assert!(login_plugin_response.successful); + assert_eq!( + login_plugin_response.data, + vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ); + } +} diff --git a/protocol/test/packet/login/login_plugin_response.dat b/protocol/test/packet/login/login_plugin_response.dat new file mode 100644 index 0000000..10c09e4 --- /dev/null +++ b/protocol/test/packet/login/login_plugin_response.dat @@ -0,0 +1 @@ +7 diff --git a/protocol/test/packet/login/login_start.dat b/protocol/test/packet/login/login_start.dat new file mode 100644 index 0000000..81e0277 --- /dev/null +++ b/protocol/test/packet/login/login_start.dat @@ -0,0 +1 @@ +Username \ No newline at end of file