remove old pso_packet
This commit is contained in:
parent
04322d2526
commit
60584e0957
@ -6,11 +6,9 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{parse_macro_input, ItemStruct, Meta, NestedMeta, Attribute};
|
||||
use syn::{parse_macro_input, ItemStruct, NestedMeta};
|
||||
use quote::quote;
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum AttrMeta {
|
||||
None,
|
||||
@ -19,8 +17,6 @@ enum AttrMeta {
|
||||
NoDebug,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
enum AttrType {
|
||||
Value(syn::PathSegment, syn::Ident, AttrMeta),
|
||||
@ -285,7 +281,7 @@ fn generate_partialeq_impl(name: syn::Ident, attrs: &Vec<AttrType>) -> proc_macr
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pso_packet2(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as syn::AttributeArgs);
|
||||
let mut cmd = 0;
|
||||
let mut flag = true;
|
||||
@ -366,328 +362,3 @@ pub fn pso_packet2(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
q.into()
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn pso_packet(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let arg = parse_macro_input!(attr as syn::LitInt);
|
||||
let pkt_cmd = arg.base10_parse::<u16>().unwrap();
|
||||
|
||||
let parsed = parse_macro_input!(item as ItemStruct);
|
||||
|
||||
let mut from_bytes = Vec::new();
|
||||
let mut as_bytes = Vec::new();
|
||||
let mut dbg_write_vars = Vec::new();
|
||||
let mut partialeq = Vec::new();
|
||||
|
||||
for f in parsed.fields.iter() {
|
||||
if let Some(ident) = &f.ident {
|
||||
let ident_str = ident.to_string();
|
||||
|
||||
match &f.ty {
|
||||
syn::Type::Array(arr) => {
|
||||
let array_length = if let syn::Expr::Lit(lit) = &arr.len {
|
||||
if let syn::Lit::Int(int) = &lit.lit {
|
||||
int.base10_parse::<usize>().unwrap()
|
||||
}
|
||||
else {
|
||||
return syn::Error::new(arr.bracket_token.span, "unknown array size").to_compile_error().into();
|
||||
}
|
||||
} else {
|
||||
return syn::Error::new(arr.bracket_token.span, "unknown array size").to_compile_error().into();
|
||||
};
|
||||
match *arr.elem {
|
||||
syn::Type::Path(ref path) => {
|
||||
let ty = path.path.segments[0].ident.to_string();
|
||||
if ty.as_str() == "u8_str" {
|
||||
dbg_write_vars.push(quote! {
|
||||
match std::str::from_utf8(&self.#ident) {
|
||||
Ok(v) => write!(f, " {}: {:?}\n", #ident_str, v).unwrap(),
|
||||
Err(_) => write!(f, " {}: {:?}\n", #ident_str, self.#ident.to_vec()).unwrap()
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
dbg_write_vars.push(quote! {
|
||||
write!(f, " {}: {:?}\n", #ident_str, self.#ident.to_vec()).unwrap();
|
||||
});
|
||||
}
|
||||
as_bytes.push(quote! {
|
||||
for f in self.#ident.iter() {
|
||||
buf.extend_from_slice(&f.to_le_bytes())
|
||||
}
|
||||
});
|
||||
match ty.as_str() {
|
||||
"u8" | "u8_str" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u8; #array_length] = [0; #array_length];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != #array_length {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
b
|
||||
},
|
||||
});
|
||||
},
|
||||
"u16" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u16; #array_length] = [0; #array_length];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != #array_length {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
b
|
||||
},
|
||||
});
|
||||
},
|
||||
"u32" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u32; #array_length] = [0; #array_length];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != #array_length {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
b
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
_ => {
|
||||
return syn::Error::new(path.path.segments[0].ident.span(), "type not supported")
|
||||
.to_compile_error().into();
|
||||
}
|
||||
}
|
||||
partialeq.push(quote! {
|
||||
if self.#ident[..] != other.#ident[..] {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
panic!("why");
|
||||
}
|
||||
}
|
||||
},
|
||||
syn::Type::Path(path) => {
|
||||
dbg_write_vars.push(quote! {
|
||||
write!(f, " {}: {:?}\n", #ident_str, self.#ident).unwrap();
|
||||
});
|
||||
let ty = path.path.segments[0].ident.to_string();
|
||||
|
||||
// as_bytes
|
||||
match ty.as_str() {
|
||||
"String" => {
|
||||
as_bytes.push(quote! {
|
||||
for c in self.#ident.as_str().encode_utf16() {
|
||||
buf.extend_from_slice(&c.to_le_bytes());
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
as_bytes.push(quote! {
|
||||
buf.extend_from_slice(&self.#ident.to_le_bytes());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// from_bytes
|
||||
match ty.as_str() {
|
||||
"u8" | "u8_str" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u8; 1] = [0; 1];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != 1 {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
b[0]
|
||||
},
|
||||
});
|
||||
},
|
||||
"u16" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u8; 2] = [0; 2];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != 2 {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
u16::from_le_bytes(b)
|
||||
},
|
||||
});
|
||||
},
|
||||
"u32" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u8; 4] = [0; 4];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != 4 {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
u32::from_le_bytes(b)
|
||||
},
|
||||
});
|
||||
},
|
||||
"String" => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut s: Vec<u8> = Vec::new();
|
||||
if let Ok(len) = cur.read_to_end(&mut s) {
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
let mut utf16 = Vec::new();
|
||||
for c in s.chunks(2) {
|
||||
utf16.push(u16::from_le_bytes([c[0], c[1]]));
|
||||
}
|
||||
String::from_utf16_lossy(utf16.as_slice())
|
||||
},
|
||||
});
|
||||
},
|
||||
_ => {
|
||||
from_bytes.push(quote! {
|
||||
#ident: {
|
||||
let mut b: [u8; #path::SIZE] = [0; #path::SIZE];
|
||||
if let Ok(len) = cur.read(&mut b) {
|
||||
if len != #path::SIZE {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Err(PacketParseError::NotEnoughBytes);
|
||||
};
|
||||
#path::from_le_bytes(b)?
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
partialeq.push(quote! {
|
||||
if self.#ident != other.#ident {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let this_struct = parsed.ident.clone();
|
||||
let this_struct_str = this_struct.to_string();
|
||||
|
||||
let psopacket = quote! {
|
||||
impl PSOPacket for #this_struct {
|
||||
fn from_bytes(data: &[u8]) -> Result<#this_struct, PacketParseError> {
|
||||
let mut cur = std::io::Cursor::new(data);
|
||||
let mut b: [u8; 2] = [0; 2];
|
||||
cur.read(&mut b).unwrap();
|
||||
let len = u16::from_le_bytes(b);
|
||||
cur.read(&mut b).unwrap();
|
||||
let cmd = u16::from_le_bytes(b);
|
||||
|
||||
if cmd != #pkt_cmd {
|
||||
return Err(PacketParseError::WrongPacketCommand);
|
||||
}
|
||||
|
||||
if len as usize != data.len() {
|
||||
return Err(PacketParseError::WrongPacketSize(len, data.len()));
|
||||
}
|
||||
|
||||
let result = Ok(#this_struct {
|
||||
#(#from_bytes)*
|
||||
});
|
||||
|
||||
if cur.position() as usize != data.len() {
|
||||
return Err(PacketParseError::DataStructNotLargeEnough(cur.position(), data.len()));
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
fn as_bytes(&self) -> Vec<u8> {
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
#(#as_bytes)*
|
||||
|
||||
while buf.len() % 4 != 0 {
|
||||
buf.push(0);
|
||||
}
|
||||
|
||||
let pkt_len = (buf.len() + 4) as u16;
|
||||
let mut prebuf: Vec<u8> = Vec::new();
|
||||
|
||||
prebuf.extend_from_slice(&u16::to_le_bytes(pkt_len));
|
||||
prebuf.extend_from_slice(&u16::to_le_bytes(#pkt_cmd));
|
||||
prebuf.append(&mut buf);
|
||||
|
||||
prebuf
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let psopacket_debug = quote! {
|
||||
impl std::fmt::Debug for #this_struct {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "packet {} {{\n", #this_struct_str).unwrap();
|
||||
#(#dbg_write_vars)*
|
||||
write!(f, "}}")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let psopacket_partialeq = quote! {
|
||||
impl std::cmp::PartialEq for #this_struct {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
#(#partialeq)*
|
||||
true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let q = quote! {
|
||||
#[derive(Clone)]
|
||||
#parsed
|
||||
#psopacket
|
||||
#psopacket_debug
|
||||
#psopacket_partialeq
|
||||
};
|
||||
|
||||
//println!("[[[{}]]]", q.to_string());
|
||||
|
||||
q.into()
|
||||
}
|
||||
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn game_command(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
item
|
||||
}
|
||||
|
16
src/lib.rs
16
src/lib.rs
@ -85,11 +85,11 @@ pub trait PSOPacket: std::fmt::Debug {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use psopacket::pso_packet2;
|
||||
use psopacket::pso_packet;
|
||||
|
||||
#[test]
|
||||
fn test_basic_pso_packet() {
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -116,7 +116,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_array_in_packet() {
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -167,7 +167,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -203,7 +203,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_string_in_packet() {
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -230,7 +230,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_vec_in_packet() {
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -256,7 +256,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_no_flag_packet() {
|
||||
#[pso_packet2(0x23, no_flag)]
|
||||
#[pso_packet(0x23, no_flag)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
@ -283,7 +283,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_command_error() {
|
||||
#[pso_packet2(0x23)]
|
||||
#[pso_packet(0x23)]
|
||||
struct Test {
|
||||
a: u32,
|
||||
b: u16,
|
||||
|
@ -1,7 +1,6 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
|
||||
//use psopacket::pso_packet;
|
||||
use psopacket::pso_packet2 as pso_packet;
|
||||
use psopacket::pso_packet;
|
||||
use crate::{PSOPacket, PacketParseError, PSOPacketData};
|
||||
|
||||
use crate::character::character::SelectScreenCharacter;
|
||||
|
@ -1,5 +1,4 @@
|
||||
//use psopacket::pso_packet;
|
||||
use psopacket::pso_packet2 as pso_packet;
|
||||
use psopacket::pso_packet;
|
||||
use crate::{PSOPacket, PacketParseError, PSOPacketData};
|
||||
|
||||
use std::io::Read;
|
||||
|
Loading…
x
Reference in New Issue
Block a user