From f4ddfaff77e1e35f4c5ec7dcc0f1dfcc0cfbc2c2 Mon Sep 17 00:00:00 2001 From: Kyler Date: Sat, 13 Sep 2025 01:10:24 -0600 Subject: [PATCH] Added mc_types::helpers --- src/mc_types.rs | 294 ++++++++++------------------------------ src/mc_types/helpers.rs | 257 +++++++++++++++++++++++++++++++++++ 2 files changed, 329 insertions(+), 222 deletions(-) create mode 100644 src/mc_types/helpers.rs diff --git a/src/mc_types.rs b/src/mc_types.rs index 01cf4a3..3cd4be9 100644 --- a/src/mc_types.rs +++ b/src/mc_types.rs @@ -1,14 +1,17 @@ // Yeahbut December 2023 +// Refactored September 2025 mod error; mod protocol; mod packet; +mod helpers; use serde::{Serialize, Deserialize}; pub use crate::mc_types::error::PacketError; pub use crate::mc_types::protocol::{ProtocolRead, ProtocolConnection}; pub use crate::mc_types::packet::{Result, Packet, PacketArray}; +use crate::mc_types::helpers::*; pub const VERSION_NAME: &str = "1.21"; pub const VERSION_PROTOCOL: i32 = 767; @@ -16,261 +19,108 @@ pub const VERSION_PROTOCOL: i32 = 767; const SEGMENT_BITS: u8 = 0x7F; const CONTINUE_BIT: u8 = 0x80; +pub trait McType: Sized { + fn get(data: &mut Vec) -> Result; + fn convert(&self) -> Vec; +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct UUID(pub u128); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct VarInt(pub i32); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct VarLong(pub i64); + #[derive(Serialize, Deserialize)] pub struct Chat { pub text: String, } -pub fn get_bool(data: &mut Vec) -> bool { - data.remove(0) != 0 -} -pub fn convert_bool(value: bool) -> Vec { - vec![value as u8] +impl McType for bool { + fn get(data: &mut Vec) -> Result { Ok(get_bool(data)) } + fn convert(&self) -> Vec { convert_bool(*self) } } -pub fn get_u8(data: &mut Vec) -> u8 { - data.remove(0) -} -pub fn convert_u8(value: u8) -> Vec { - vec![value] +impl McType for u8 { + fn get(data: &mut Vec) -> Result { Ok(get_u8(data)) } + fn convert(&self) -> Vec { convert_u8(*self) } } -pub fn get_i8(data: &mut Vec) -> i8 { - get_u8(data) as i8 -} -pub fn convert_i8(value: i8) -> Vec { - convert_u8(value as u8) +impl McType for i8 { + fn get(data: &mut Vec) -> Result { Ok(get_i8(data)) } + fn convert(&self) -> Vec { convert_i8(*self) } } -pub fn get_u16(data: &mut Vec) -> u16 { - ((data.remove(0) as u16) << 8) | - (data.remove(0) as u16) -} -pub fn convert_u16(value: u16) -> Vec { - vec![ - ((value & 0xFF00) >> 8) as u8, - (value & 0xFF) as u8, - ] +impl McType for u16 { + fn get(data: &mut Vec) -> Result { Ok(get_u16(data)) } + fn convert(&self) -> Vec { convert_u16(*self) } } -pub fn get_i16(data: &mut Vec) -> i16 { - get_u16(data) as i16 -} -pub fn convert_i16(value: i16) -> Vec { - convert_u16(value as u16) +impl McType for i16 { + fn get(data: &mut Vec) -> Result { Ok(get_i16(data)) } + fn convert(&self) -> Vec { convert_i16(*self) } } -pub fn get_u32(data: &mut Vec) -> u32 { - ((data.remove(0) as u32) << 24) | - ((data.remove(0) as u32) << 16) | - ((data.remove(0) as u32) << 8) | - (data.remove(0) as u32) -} -pub fn convert_u32(value: u32) -> Vec { - vec![ - ((value & 0xFF0000) >> 24) as u8, - ((value & 0xFF0000) >> 16) as u8, - ((value & 0xFF00) >> 8) as u8, - (value & 0xFF) as u8, - ] +impl McType for u32 { + fn get(data: &mut Vec) -> Result { Ok(get_u32(data)) } + fn convert(&self) -> Vec { convert_u32(*self) } } -pub fn get_i32(data: &mut Vec) -> i32 { - get_u32(data) as i32 -} -pub fn convert_i32(value: i32) -> Vec { - convert_u32(value as u32) +impl McType for i32 { + fn get(data: &mut Vec) -> Result { Ok(get_i32(data)) } + fn convert(&self) -> Vec { convert_i32(*self) } } -pub fn get_f32(data: &mut Vec) -> f32 { - get_u32(data) as f32 -} -pub fn convert_f32(value: f32) -> Vec { - convert_u32(value as u32) +impl McType for f32 { + fn get(data: &mut Vec) -> Result { Ok(get_f32(data)) } + fn convert(&self) -> Vec { convert_f32(*self) } } -pub fn get_u64(data: &mut Vec) -> u64 { - ((data.remove(0) as u64) << 56) | - ((data.remove(0) as u64) << 48) | - ((data.remove(0) as u64) << 40) | - ((data.remove(0) as u64) << 32) | - ((data.remove(0) as u64) << 24) | - ((data.remove(0) as u64) << 16) | - ((data.remove(0) as u64) << 8) | - (data.remove(0) as u64) -} -pub fn convert_u64(value: u64) -> Vec { - vec![ - ((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, - ] +impl McType for u64 { + fn get(data: &mut Vec) -> Result { Ok(get_u64(data)) } + fn convert(&self) -> Vec { convert_u64(*self) } } -pub fn get_i64(data: &mut Vec) -> i64 { - get_u64(data) as i64 -} -pub fn convert_i64(value: i64) -> Vec { - convert_u64(value as u64) +impl McType for i64 { + fn get(data: &mut Vec) -> Result { Ok(get_i64(data)) } + fn convert(&self) -> Vec { convert_i64(*self) } } -pub fn get_f64(data: &mut Vec) -> f64 { - get_u64(data) as f64 -} -pub fn convert_f64(value: f64) -> Vec { - convert_u64(value as u64) +impl McType for f64 { + fn get(data: &mut Vec) -> Result { Ok(get_f64(data)) } + fn convert(&self) -> Vec { convert_f64(*self) } } -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 uuid_u128_to_string(uuid: u128) -> String { - let uuid_bytes = convert_uuid(uuid); - format!( - "{:08x}-{:04x}-{:04x}-{:04x}-{:012x}", - get_u32(&mut vec![ - uuid_bytes[0], - uuid_bytes[1], - uuid_bytes[2], - uuid_bytes[3], - ]), - get_u16(&mut vec![uuid_bytes[4], uuid_bytes[5]]), - get_u16(&mut vec![uuid_bytes[6], uuid_bytes[7]]), - get_u16(&mut vec![uuid_bytes[8], uuid_bytes[9]]), - get_u64(&mut vec![ - 0, - 0, - uuid_bytes[10], - uuid_bytes[11], - uuid_bytes[12], - uuid_bytes[13], - uuid_bytes[14], - uuid_bytes[15], - ]), - ) -} -pub fn uuid_string_to_u128(uuid: &str) -> Result { - let cleaned_uuid = uuid.replace("-", ""); - if cleaned_uuid.len() != 32 { - return Err(Box::new(PacketError::InvalidUUIDString)); - } - Ok(u128::from_str_radix(&cleaned_uuid, 16)?) +impl McType for UUID { + fn get(data: &mut Vec) -> Result { Ok(get_uuid(data)) } + fn convert(&self) -> Vec { convert_uuid(*self) } } -pub fn get_var_int(data: &mut Vec) -> Result { - Ok(get_var(data, 32)? as i32) -} -pub fn convert_var_int(value: i32) -> Vec { - convert_var(value as i64) -} - -pub fn get_var_long(data: &mut Vec) -> Result { - get_var(data, 64) -} -pub fn convert_var_long(value: i64) -> Vec { - convert_var(value) -} - -fn get_var(data: &mut Vec, size: u8) -> Result { - let mut value: i64 = 0; - let mut position: u8 = 0; - - loop { - if data.is_empty() { - return Err(Box::new(PacketError::RanOutOfBytes)); - } - - let current_byte = data.remove(0); - value |= ((current_byte & SEGMENT_BITS) as i64) << position; - - if (current_byte & CONTINUE_BIT) == 0 { - break; - } - - position += 7; - - if position >= size { - return Err(Box::new(PacketError::ValueTooLarge)); - } - } - - Ok(value) -} -fn convert_var(mut value: i64) -> Vec { - let mut data: Vec = vec![]; - loop { - if (value & !(SEGMENT_BITS as i64)) == 0 { - data.append(&mut vec![value as u8]); - return data; - } - data.append( - &mut vec![(value & (SEGMENT_BITS as i64)) as u8 | CONTINUE_BIT]); - value >>= 7; +impl UUID { + fn to_string(&self) -> String { uuid_u128_to_string(*self) } + fn from_string(str_data: &str) -> Result { + uuid_string_to_u128(str_data) } } -pub fn get_string(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(String::from_utf8_lossy(&buffer).to_string()) -} -pub fn convert_string(s: &str) -> Vec { - let length = s.len() as i32; - let mut data = convert_var_int(length); - data.append(&mut s.as_bytes().to_vec()); - data +impl McType for VarInt { + fn get(data: &mut Vec) -> Result { Ok(get_var_int(data)) } + fn convert(&self) -> Vec { convert_var_int(*self) } } -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) +impl McType for VarLong { + fn get(data: &mut Vec) -> Result { Ok(get_var_long(data)) } + fn convert(&self) -> Vec { convert_var_long(*self) } } -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 + +impl McType for String { + fn get(data: &mut Vec) -> Result { Ok(get_string(data)) } + fn convert(&self) -> Vec { convert_string(*self) } +} + +impl McType for Vec { + fn get(data: &mut Vec) -> Result { Ok(get_byte_array(data)) } + fn convert(&self) -> Vec { convert_byte_array(*self) } } diff --git a/src/mc_types/helpers.rs b/src/mc_types/helpers.rs new file mode 100644 index 0000000..d73e481 --- /dev/null +++ b/src/mc_types/helpers.rs @@ -0,0 +1,257 @@ +// Yeahbut September 2025 + +use crate::mc_types::*; + +pub fn get_bool(data: &mut Vec) -> bool { + data.remove(0) != 0 +} +pub fn convert_bool(value: bool) -> Vec { + vec![value as u8] +} + +pub fn get_u8(data: &mut Vec) -> u8 { + data.remove(0) +} +pub fn convert_u8(value: u8) -> Vec { + vec![value] +} + +pub fn get_i8(data: &mut Vec) -> i8 { + get_u8(data) as i8 +} +pub fn convert_i8(value: i8) -> Vec { + convert_u8(value as u8) +} + +pub fn get_u16(data: &mut Vec) -> u16 { + ((data.remove(0) as u16) << 8) | + (data.remove(0) as u16) +} +pub fn convert_u16(value: u16) -> Vec { + vec![ + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + +pub fn get_i16(data: &mut Vec) -> i16 { + get_u16(data) as i16 +} +pub fn convert_i16(value: i16) -> Vec { + convert_u16(value as u16) +} + +pub fn get_u32(data: &mut Vec) -> u32 { + ((data.remove(0) as u32) << 24) | + ((data.remove(0) as u32) << 16) | + ((data.remove(0) as u32) << 8) | + (data.remove(0) as u32) +} +pub fn convert_u32(value: u32) -> Vec { + vec![ + ((value & 0xFF0000) >> 24) as u8, + ((value & 0xFF0000) >> 16) as u8, + ((value & 0xFF00) >> 8) as u8, + (value & 0xFF) as u8, + ] +} + +pub fn get_i32(data: &mut Vec) -> i32 { + get_u32(data) as i32 +} +pub fn convert_i32(value: i32) -> Vec { + convert_u32(value as u32) +} + +pub fn get_f32(data: &mut Vec) -> f32 { + get_u32(data) as f32 +} +pub fn convert_f32(value: f32) -> Vec { + convert_u32(value as u32) +} + +pub fn get_u64(data: &mut Vec) -> u64 { + ((data.remove(0) as u64) << 56) | + ((data.remove(0) as u64) << 48) | + ((data.remove(0) as u64) << 40) | + ((data.remove(0) as u64) << 32) | + ((data.remove(0) as u64) << 24) | + ((data.remove(0) as u64) << 16) | + ((data.remove(0) as u64) << 8) | + (data.remove(0) as u64) +} +pub fn convert_u64(value: u64) -> Vec { + vec![ + ((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_i64(data: &mut Vec) -> i64 { + get_u64(data) as i64 +} +pub fn convert_i64(value: i64) -> Vec { + convert_u64(value as u64) +} + +pub fn get_f64(data: &mut Vec) -> f64 { + get_u64(data) as f64 +} +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 uuid_u128_to_string(uuid: u128) -> String { + let uuid_bytes = convert_uuid(uuid); + format!( + "{:08x}-{:04x}-{:04x}-{:04x}-{:012x}", + get_u32(&mut vec![ + uuid_bytes[0], + uuid_bytes[1], + uuid_bytes[2], + uuid_bytes[3], + ]), + get_u16(&mut vec![uuid_bytes[4], uuid_bytes[5]]), + get_u16(&mut vec![uuid_bytes[6], uuid_bytes[7]]), + get_u16(&mut vec![uuid_bytes[8], uuid_bytes[9]]), + get_u64(&mut vec![ + 0, + 0, + uuid_bytes[10], + uuid_bytes[11], + uuid_bytes[12], + uuid_bytes[13], + uuid_bytes[14], + uuid_bytes[15], + ]), + ) +} +pub fn uuid_string_to_u128(uuid: &str) -> Result { + let cleaned_uuid = uuid.replace("-", ""); + if cleaned_uuid.len() != 32 { + return Err(Box::new(PacketError::InvalidUUIDString)); + } + Ok(u128::from_str_radix(&cleaned_uuid, 16)?) +} + +pub fn get_var_int(data: &mut Vec) -> Result { + Ok(get_var(data, 32)? as i32) +} +pub fn convert_var_int(value: i32) -> Vec { + convert_var(value as i64) +} + +pub fn get_var_long(data: &mut Vec) -> Result { + get_var(data, 64) +} +pub fn convert_var_long(value: i64) -> Vec { + convert_var(value) +} + +fn get_var(data: &mut Vec, size: u8) -> Result { + let mut value: i64 = 0; + let mut position: u8 = 0; + + loop { + if data.is_empty() { + return Err(Box::new(PacketError::RanOutOfBytes)); + } + + let current_byte = data.remove(0); + value |= ((current_byte & SEGMENT_BITS) as i64) << position; + + if (current_byte & CONTINUE_BIT) == 0 { + break; + } + + position += 7; + + if position >= size { + return Err(Box::new(PacketError::ValueTooLarge)); + } + } + + Ok(value) +} +fn convert_var(mut value: i64) -> Vec { + let mut data: Vec = vec![]; + loop { + if (value & !(SEGMENT_BITS as i64)) == 0 { + data.append(&mut vec![value as u8]); + return data; + } + data.append( + &mut vec![(value & (SEGMENT_BITS as i64)) as u8 | CONTINUE_BIT]); + value >>= 7; + } +} + +pub fn get_string(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(String::from_utf8_lossy(&buffer).to_string()) +} +pub fn convert_string(s: &str) -> Vec { + let length = s.len() as i32; + let mut data = convert_var_int(length); + 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 +}