From b4f039edb61093c15093b558a46c9d73fefc5b3e Mon Sep 17 00:00:00 2001 From: Kyler <59854022+KylerOlsen@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:23:29 -0700 Subject: [PATCH] Added some clientbound login packets --- src/login.rs | 122 +++++++++++++++++++++++++++++++++++++++++++++++- src/mc_types.rs | 104 ++++++++++++++++++++++++++++++++--------- 2 files changed, 204 insertions(+), 22 deletions(-) diff --git a/src/login.rs b/src/login.rs index 7d737a9..95048aa 100644 --- a/src/login.rs +++ b/src/login.rs @@ -4,10 +4,12 @@ pub mod clientbound { use tokio::net::tcp::OwnedReadHalf; - use crate::mc_types::{self, Result, Packet, PacketError}; + use crate::mc_types::{self, Result, Packet, PacketArray, PacketError}; pub enum Login { Disconnect(Disconnect), + EncryptionRequest(EncryptionRequest), + LoginSuccess(LoginSuccess), } impl Login { @@ -16,6 +18,11 @@ pub mod clientbound { let packet_id = mc_types::get_var_int(&mut data)?; if packet_id == Disconnect::packet_id() { return Ok(Self::Disconnect(Disconnect::get(&mut data)?)) + } else if packet_id == EncryptionRequest::packet_id() { + return Ok(Self::EncryptionRequest( + EncryptionRequest::get(&mut data)?)) + } else if packet_id == LoginSuccess::packet_id() { + return Ok(Self::LoginSuccess(LoginSuccess::get(&mut data)?)) } else { return Err(Box::new(PacketError::InvalidPacketId)) } @@ -46,4 +53,117 @@ pub mod clientbound { } + pub struct EncryptionRequest { + pub server_id: String, + pub public_key: Vec, + pub verify_token: Vec, + } + + impl Packet for EncryptionRequest { + + fn packet_id() -> i32 {1} + + fn get(mut data: &mut Vec) -> Result { + Ok(Self { + server_id: mc_types::get_string(&mut data)?, + public_key: mc_types::get_byte_array(&mut data)?, + verify_token: mc_types::get_byte_array(&mut data)?, + }) + } + + fn convert(&self) -> Vec { + let mut data: Vec = vec![]; + data.append(&mut mc_types::convert_var_int(Self::packet_id())); + data.append(&mut mc_types::convert_string(&self.server_id)); + data.append(&mut mc_types::convert_byte_array( + &mut self.public_key.clone())); + data.append(&mut mc_types::convert_byte_array( + &mut self.verify_token.clone())); + + data + } + + } + + pub struct LoginSuccess { + pub uuid: u128, + pub username: String, + pub properties: Vec, + } + + impl Packet for LoginSuccess { + + fn packet_id() -> i32 {2} + + fn get(mut data: &mut Vec) -> Result { + Ok(Self { + uuid: mc_types::get_uuid(&mut data), + username: mc_types::get_string(&mut data)?, + properties: LoginSuccessProperty::get_array(&mut data)?, + }) + } + + fn convert(&self) -> Vec { + let mut data: Vec = vec![]; + data.append(&mut mc_types::convert_var_int(Self::packet_id())); + data.append(&mut mc_types::convert_uuid(self.uuid)); + data.append(&mut mc_types::convert_string(&self.username)); + data.append(&mut LoginSuccessProperty::convert_array( + &mut self.properties.clone())); + + data + } + + } + + pub struct LoginSuccessProperty { + name: String, + value: String, + signature: Option, + } + + impl Clone for LoginSuccessProperty { + fn clone(&self) -> Self { + Self { + name: self.name.clone(), + value: self.value.clone(), + signature: self.signature.clone(), + } + } + } + + impl PacketArray for LoginSuccessProperty { + + fn get(mut data: &mut Vec) -> Result { + let name = mc_types::get_string(&mut data)?; + let value = mc_types::get_string(&mut data)?; + let is_signed = mc_types::get_bool(&mut data); + let mut signature: Option = None; + if is_signed { + signature = Some(mc_types::get_string(&mut data)?); + } + Ok(Self { + name, + value, + signature, + }) + } + + fn convert(&self) -> Vec { + let mut data: Vec = vec![]; + data.append(&mut mc_types::convert_string(&self.name)); + data.append(&mut mc_types::convert_string(&self.value)); + match &self.signature { + Some(value) => { + data.append(&mut &mut mc_types::convert_bool(true)); + data.append(&mut mc_types::convert_string(&value)); + }, + None => data.append(&mut &mut mc_types::convert_bool(false)) + } + + data + } + + } + } diff --git a/src/mc_types.rs b/src/mc_types.rs index f379c39..f9d6b2a 100644 --- a/src/mc_types.rs +++ b/src/mc_types.rs @@ -18,12 +18,18 @@ const CONTINUE_BIT: u8 = 0x80; #[derive(Debug)] pub enum PacketError { + ValueTooLarge, + RanOutOfBytes, InvalidPacketId, } impl fmt::Display for PacketError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + PacketError::ValueTooLarge => + write!(f, "VarInt value is too large"), + PacketError::RanOutOfBytes => + write!(f, "Ran out of bytes while reading VarInt"), PacketError::InvalidPacketId => write!(f, "Invalid packet id"), } @@ -32,25 +38,6 @@ impl fmt::Display for PacketError { impl Error for PacketError {} -#[derive(Debug)] -pub enum VarIntError { - ValueTooLarge, - RanOutOfBytes, -} - -impl fmt::Display for VarIntError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - VarIntError::ValueTooLarge => - write!(f, "VarInt value is too large"), - VarIntError::RanOutOfBytes => - write!(f, "Ran out of bytes while reading VarInt"), - } - } -} - -impl Error for VarIntError {} - #[derive(Serialize, Deserialize)] pub struct Chat { pub text: String, @@ -114,6 +101,29 @@ async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> Result { Ok(varint) } +pub trait PacketArray: Sized { + fn get(data: &mut Vec) -> Result; + fn convert(&self) -> Vec; + + fn get_array(data: &mut Vec) -> Result> { + let length = get_var_int(data)?; + let mut out_data: Vec = vec![]; + for _ in 0..length { + out_data.push(Self::get(data)?); + } + Ok(out_data) + } + + fn convert_array(array: &mut Vec) -> Vec { + let length = array.len() as i32; + let mut data: Vec = convert_var_int(length); + for element in array { + data.append(&mut Self::convert(element)); + } + data + } +} + pub fn get_bool(data: &mut Vec) -> bool { data.remove(0) != 0 } @@ -219,6 +229,45 @@ pub fn convert_f64(value: f64) -> Vec { convert_u64(value as u64) } +pub fn get_uuid(data: &mut Vec) -> u128 { + ((data.remove(0) as u128) << 120) | + ((data.remove(0) as u128) << 112) | + ((data.remove(0) as u128) << 104) | + ((data.remove(0) as u128) << 96) | + ((data.remove(0) as u128) << 88) | + ((data.remove(0) as u128) << 80) | + ((data.remove(0) as u128) << 72) | + ((data.remove(0) as u128) << 64) | + ((data.remove(0) as u128) << 56) | + ((data.remove(0) as u128) << 48) | + ((data.remove(0) as u128) << 40) | + ((data.remove(0) as u128) << 32) | + ((data.remove(0) as u128) << 24) | + ((data.remove(0) as u128) << 16) | + ((data.remove(0) as u128) << 8) | + (data.remove(0) as u128) +} +pub fn convert_uuid(value: u128) -> Vec { + vec![ + ((value & 0xFF000000000000000000000000000000) >> 120) as u8, + ((value & 0xFF0000000000000000000000000000) >> 112) as u8, + ((value & 0xFF00000000000000000000000000) >> 104) as u8, + ((value & 0xFF000000000000000000000000) >> 96) as u8, + ((value & 0xFF0000000000000000000000) >> 88) as u8, + ((value & 0xFF00000000000000000000) >> 80) as u8, + ((value & 0xFF000000000000000000) >> 72) as u8, + ((value & 0xFF0000000000000000) >> 64) as u8, + ((value & 0xFF00000000000000) >> 56) as u8, + ((value & 0xFF000000000000) >> 48) as u8, + ((value & 0xFF0000000000) >> 40) as u8, + ((value & 0xFF00000000) >> 32) as u8, + ((value & 0xFF000000) >> 24) as u8, + ((value & 0xFF0000) >> 16) as u8, + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + pub fn get_var_int(data: &mut Vec) -> Result { Ok(get_var(data, 32)? as i32) } @@ -239,7 +288,7 @@ fn get_var(data: &mut Vec, size: u8) -> Result { loop { if data.is_empty() { - return Err(Box::new(VarIntError::RanOutOfBytes)); + return Err(Box::new(PacketError::RanOutOfBytes)); } let current_byte = data.remove(0); @@ -252,7 +301,7 @@ fn get_var(data: &mut Vec, size: u8) -> Result { position += 7; if position >= size { - return Err(Box::new(VarIntError::ValueTooLarge)); + return Err(Box::new(PacketError::ValueTooLarge)); } } @@ -283,3 +332,16 @@ pub fn convert_string(s: &str) -> Vec { data.append(&mut s.as_bytes().to_vec()); data } + +pub fn get_byte_array(data: &mut Vec) -> Result> { + let length = get_var_int(data)? as usize; + let buffer = data[..length].to_vec(); + for _ in 0..length { data.remove(0); } + Ok(buffer) +} +pub fn convert_byte_array(mut s: &mut Vec) -> Vec { + let length = s.len() as i32; + let mut data = convert_var_int(length); + data.append(&mut s); + data +}