Replaced `PacketArray` trait with `McType` macro
This commit is contained in:
parent
90f2270c78
commit
17c7360c76
|
|
@ -107,3 +107,51 @@ pub fn derive_packet(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
expanded.into()
|
expanded.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(McType)]
|
||||||
|
pub fn derive_mctype_struct(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
let name = &input.ident;
|
||||||
|
|
||||||
|
let Data::Struct(data_struct) = input.data else {
|
||||||
|
return syn::Error::new_spanned(name, "McType can only be derived for structs")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
};
|
||||||
|
|
||||||
|
let Fields::Named(fields) = data_struct.fields else {
|
||||||
|
return syn::Error::new_spanned(name, "McType requires named fields")
|
||||||
|
.to_compile_error()
|
||||||
|
.into();
|
||||||
|
};
|
||||||
|
|
||||||
|
// build field accessors
|
||||||
|
let read_fields = fields.named.iter().map(|f| {
|
||||||
|
let fname = &f.ident;
|
||||||
|
let fty = &f.ty;
|
||||||
|
quote! { #fname: <#fty as McType>::get(data)? }
|
||||||
|
});
|
||||||
|
|
||||||
|
let write_fields = fields.named.iter().map(|f| {
|
||||||
|
let fname = &f.ident;
|
||||||
|
quote! { out.extend(self.#fname.convert()); }
|
||||||
|
});
|
||||||
|
|
||||||
|
let expanded = quote! {
|
||||||
|
impl McType for #name {
|
||||||
|
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
#(#read_fields),*
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(&self) -> Vec<u8> {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
#(#write_fields)*
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expanded.into()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ 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};
|
||||||
use crate::mc_types::helpers::*;
|
use crate::mc_types::helpers::*;
|
||||||
|
|
||||||
pub const VERSION_NAME: &str = "1.21";
|
pub const VERSION_NAME: &str = "1.21";
|
||||||
|
|
@ -120,7 +120,42 @@ impl McType for String {
|
||||||
fn convert(&self) -> Vec<u8> { convert_string(*self) }
|
fn convert(&self) -> Vec<u8> { convert_string(*self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl McType for Vec<u8> {
|
impl<T: McType> McType for Vec<T> {
|
||||||
fn get(data: &mut Vec<u8>) -> Result<Self> { Ok(get_byte_array(data)) }
|
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||||
fn convert(&self) -> Vec<u8> { convert_byte_array(*self) }
|
let length = get_var_int(data)?;
|
||||||
|
let mut out = Vec::with_capacity(length as usize);
|
||||||
|
for _ in 0..length {
|
||||||
|
out.push(T::get(data)?);
|
||||||
|
}
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(&self) -> Vec<u8> {
|
||||||
|
let mut data = convert_var_int(self.len() as i32);
|
||||||
|
for el in self {
|
||||||
|
data.extend(el.convert());
|
||||||
|
}
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: McType> McType for Option<T> {
|
||||||
|
fn get(data: &mut Vec<u8>) -> Result<Self> {
|
||||||
|
if get_bool(data) {
|
||||||
|
Ok(Some(T::get(data)?))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert(&self) -> Vec<u8> {
|
||||||
|
match self {
|
||||||
|
Some(v) => {
|
||||||
|
let mut data = convert_bool(true);
|
||||||
|
data.extend(v.convert());
|
||||||
|
data
|
||||||
|
}
|
||||||
|
None => convert_bool(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -242,16 +242,3 @@ pub fn convert_string(s: &str) -> Vec<u8> {
|
||||||
data.append(&mut s.as_bytes().to_vec());
|
data.append(&mut s.as_bytes().to_vec());
|
||||||
data
|
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -30,26 +30,3 @@ pub trait Packet: Sized {
|
||||||
conn.write_data(&mut self.convert()).await
|
conn.write_data(&mut self.convert()).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PacketArray: Sized {
|
|
||||||
fn get(data: &mut Vec<u8>) -> Result<Self>;
|
|
||||||
fn convert(&self) -> Vec<u8>;
|
|
||||||
|
|
||||||
fn get_array(data: &mut Vec<u8>) -> Result<Vec<Self>> {
|
|
||||||
let length = get_var_int(data)?;
|
|
||||||
let mut out_data: Vec<Self> = vec![];
|
|
||||||
for _ in 0..length {
|
|
||||||
out_data.push(Self::get(data)?);
|
|
||||||
}
|
|
||||||
Ok(out_data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_array(array: &mut Vec<Self>) -> Vec<u8> {
|
|
||||||
let length = array.len() as i32;
|
|
||||||
let mut data: Vec<u8> = convert_var_int(length);
|
|
||||||
for element in array {
|
|
||||||
data.append(&mut Self::convert(element));
|
|
||||||
}
|
|
||||||
data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue