Started Macros
This commit is contained in:
parent
600de7f025
commit
f3f5de64ac
|
@ -25,7 +25,7 @@ checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -198,11 +198,20 @@ name = "purple_cello_mc_protocol"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"purple_cello_mc_protocol_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "purple_cello_mc_protocol_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
|
@ -256,7 +265,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -295,6 +304,17 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.42"
|
||||
|
@ -333,7 +353,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.42",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -10,3 +10,4 @@ tokio = { version = "1", features = ["full"] }
|
|||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
async-trait = "0.1.75"
|
||||
purple_cello_mc_protocol_derive = { path = "./purple_cello_mc_protocol_derive" }
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, Data, DataStruct, DeriveInput};
|
||||
|
||||
#[proc_macro_derive(Packet)]
|
||||
pub fn packet_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let struct_name = &input.ident;
|
||||
|
||||
if let Data::Struct(DataStruct { fields, .. }) = &input.data {
|
||||
let field_names: Vec<_> = fields
|
||||
.iter()
|
||||
.map(|field| field.ident.as_ref().unwrap())
|
||||
.collect();
|
||||
let field_types: Vec<_> = fields
|
||||
.iter()
|
||||
.map(|field| &field.ty)
|
||||
.collect();
|
||||
|
||||
// let get_code = quote! {
|
||||
// Ok(Self {
|
||||
// #( #field_names: #{
|
||||
// let data_fn = #{
|
||||
// let field_ty_str = stringify!(#field_types).replace(" ", "");
|
||||
// TYPE_FUNCTION_GET_MAPPING
|
||||
// .iter()
|
||||
// .find(|(ty, _)| field_ty_str.contains(*ty))
|
||||
// .map(|(_, fn_name)| fn_name)
|
||||
// .unwrap_or_else(|| panic!("Unknown type: {}", field_ty_str))
|
||||
// };
|
||||
// let fn_ident = syn::Ident::new(data_fn, proc_macro2::Span::call_site());
|
||||
// quote! { #fn_ident(data)? }
|
||||
// }, )*
|
||||
// })
|
||||
// };
|
||||
|
||||
// let convert_code = quote! {
|
||||
// let mut data: Vec<u8> = vec![];
|
||||
// data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
// #( data.append(&mut #{
|
||||
// let data_fn = #{
|
||||
// let field_ty_str = stringify!(#field_types).replace(" ", "");
|
||||
// TYPE_FUNCTION_CONVERT_MAPPING
|
||||
// .iter()
|
||||
// .find(|(ty, _)| field_ty_str.contains(*ty))
|
||||
// .map(|(_, fn_name)| fn_name)
|
||||
// .unwrap_or_else(|| panic!("Unknown type: {}", field_ty_str))
|
||||
// };
|
||||
// let fn_ident = syn::Ident::new(data_fn, proc_macro2::Span::call_site());
|
||||
// quote! { #fn_ident(self.#field_names) }
|
||||
// }); )*
|
||||
// };
|
||||
|
||||
let type_function_get_mapping: Vec<(&str, &str)> = vec![
|
||||
("Boolean", "mc_types::get_boolean"),
|
||||
("Byte", "mc_types::get_byte"),
|
||||
("UnsignedByte", "mc_types::get_unsigned_byte"),
|
||||
("Short", "mc_types::get_short"),
|
||||
("UnsignedShort", "mc_types::get_unsigned_short"),
|
||||
("Int", "mc_types::get_int"),
|
||||
("Long", "mc_types::get_long"),
|
||||
("Float", "mc_types::get_float"),
|
||||
("Double", "mc_types::get_double"),
|
||||
("String", "mc_types::get_string"),
|
||||
("Json", "mc_types::get_string"),
|
||||
("Identifier", "mc_types::get_string"),
|
||||
("VarInt", "mc_types::get_var_int"),
|
||||
("VarLong", "mc_types::get_var_long"),
|
||||
("Position", "mc_types::get_position"),
|
||||
("Angle", "mc_types::get_unsigned_short"),
|
||||
("Uuid", "mc_types::get_uuid"),
|
||||
("ByteArray", "mc_types::get_byte_array"),
|
||||
];
|
||||
|
||||
let type_function_convert_mapping: Vec<(&str, &str)> = vec![
|
||||
("Boolean", "mc_types::convert_boolean"),
|
||||
("Byte", "mc_types::convert_byte"),
|
||||
("UnsignedByte", "mc_types::convert_unsigned_byte"),
|
||||
("Short", "mc_types::convert_short"),
|
||||
("UnsignedShort", "mc_types::convert_unsigned_short"),
|
||||
("Int", "mc_types::convert_int"),
|
||||
("Long", "mc_types::convert_long"),
|
||||
("Float", "mc_types::convert_float"),
|
||||
("Double", "mc_types::convert_double"),
|
||||
("String", "mc_types::convert_string"),
|
||||
("Json", "mc_types::convert_string"),
|
||||
("Identifier", "mc_types::convert_string"),
|
||||
("VarInt", "mc_types::convert_var_int"),
|
||||
("VarLong", "mc_types::convert_var_long"),
|
||||
("Position", "mc_types::convert_position"),
|
||||
("Angle", "mc_types::convert_unsigned_short"),
|
||||
("Uuid", "mc_types::convert_uuid"),
|
||||
("ByteArray", "mc_types::convert_byte_array"),
|
||||
];
|
||||
|
||||
let get_code = {
|
||||
let field_code: Vec<_> = field_names.iter().zip(field_types.iter()).map(|(name, ty)| {
|
||||
let data_fn = {
|
||||
let field_ty_str = stringify!(#ty).replace(" ", "");
|
||||
type_function_get_mapping
|
||||
.iter()
|
||||
.find(|(ty, _)| field_ty_str.contains(*ty))
|
||||
.map(|(_, fn_name)| fn_name)
|
||||
.unwrap_or_else(|| panic!("Unknown type: {}", field_ty_str))
|
||||
};
|
||||
quote! { #name: #data_fn(data)?, }
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
Ok(Self {
|
||||
#( #field_code )*
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let convert_code = {
|
||||
let field_code: Vec<_> = field_names.iter().zip(field_types.iter()).map(|(name, ty)| {
|
||||
let data_fn = {
|
||||
let field_ty_str = stringify!(#ty).replace(" ", "");
|
||||
type_function_convert_mapping
|
||||
.iter()
|
||||
.find(|(ty, _)| field_ty_str.contains(*ty))
|
||||
.map(|(_, fn_name)| fn_name)
|
||||
.unwrap_or_else(|| panic!("Unknown type: {}", field_ty_str))
|
||||
};
|
||||
quote! { mc_types::#data_fn(self.#name), }
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
#( data.append(&mut #field_code );)*
|
||||
data
|
||||
}
|
||||
};
|
||||
|
||||
let gen = quote! {
|
||||
impl Packet for #struct_name {
|
||||
fn packet_id() -> i32 { 0 }
|
||||
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
#get_code
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
#convert_code
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return gen.into();
|
||||
}
|
||||
|
||||
TokenStream::from(quote! {
|
||||
compile_error!("Packet derive macro only supports named structs");
|
||||
})
|
||||
}
|
|
@ -4,7 +4,8 @@ pub mod serverbound {
|
|||
|
||||
use tokio::net::tcp::OwnedReadHalf;
|
||||
|
||||
use crate::mc_types::{self, Result, Packet, PacketError};
|
||||
use crate::mc_types::{self, Result, Packet, PacketError, MCTypes};
|
||||
use purple_cello_mc_protocol_derive::packet_derive;
|
||||
|
||||
pub enum HandshakeEnum {
|
||||
Handshake(Handshake),
|
||||
|
@ -22,36 +23,38 @@ pub mod serverbound {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(packet_derive)]
|
||||
pub struct Handshake {
|
||||
pub protocol_version: i32,
|
||||
pub server_address: String,
|
||||
pub server_port: u16,
|
||||
pub next_state: i32,
|
||||
pub protocol_version: MCTypes::VarInt,
|
||||
pub server_address: MCTypes::String,
|
||||
pub server_port: MCTypes::UnsignedShort,
|
||||
pub next_state: MCTypes::VarInt,
|
||||
}
|
||||
|
||||
impl Packet for Handshake {
|
||||
// impl Packet for Handshake {
|
||||
|
||||
fn packet_id() -> i32 {0}
|
||||
// fn packet_id() -> i32 {0}
|
||||
|
||||
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
protocol_version: mc_types::get_var_int(data)?,
|
||||
server_address: mc_types::get_string(data)?,
|
||||
server_port: mc_types::get_u16(data),
|
||||
next_state: mc_types::get_var_int(data)?,
|
||||
})
|
||||
}
|
||||
// fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
// Ok(Self {
|
||||
// protocol_version: mc_types::get_var_int(data)?,
|
||||
// server_address: mc_types::get_string(data)?,
|
||||
// server_port: mc_types::get_unsigned_short(data)?,
|
||||
// next_state: mc_types::get_var_int(data)?,
|
||||
// })
|
||||
// }
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
data.append(&mut mc_types::convert_var_int(self.protocol_version));
|
||||
data.append(&mut mc_types::convert_string(&self.server_address));
|
||||
data.append(&mut mc_types::convert_u16(self.server_port));
|
||||
data.append(&mut mc_types::convert_var_int(self.next_state));
|
||||
// fn convert(&self) -> Vec<u8> {
|
||||
// let mut data: Vec<u8> = vec![];
|
||||
// data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
// data.append(&mut mc_types::convert_var_int(self.protocol_version));
|
||||
// data.append(&mut mc_types::convert_string(&self.server_address));
|
||||
// data.append(
|
||||
// &mut mc_types::convert_unsigned_short(self.server_port));
|
||||
// data.append(&mut mc_types::convert_var_int(self.next_state));
|
||||
|
||||
data
|
||||
}
|
||||
// data
|
||||
// }
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Yeahbut December 2023
|
||||
|
||||
pub mod mc_types;
|
||||
// pub mod handshake;
|
||||
// pub mod status;
|
||||
// pub mod login;
|
||||
pub mod handshake;
|
||||
pub mod status;
|
||||
pub mod login;
|
||||
|
|
12
src/login.rs
12
src/login.rs
|
@ -4,7 +4,7 @@ pub mod clientbound {
|
|||
|
||||
use tokio::net::tcp::OwnedReadHalf;
|
||||
|
||||
use crate::mc_types::{self, Result, Packet, PacketArray, PacketError};
|
||||
use crate::mc_types::{self, Result, Packet, MCTypeArray, PacketError};
|
||||
|
||||
pub enum Login {
|
||||
Disconnect(Disconnect),
|
||||
|
@ -97,7 +97,7 @@ pub mod clientbound {
|
|||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
uuid: mc_types::get_uuid(&mut data),
|
||||
uuid: mc_types::get_uuid(&mut data)?,
|
||||
username: mc_types::get_string(&mut data)?,
|
||||
properties: LoginSuccessProperty::get_array(&mut data)?,
|
||||
})
|
||||
|
@ -132,12 +132,12 @@ pub mod clientbound {
|
|||
}
|
||||
}
|
||||
|
||||
impl PacketArray for LoginSuccessProperty {
|
||||
impl MCTypeArray for LoginSuccessProperty {
|
||||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
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 is_signed = mc_types::get_boolean(&mut data)?;
|
||||
let mut signature: Option<String> = None;
|
||||
if is_signed {
|
||||
signature = Some(mc_types::get_string(&mut data)?);
|
||||
|
@ -155,10 +155,10 @@ pub mod clientbound {
|
|||
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 &mut mc_types::convert_boolean(true));
|
||||
data.append(&mut mc_types::convert_string(&value));
|
||||
},
|
||||
None => data.append(&mut &mut mc_types::convert_bool(false))
|
||||
None => data.append(&mut &mut mc_types::convert_boolean(false))
|
||||
}
|
||||
|
||||
data
|
||||
|
|
|
@ -109,6 +109,25 @@ async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> Result<i32> {
|
|||
|
||||
// enum MCTypes
|
||||
|
||||
// pub enum MCTypes {
|
||||
// Boolean,
|
||||
// Byte,
|
||||
// UnsignedByte,
|
||||
// Short,
|
||||
// UnsignedShort,
|
||||
// Int,
|
||||
// Long,
|
||||
// Float,
|
||||
// Double,
|
||||
// String,
|
||||
// VarInt,
|
||||
// VarLong,
|
||||
// Uuid,
|
||||
// Optional,
|
||||
// Array,
|
||||
// ByteArray,
|
||||
// }
|
||||
|
||||
pub enum MCTypes {
|
||||
Boolean,
|
||||
Byte,
|
||||
|
@ -131,8 +150,8 @@ pub enum MCTypes {
|
|||
Position,
|
||||
Angle,
|
||||
Uuid,
|
||||
Optional,
|
||||
Array,
|
||||
// Optional,
|
||||
// Array,
|
||||
// Enum,
|
||||
ByteArray,
|
||||
}
|
||||
|
@ -278,24 +297,6 @@ pub fn convert_string(s: &str) -> Vec<u8> {
|
|||
// convert_nbt_tag(value)
|
||||
// }
|
||||
|
||||
// fn get_json_chat <- string
|
||||
pub fn get_json_chat(data: &mut Vec<u8>) -> Result<String> {
|
||||
get_string(data)
|
||||
}
|
||||
// fn convert_json_chat <- string
|
||||
pub fn convert_json_chat(value: String) -> Vec<u8> {
|
||||
convert_string(value)
|
||||
}
|
||||
|
||||
// fn get_identifier <- string
|
||||
pub fn get_identifier(data: &mut Vec<u8>) -> Result<String> {
|
||||
get_string(data)
|
||||
}
|
||||
// fn convert_identifier <- string
|
||||
pub fn convert_identifier(value: String) -> Vec<u8> {
|
||||
convert_string(value)
|
||||
}
|
||||
|
||||
// fn get_var_int
|
||||
pub fn get_var_int(data: &mut Vec<u8>) -> Result<i32> {
|
||||
Ok(get_var(data, 32)? as i32)
|
||||
|
@ -374,48 +375,34 @@ pub struct MCPosition {
|
|||
z: i32,
|
||||
y: i16,
|
||||
}
|
||||
|
||||
impl MCPosition {
|
||||
|
||||
// fn get_position
|
||||
pub fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||
let pos = get_long(data)?;
|
||||
Ok(MCPosition {
|
||||
x: (pos >> 38) as i32,
|
||||
z: (pos << 26 >> 38) as i32,
|
||||
y: (pos << 52 >> 52) as i16,
|
||||
})
|
||||
}
|
||||
// fn convert_position
|
||||
pub fn convert(&self) -> Vec<u8> {
|
||||
let pos: u64 =
|
||||
((self.x as u64 & 0x3FFFFFF) << 38) |
|
||||
((self.z as u64 & 0x3FFFFFF) << 12) |
|
||||
(self.y as u64 & 0xFFF);
|
||||
convert_long(pos as i64)
|
||||
}
|
||||
|
||||
// fn get_position
|
||||
pub fn get_position(data: &mut Vec<u8>) -> Result<MCPosition> {
|
||||
let pos = get_long(data)?;
|
||||
Ok(MCPosition {
|
||||
x: (pos >> 38) as i32,
|
||||
z: (pos << 26 >> 38) as i32,
|
||||
y: (pos << 52 >> 52) as i16,
|
||||
})
|
||||
}
|
||||
|
||||
// fn get_angle <- u8
|
||||
pub fn get_angle(data: &mut Vec<u8>) -> Result<u8> {
|
||||
get_unsigned_byte(data)
|
||||
}
|
||||
// fn convert_angle <- u8
|
||||
pub fn convert_angle(value: u8) -> Vec<u8> {
|
||||
convert_unsigned_byte(value)
|
||||
// fn convert_position
|
||||
pub fn convert_position(value: MCPosition) -> Vec<u8> {
|
||||
let pos: u64 =
|
||||
((value.x as u64 & 0x3FFFFFF) << 38) |
|
||||
((value.z as u64 & 0x3FFFFFF) << 12) |
|
||||
(value.y as u64 & 0xFFF);
|
||||
convert_long(pos as i64)
|
||||
}
|
||||
|
||||
// fn get_uuid
|
||||
pub fn get_uuid(data: &mut Vec<u8>) -> Result<i128> {
|
||||
if data.len() < std::mem::size_of::<i128>() {
|
||||
pub fn get_uuid(data: &mut Vec<u8>) -> Result<u128> {
|
||||
if data.len() < std::mem::size_of::<u128>() {
|
||||
return Err(Box::new(PacketError::RanOutOfBytes))
|
||||
}
|
||||
Ok(i128::from_be_bytes(
|
||||
data.drain(0..std::mem::size_of::<i128>()).as_slice().try_into()?))
|
||||
Ok(u128::from_be_bytes(
|
||||
data.drain(0..std::mem::size_of::<u128>()).as_slice().try_into()?))
|
||||
}
|
||||
// fn convert_uuid
|
||||
pub fn convert_uuid(value: i128) -> Vec<u8> {
|
||||
pub fn convert_uuid(value: u128) -> Vec<u8> {
|
||||
value.to_be_bytes().to_vec()
|
||||
}
|
||||
|
||||
|
|
|
@ -107,14 +107,14 @@ pub mod clientbound {
|
|||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
payload: mc_types::get_i64(&mut data)
|
||||
payload: mc_types::get_long(&mut data)?
|
||||
})
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
data.append(&mut mc_types::convert_i64(self.payload));
|
||||
data.append(&mut mc_types::convert_long(self.payload));
|
||||
|
||||
data
|
||||
}
|
||||
|
@ -177,14 +177,14 @@ pub mod serverbound {
|
|||
|
||||
fn get(mut data: &mut Vec<u8>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
payload: mc_types::get_i64(&mut data)
|
||||
payload: mc_types::get_long(&mut data)?
|
||||
})
|
||||
}
|
||||
|
||||
fn convert(&self) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
data.append(&mut mc_types::convert_var_int(Self::packet_id()));
|
||||
data.append(&mut mc_types::convert_i64(self.payload));
|
||||
data.append(&mut mc_types::convert_long(self.payload));
|
||||
|
||||
data
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue