mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 06:16:04 +00:00
start adding declare_state_packets
This commit is contained in:
parent
747bfa568c
commit
f60426cd5a
2 changed files with 201 additions and 73 deletions
|
@ -1,10 +1,14 @@
|
|||
use quote::{quote, ToTokens};
|
||||
use syn::{self, parse_macro_input, DeriveInput, FieldsNamed};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
fn as_packet_derive(
|
||||
input: proc_macro::TokenStream,
|
||||
state: proc_macro2::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{
|
||||
self, braced,
|
||||
parse::{Parse, ParseStream, Result},
|
||||
parse_macro_input, DeriveInput, Expr, FieldsNamed, Ident, LitInt, Token, Type, Visibility,
|
||||
};
|
||||
|
||||
fn as_packet_derive(input: TokenStream, state: proc_macro2::TokenStream) -> TokenStream {
|
||||
let DeriveInput { ident, data, .. } = parse_macro_input!(input);
|
||||
|
||||
let fields = match data {
|
||||
|
@ -99,21 +103,132 @@ fn as_packet_derive(
|
|||
}
|
||||
|
||||
#[proc_macro_derive(GamePacket, attributes(varint))]
|
||||
pub fn derive_game_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn derive_game_packet(input: TokenStream) -> TokenStream {
|
||||
as_packet_derive(input, quote! {crate::packets::game::GamePacket})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(HandshakePacket, attributes(varint))]
|
||||
pub fn derive_handshake_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn derive_handshake_packet(input: TokenStream) -> TokenStream {
|
||||
as_packet_derive(input, quote! {crate::packets::handshake::HandshakePacket})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(LoginPacket, attributes(varint))]
|
||||
pub fn derive_login_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn derive_login_packet(input: TokenStream) -> TokenStream {
|
||||
as_packet_derive(input, quote! {crate::packets::login::LoginPacket})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(StatusPacket, attributes(varint))]
|
||||
pub fn derive_status_packet(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
pub fn derive_status_packet(input: TokenStream) -> TokenStream {
|
||||
as_packet_derive(input, quote! {crate::packets::status::StatusPacket})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PacketIdPair {
|
||||
id: u32,
|
||||
module: Ident,
|
||||
name: Ident,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
struct PacketIdMap {
|
||||
packets: Vec<PacketIdPair>,
|
||||
}
|
||||
|
||||
impl Parse for PacketIdMap {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let mut packets = vec![];
|
||||
loop {
|
||||
// 0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket,
|
||||
// 0x0e
|
||||
let packet_id: LitInt = match input.parse() {
|
||||
Ok(i) => i,
|
||||
Err(_) => break,
|
||||
};
|
||||
let packet_id = packet_id.base10_parse::<u32>()?;
|
||||
// :
|
||||
input.parse::<Token![:]>()?;
|
||||
// clientbound_change_difficulty_packet
|
||||
let module: Ident = input.parse()?;
|
||||
// ::
|
||||
input.parse::<Token![::]>()?;
|
||||
// ClientboundChangeDifficultyPacket
|
||||
let name: Ident = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
packets.push(PacketIdPair {
|
||||
id: packet_id,
|
||||
module,
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(PacketIdMap { packets })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DeclareStatePackets {
|
||||
name: Ident,
|
||||
serverbound: PacketIdMap,
|
||||
clientbound: PacketIdMap,
|
||||
}
|
||||
|
||||
impl Parse for DeclareStatePackets {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let name = input.parse()?;
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
let serverbound_token: Ident = input.parse()?;
|
||||
if serverbound_token != "Serverbound" {
|
||||
return Err(syn::Error::new(
|
||||
serverbound_token.span(),
|
||||
"Expected `Serverbound`",
|
||||
));
|
||||
}
|
||||
input.parse::<Token![=>]>()?;
|
||||
let content;
|
||||
braced!(content in input);
|
||||
let serverbound = content.parse()?;
|
||||
|
||||
input.parse::<Token![,]>()?;
|
||||
|
||||
let clientbound_token: Ident = input.parse()?;
|
||||
if clientbound_token != "Clientbound" {
|
||||
return Err(syn::Error::new(
|
||||
clientbound_token.span(),
|
||||
"Expected `Clientbound`",
|
||||
));
|
||||
}
|
||||
input.parse::<Token![=>]>()?;
|
||||
let content;
|
||||
braced!(content in input);
|
||||
let clientbound = content.parse()?;
|
||||
|
||||
Ok(DeclareStatePackets {
|
||||
name,
|
||||
serverbound,
|
||||
clientbound,
|
||||
})
|
||||
}
|
||||
}
|
||||
#[proc_macro]
|
||||
pub fn declare_state_packets(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeclareStatePackets);
|
||||
|
||||
let name = input.name;
|
||||
|
||||
let mut enum_contents = quote!();
|
||||
for PacketIdPair { id, module, name } in input.serverbound.packets {
|
||||
enum_contents.extend(quote! {#name(#module::#name)});
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum #name
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
#enum_contents
|
||||
}
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -6,70 +6,83 @@ pub mod clientbound_update_view_distance_packet;
|
|||
use super::ProtocolPacket;
|
||||
use crate::connect::PacketFlow;
|
||||
use async_trait::async_trait;
|
||||
use packet_macros::declare_state_packets;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum GamePacket
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
ClientboundLoginPacket(clientbound_login_packet::ClientboundLoginPacket),
|
||||
ClientboundUpdateViewDistancePacket(
|
||||
clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket,
|
||||
),
|
||||
ClientboundCustomPayloadPacket(
|
||||
clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
|
||||
),
|
||||
ClientboundChangeDifficultyPacket(
|
||||
clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket,
|
||||
),
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ProtocolPacket for GamePacket {
|
||||
fn id(&self) -> u32 {
|
||||
match self {
|
||||
GamePacket::ClientboundChangeDifficultyPacket(_packet) => 0x0e,
|
||||
GamePacket::ClientboundCustomPayloadPacket(_packet) => 0x18,
|
||||
GamePacket::ClientboundLoginPacket(_packet) => 0x26,
|
||||
GamePacket::ClientboundUpdateViewDistancePacket(_packet) => 0x4a,
|
||||
}
|
||||
declare_state_packets!(
|
||||
GamePacket,
|
||||
// no serverbound packets implemented yet
|
||||
Serverbound => {},
|
||||
Clientbound => {
|
||||
0x0e: clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket,
|
||||
0x18: clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
|
||||
0x26: clientbound_login_packet::ClientboundLoginPacket,
|
||||
0x4a: clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket,
|
||||
}
|
||||
);
|
||||
|
||||
fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
|
||||
match self {
|
||||
GamePacket::ClientboundChangeDifficultyPacket(packet) => packet.write(buf),
|
||||
GamePacket::ClientboundCustomPayloadPacket(packet) => packet.write(buf),
|
||||
GamePacket::ClientboundLoginPacket(packet) => packet.write(buf),
|
||||
GamePacket::ClientboundUpdateViewDistancePacket(packet) => packet.write(buf),
|
||||
}
|
||||
}
|
||||
// #[derive(Clone, Debug)]
|
||||
// pub enum GamePacket
|
||||
// where
|
||||
// Self: Sized,
|
||||
// {
|
||||
// ClientboundLoginPacket(clientbound_login_packet::ClientboundLoginPacket),
|
||||
// ClientboundUpdateViewDistancePacket(
|
||||
// clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket,
|
||||
// ),
|
||||
// ClientboundCustomPayloadPacket(
|
||||
// clientbound_custom_payload_packet::ClientboundCustomPayloadPacket,
|
||||
// ),
|
||||
// ClientboundChangeDifficultyPacket(
|
||||
// clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket,
|
||||
// ),
|
||||
// }
|
||||
|
||||
/// Read a packet by its id, ConnectionProtocol, and flow
|
||||
async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
|
||||
id: u32,
|
||||
flow: &PacketFlow,
|
||||
buf: &mut T,
|
||||
) -> Result<GamePacket, String>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Ok(match flow {
|
||||
PacketFlow::ServerToClient => match id {
|
||||
0x0e => clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket
|
||||
::read(buf)
|
||||
.await?,
|
||||
0x18 => clientbound_custom_payload_packet::ClientboundCustomPayloadPacket::read(buf).await?,
|
||||
0x26 => clientbound_login_packet::ClientboundLoginPacket::read(buf).await?,
|
||||
0x4a => clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket
|
||||
::read(buf)
|
||||
.await?,
|
||||
// _ => return Err(format!("Unknown ServerToClient game packet id: {}", id)),
|
||||
_ => panic!("Unknown ServerToClient game packet id: {}", id),
|
||||
},
|
||||
PacketFlow::ClientToServer => match id {
|
||||
// 0x00 => serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
|
||||
_ => return Err(format!("Unknown ClientToServer game packet id: {}", id)),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
// #[async_trait]
|
||||
// impl ProtocolPacket for GamePacket {
|
||||
// fn id(&self) -> u32 {
|
||||
// match self {
|
||||
// GamePacket::ClientboundChangeDifficultyPacket(_packet) => 0x0e,
|
||||
// GamePacket::ClientboundCustomPayloadPacket(_packet) => 0x18,
|
||||
// GamePacket::ClientboundLoginPacket(_packet) => 0x26,
|
||||
// GamePacket::ClientboundUpdateViewDistancePacket(_packet) => 0x4a,
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn write(&self, buf: &mut Vec<u8>) -> Result<(), std::io::Error> {
|
||||
// match self {
|
||||
// GamePacket::ClientboundChangeDifficultyPacket(packet) => packet.write(buf),
|
||||
// GamePacket::ClientboundCustomPayloadPacket(packet) => packet.write(buf),
|
||||
// GamePacket::ClientboundLoginPacket(packet) => packet.write(buf),
|
||||
// GamePacket::ClientboundUpdateViewDistancePacket(packet) => packet.write(buf),
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// Read a packet by its id, ConnectionProtocol, and flow
|
||||
// async fn read<T: tokio::io::AsyncRead + std::marker::Unpin + std::marker::Send>(
|
||||
// id: u32,
|
||||
// flow: &PacketFlow,
|
||||
// buf: &mut T,
|
||||
// ) -> Result<GamePacket, String>
|
||||
// where
|
||||
// Self: Sized,
|
||||
// {
|
||||
// Ok(match flow {
|
||||
// PacketFlow::ServerToClient => match id {
|
||||
// 0x0e => clientbound_change_difficulty_packet::ClientboundChangeDifficultyPacket
|
||||
// ::read(buf)
|
||||
// .await?,
|
||||
// 0x18 => clientbound_custom_payload_packet::ClientboundCustomPayloadPacket::read(buf).await?,
|
||||
// 0x26 => clientbound_login_packet::ClientboundLoginPacket::read(buf).await?,
|
||||
// 0x4a => clientbound_update_view_distance_packet::ClientboundUpdateViewDistancePacket
|
||||
// ::read(buf)
|
||||
// .await?,
|
||||
// // _ => return Err(format!("Unknown ServerToClient game packet id: {}", id)),
|
||||
// _ => panic!("Unknown ServerToClient game packet id: {}", id),
|
||||
// },
|
||||
// PacketFlow::ClientToServer => match id {
|
||||
// // 0x00 => serverbound_hello_packet::ServerboundHelloPacket::read(buf).await?,
|
||||
// _ => return Err(format!("Unknown ClientToServer game packet id: {}", id)),
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
|
Loading…
Add table
Reference in a new issue