From 1286286e836bd9ec8d6df1d1aa13f6f3346d17da Mon Sep 17 00:00:00 2001 From: mat Date: Sun, 12 Dec 2021 13:48:18 -0600 Subject: [PATCH] ok i give up trying to use macros --- Cargo.lock | 19 +++ minecraft-protocol/Cargo.toml | 1 + minecraft-protocol/packet-macros/Cargo.toml | 13 ++ minecraft-protocol/packet-macros/src/lib.rs | 145 ++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 minecraft-protocol/packet-macros/Cargo.toml create mode 100644 minecraft-protocol/packet-macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 3847548f..386b173e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,6 +57,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "casey" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14" +dependencies = [ + "syn", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -309,6 +318,7 @@ dependencies = [ "byteorder", "bytes", "minecraft-chat", + "packet-macros", "serde", "serde_json", "thiserror", @@ -358,6 +368,15 @@ dependencies = [ "libc", ] +[[package]] +name = "packet-macros" +version = "0.1.0" +dependencies = [ + "casey", + "quote", + "syn", +] + [[package]] name = "parking_lot" version = "0.11.2" diff --git a/minecraft-protocol/Cargo.toml b/minecraft-protocol/Cargo.toml index 3cbf663b..2aaffa88 100644 --- a/minecraft-protocol/Cargo.toml +++ b/minecraft-protocol/Cargo.toml @@ -11,6 +11,7 @@ async-trait = "0.1.51" byteorder = "^1.4.3" bytes = "^1.1.0" minecraft-chat = {path = "../minecraft-chat"} +packet-macros = {path = "./packet-macros"} serde = {version = "1.0.130", features = ["serde_derive"]} serde_json = "^1.0.72" thiserror = "^1.0.30" diff --git a/minecraft-protocol/packet-macros/Cargo.toml b/minecraft-protocol/packet-macros/Cargo.toml new file mode 100644 index 00000000..0e7b31bf --- /dev/null +++ b/minecraft-protocol/packet-macros/Cargo.toml @@ -0,0 +1,13 @@ +[package] +edition = "2021" +name = "packet-macros" +version = "0.1.0" + +[lib] +proc-macro = true +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +casey = "^0.3.3" +quote = "^1.0.10" +syn = "^1.0.82" diff --git a/minecraft-protocol/packet-macros/src/lib.rs b/minecraft-protocol/packet-macros/src/lib.rs new file mode 100644 index 00000000..78a8a402 --- /dev/null +++ b/minecraft-protocol/packet-macros/src/lib.rs @@ -0,0 +1,145 @@ +use casey::{pascal, snake}; +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn::{ + self, + parse::{Parse, ParseStream}, + parse_macro_input, DeriveInput, Signature, +}; + +// #[derive(Clone, Debug)] +// pub enum Packet { +// // game + +// // handshake +// ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket), + +// // login + +// // status +// ServerboundStatusRequestPacket( +// status::serverbound_status_request_packet::ServerboundStatusRequestPacket, +// ), +// ClientboundStatusResponsePacket( +// status::clientbound_status_response_packet::ClientboundStatusResponsePacket, +// ), +// } + +// // TODO: do all this with macros so it's less repetitive +// impl Packet { +// fn get_inner_packet(&self) -> &dyn PacketTrait { +// match self { +// Packet::ClientIntentionPacket(packet) => packet, +// Packet::ServerboundStatusRequestPacket(packet) => packet, +// Packet::ClientboundStatusResponsePacket(packet) => packet, +// } +// } + +// pub fn id(&self) -> u32 { +// match self { +// Packet::ClientIntentionPacket(_packet) => 0x00, +// Packet::ServerboundStatusRequestPacket(_packet) => 0x00, +// Packet::ClientboundStatusResponsePacket(_packet) => 0x00, +// } +// } + +// /// Read a packet by its id, ConnectionProtocol, and flow +// pub async fn read( +// id: u32, +// protocol: &ConnectionProtocol, +// flow: &PacketFlow, +// buf: &mut BufReader, +// ) -> Result { +// match protocol { +// ConnectionProtocol::Handshake => match id { +// 0x00 => Ok( +// handshake::client_intention_packet::ClientIntentionPacket::read(buf).await?, +// ), +// _ => Err(format!("Unknown packet id: {}", id)), +// }, +// ConnectionProtocol::Game => Err("Game protocol not implemented yet".to_string()), +// ConnectionProtocol::Status => match flow { +// PacketFlow::ServerToClient => match id { +// 0x00 => Ok( +// status::clientbound_status_response_packet::ClientboundStatusResponsePacket +// ::read(buf) +// .await?, +// ), +// _ => Err(format!("Unknown packet id: {}", id)), +// }, +// PacketFlow::ClientToServer => match id { +// 0x00 => Ok( +// status::serverbound_status_request_packet::ServerboundStatusRequestPacket +// ::read(buf) +// .await?, +// ), +// _ => Err(format!("Unknown packet id: {}", id)), +// }, +// }, +// ConnectionProtocol::Login => Err("Login protocol not implemented yet".to_string()), +// } +// } + +// pub fn write(&self, buf: &mut Vec) { +// self.get_inner_packet().write(buf); +// } +// } + +struct RegisterPacket { + name: syn::Ident, + connection_protocol: syn::Ident, + flow: syn::Ident, +} + +struct RegisterPackets { + packets: Vec, +} + +impl Parse for RegisterPackets { + fn parse(input: ParseStream) -> syn::Result { + let packets = vec![]; + loop { + let name: syn::Ident = input.parse()?; + + input.parse::]>()?; + + let connection_protocol: syn::Ident = input.parse()?; + input.parse::()?; + let flow: syn::Ident = input.parse()?; + + input.parse::()?; + + packets.push(RegisterPacket { + name, + connection_protocol, + flow, + }); + + if input.is_empty() { + break; + } + } + + Ok(RegisterPackets { packets }) + } +} + +#[proc_macro] +pub fn register_packets(input: TokenStream) -> TokenStream { + let RegisterPackets { packets } = syn::parse_macro_input!(input as RegisterPackets); + + // ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket), + let gen = quote! { + // #[derive(Clone, Debug)] + // pub enum Packet { + // // ClientIntentionPacket(handshake::client_intention_packet::ClientIntentionPacket), + // // ClientboundStatusResponsePacket( + // // status::clientbound_status_response_packet::ClientboundStatusResponsePacket, + // // ), + + // } + }; + gen.into() +}