Added mc_types::helpers

This commit is contained in:
Kyler Olsen 2025-09-13 01:10:24 -06:00
parent 4c2555d299
commit f4ddfaff77
2 changed files with 329 additions and 222 deletions

View File

@ -1,14 +1,17 @@
// Yeahbut December 2023 // Yeahbut December 2023
// Refactored September 2025
mod error; mod error;
mod protocol; mod protocol;
mod packet; mod packet;
mod helpers;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
pub use crate::mc_types::error::PacketError; pub use crate::mc_types::error::PacketError;
pub use crate::mc_types::protocol::{ProtocolRead, ProtocolConnection}; pub use crate::mc_types::protocol::{ProtocolRead, ProtocolConnection};
pub use crate::mc_types::packet::{Result, Packet, PacketArray}; pub use crate::mc_types::packet::{Result, Packet, PacketArray};
use crate::mc_types::helpers::*;
pub const VERSION_NAME: &str = "1.21"; pub const VERSION_NAME: &str = "1.21";
pub const VERSION_PROTOCOL: i32 = 767; pub const VERSION_PROTOCOL: i32 = 767;
@ -16,261 +19,108 @@ pub const VERSION_PROTOCOL: i32 = 767;
const SEGMENT_BITS: u8 = 0x7F; const SEGMENT_BITS: u8 = 0x7F;
const CONTINUE_BIT: u8 = 0x80; const CONTINUE_BIT: u8 = 0x80;
pub trait McType: Sized {
fn get(data: &mut Vec<u8>) -> Result<Self>;
fn convert(&self) -> Vec<u8>;
}
#[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)] #[derive(Serialize, Deserialize)]
pub struct Chat { pub struct Chat {
pub text: String, pub text: String,
} }
pub fn get_bool(data: &mut Vec<u8>) -> bool { impl McType for bool {
data.remove(0) != 0 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_bool(data)) }
} fn convert(&self) -> Vec<u8> { convert_bool(*self) }
pub fn convert_bool(value: bool) -> Vec<u8> {
vec![value as u8]
} }
pub fn get_u8(data: &mut Vec<u8>) -> u8 { impl McType for u8 {
data.remove(0) fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_u8(data)) }
} fn convert(&self) -> Vec<u8> { convert_u8(*self) }
pub fn convert_u8(value: u8) -> Vec<u8> {
vec![value]
} }
pub fn get_i8(data: &mut Vec<u8>) -> i8 { impl McType for i8 {
get_u8(data) as i8 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_i8(data)) }
} fn convert(&self) -> Vec<u8> { convert_i8(*self) }
pub fn convert_i8(value: i8) -> Vec<u8> {
convert_u8(value as u8)
} }
pub fn get_u16(data: &mut Vec<u8>) -> u16 { impl McType for u16 {
((data.remove(0) as u16) << 8) | fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_u16(data)) }
(data.remove(0) as u16) fn convert(&self) -> Vec<u8> { convert_u16(*self) }
}
pub fn convert_u16(value: u16) -> Vec<u8> {
vec![
((value & 0xFF00) >> 8) as u8,
(value & 0xFF) as u8,
]
} }
pub fn get_i16(data: &mut Vec<u8>) -> i16 { impl McType for i16 {
get_u16(data) as i16 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_i16(data)) }
} fn convert(&self) -> Vec<u8> { convert_i16(*self) }
pub fn convert_i16(value: i16) -> Vec<u8> {
convert_u16(value as u16)
} }
pub fn get_u32(data: &mut Vec<u8>) -> u32 { impl McType for u32 {
((data.remove(0) as u32) << 24) | fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_u32(data)) }
((data.remove(0) as u32) << 16) | fn convert(&self) -> Vec<u8> { convert_u32(*self) }
((data.remove(0) as u32) << 8) |
(data.remove(0) as u32)
}
pub fn convert_u32(value: u32) -> Vec<u8> {
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<u8>) -> i32 { impl McType for i32 {
get_u32(data) as i32 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_i32(data)) }
} fn convert(&self) -> Vec<u8> { convert_i32(*self) }
pub fn convert_i32(value: i32) -> Vec<u8> {
convert_u32(value as u32)
} }
pub fn get_f32(data: &mut Vec<u8>) -> f32 { impl McType for f32 {
get_u32(data) as f32 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_f32(data)) }
} fn convert(&self) -> Vec<u8> { convert_f32(*self) }
pub fn convert_f32(value: f32) -> Vec<u8> {
convert_u32(value as u32)
} }
pub fn get_u64(data: &mut Vec<u8>) -> u64 { impl McType for u64 {
((data.remove(0) as u64) << 56) | fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_u64(data)) }
((data.remove(0) as u64) << 48) | fn convert(&self) -> Vec<u8> { convert_u64(*self) }
((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<u8> {
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<u8>) -> i64 { impl McType for i64 {
get_u64(data) as i64 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_i64(data)) }
} fn convert(&self) -> Vec<u8> { convert_i64(*self) }
pub fn convert_i64(value: i64) -> Vec<u8> {
convert_u64(value as u64)
} }
pub fn get_f64(data: &mut Vec<u8>) -> f64 { impl McType for f64 {
get_u64(data) as f64 fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_f64(data)) }
} fn convert(&self) -> Vec<u8> { convert_f64(*self) }
pub fn convert_f64(value: f64) -> Vec<u8> {
convert_u64(value as u64)
} }
pub fn get_uuid(data: &mut Vec<u8>) -> u128 { impl McType for UUID {
((data.remove(0) as u128) << 120) | fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_uuid(data)) }
((data.remove(0) as u128) << 112) | fn convert(&self) -> Vec<u8> { convert_uuid(*self) }
((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<u8> {
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<u128> {
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<u8>) -> Result<i32> { impl UUID {
Ok(get_var(data, 32)? as i32) fn to_string(&self) -> String { uuid_u128_to_string(*self) }
} fn from_string(str_data: &str) -> Result<Self> {
pub fn convert_var_int(value: i32) -> Vec<u8> { uuid_string_to_u128(str_data)
convert_var(value as i64)
}
pub fn get_var_long(data: &mut Vec<u8>) -> Result<i64> {
get_var(data, 64)
}
pub fn convert_var_long(value: i64) -> Vec<u8> {
convert_var(value)
}
fn get_var(data: &mut Vec<u8>, size: u8) -> Result<i64> {
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<u8> {
let mut data: Vec<u8> = 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<u8>) -> Result<String> { impl McType for VarInt {
let length = get_var_int(data)? as usize; fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_var_int(data)) }
let buffer = data[..length].to_vec(); fn convert(&self) -> Vec<u8> { convert_var_int(*self) }
for _ in 0..length { data.remove(0); }
Ok(String::from_utf8_lossy(&buffer).to_string())
}
pub fn convert_string(s: &str) -> Vec<u8> {
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<u8>) -> Result<Vec<u8>> { impl McType for VarLong {
let length = get_var_int(data)? as usize; fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_var_long(data)) }
let buffer = data[..length].to_vec(); fn convert(&self) -> Vec<u8> { convert_var_long(*self) }
for _ in 0..length { data.remove(0); }
Ok(buffer)
} }
pub fn convert_byte_array(mut s: &mut Vec<u8>) -> Vec<u8> {
let length = s.len() as i32; impl McType for String {
let mut data = convert_var_int(length); fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_string(data)) }
data.append(&mut s); fn convert(&self) -> Vec<u8> { convert_string(*self) }
data }
impl McType for Vec<u8> {
fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_byte_array(data)) }
fn convert(&self) -> Vec<u8> { convert_byte_array(*self) }
} }

