aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock19
-rw-r--r--minecraft-protocol/Cargo.toml1
-rw-r--r--minecraft-protocol/packet-macros/Cargo.toml13
-rw-r--r--minecraft-protocol/packet-macros/src/lib.rs145
4 files changed, 178 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3847548f..386b173e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,6 +58,15 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -309,6 +318,7 @@ dependencies = [
"byteorder",
"bytes",
"minecraft-chat",
+ "packet-macros",
"serde",
"serde_json",
"thiserror",
@@ -359,6 +369,15 @@ dependencies = [
]
[[package]]
+name = "packet-macros"
+version = "0.1.0"
+dependencies = [
+ "casey",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
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<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
+// id: u32,
+// protocol: &ConnectionProtocol,
+// flow: &PacketFlow,
+// buf: &mut BufReader<T>,
+// ) -> Result<Packet, String> {
+// 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<u8>) {
+// self.get_inner_packet().write(buf);
+// }
+// }
+
+struct RegisterPacket {
+ name: syn::Ident,
+ connection_protocol: syn::Ident,
+ flow: syn::Ident,
+}
+
+struct RegisterPackets {
+ packets: Vec<RegisterPacket>,
+}
+
+impl Parse for RegisterPackets {
+ fn parse(input: ParseStream) -> syn::Result<Self> {
+ let packets = vec![];
+ loop {
+ let name: syn::Ident = input.parse()?;
+
+ input.parse::<syn::Token![=>]>()?;
+
+ let connection_protocol: syn::Ident = input.parse()?;
+ input.parse::<syn::Token![,]>()?;
+ let flow: syn::Ident = input.parse()?;
+
+ input.parse::<syn::Token![;]>()?;
+
+ 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()
+}