257
src/mc_types/helpers.rs Normal file
View File

@ -0,0 +1,257 @@
// Yeahbut September 2025
use crate::mc_types::*;
pub fn get_bool(data: &mut Vec<u8>) -> bool {
data.remove(0) != 0
}
pub fn convert_bool(value: bool) -> Vec<u8> {
vec![value as u8]
}
pub fn get_u8(data: &mut Vec<u8>) -> u8 {
data.remove(0)
}
pub fn convert_u8(value: u8) -> Vec<u8> {
vec![value]
}
pub fn get_i8(data: &mut Vec<u8>) -> i8 {
get_u8(data) as i8
}
pub fn convert_i8(value: i8) -> Vec<u8> {
convert_u8(value as u8)
}
pub fn get_u16(data: &mut Vec<u8>) -> u16 {
((data.remove(0) as u16) << 8) |
(data.remove(0) as u16)
}
pub fn convert_u16(value: u16) -> Vec<u8> {
vec![
((value & 0xFF00) >> 8) as u8,
(value & 0xFF) as u8,
]
}
pub fn get_i16(data: &mut Vec<u8>) -> i16 {
get_u16(data) as i16
}
pub fn convert_i16(value: i16) -> Vec<u8> {
convert_u16(value as u16)
}
pub fn get_u32(data: &mut Vec<u8>) -> 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<u8> {
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<u8>) -> i32 {
get_u32(data) as i32
}
pub fn convert_i32(value: i32) -> Vec<u8> {
convert_u32(value as u32)
}
pub fn get_f32(data: &mut Vec<u8>) -> f32 {
get_u32(data) as f32
}
pub fn convert_f32(value: f32) -> Vec<u8> {
convert_u32(value as u32)
}
pub fn get_u64(data: &mut Vec<u8>) -> 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<u8> {
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<u8>) -> i64 {
get_u64(data) as i64
}
pub fn convert_i64(value: i64) -> Vec<u8> {
convert_u64(value as u64)
}
pub fn get_f64(data: &mut Vec<u8>) -> f64 {
get_u64(data) as f64
}
pub fn convert_f64(value: f64) -> Vec<u8> {
convert_u64(value as u64)
}
pub fn get_uuid(data: &mut Vec<u8>) -> 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<u8> {
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<u128> {
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<u8>) -> Result<i32> {
Ok(get_var(data, 32)? as i32)
}
pub fn convert_var_int(value: i32) -> Vec<u8> {
convert_var(value as i64)
}
pub fn get_var_long(data: &mut Vec<u8>) -> Result<i64> {
get_var(data, 64)
}
pub fn convert_var_long(value: i64) -> Vec<u8> {
convert_var(value)
}
fn get_var(data: &mut Vec<u8>, size: u8) -> Result<i64> {
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<u8> {
let mut data: Vec<u8> = 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<u8>) -> Result<String> {
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<u8> {
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<u8>) -> Result<Vec<u8>> {
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<u8>) -> Vec<u8> {
let length = s.len() as i32;
let mut data = convert_var_int(length);
data.append(&mut s);
data
}