Add field custom encoder decoder support
This commit is contained in:
parent
0a0500239b
commit
61fff6fcf7
@ -5,6 +5,7 @@ use proc_macro2::Ident;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::{quote, TokenStreamExt};
|
||||
use std::iter::FromIterator;
|
||||
use syn::export::Span;
|
||||
use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, Lit, Meta, NestedMeta};
|
||||
|
||||
#[proc_macro_derive(Packet, attributes(packet))]
|
||||
@ -34,11 +35,22 @@ fn impl_encoder_trait(name: &Ident, fields: &Fields) -> TokenStream2 {
|
||||
let name = &field.ident;
|
||||
|
||||
let unparsed_meta = get_packet_field_meta(field);
|
||||
let parsed_meta = parse_field_meta(&unparsed_meta);
|
||||
let parsed_meta = parse_packet_field_meta(&unparsed_meta);
|
||||
|
||||
match parsed_meta.module {
|
||||
Some(module) => {
|
||||
let module_ident = Ident::new(&module, Span::call_site());
|
||||
|
||||
quote! {
|
||||
crate::#module_ident::encode(&self.#name, writer)?;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
quote! {
|
||||
crate::Encoder::encode(&self.#name, writer)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
@ -76,7 +88,7 @@ struct PacketFieldMeta {
|
||||
max_length: Option<u16>,
|
||||
}
|
||||
|
||||
fn parse_field_meta(meta_list: &Vec<NestedMeta>) -> PacketFieldMeta {
|
||||
fn parse_packet_field_meta(meta_list: &Vec<NestedMeta>) -> PacketFieldMeta {
|
||||
let mut module = None;
|
||||
let mut max_length = None;
|
||||
|
||||
|
@ -8,9 +8,6 @@ use minecraft_protocol_derive::Packet;
|
||||
use nbt::CompoundTag;
|
||||
use std::io::Read;
|
||||
|
||||
const SERVER_BOUND_CHAT_MESSAGE_MAX_LENGTH: u32 = 256;
|
||||
const LEVEL_TYPE_MAX_LENGTH: u32 = 16;
|
||||
|
||||
pub enum GameServerBoundPacket {
|
||||
ServerBoundChatMessage(ServerBoundChatMessage),
|
||||
ServerBoundKeepAlive(ServerBoundKeepAlive),
|
||||
@ -87,6 +84,7 @@ impl GameClientBoundPacket {
|
||||
|
||||
#[derive(Packet, Debug)]
|
||||
pub struct ServerBoundChatMessage {
|
||||
#[packet(max_length = 256)]
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
@ -127,8 +125,10 @@ pub struct JoinGame {
|
||||
pub game_mode: GameMode,
|
||||
pub dimension: i32,
|
||||
pub max_players: u8,
|
||||
#[packet(max_length = 16)]
|
||||
pub level_type: String,
|
||||
pub view_distance: u8,
|
||||
#[packet(with = "var_int")]
|
||||
pub view_distance: i32,
|
||||
pub reduced_debug_info: bool,
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ impl JoinGame {
|
||||
dimension: i32,
|
||||
max_players: u8,
|
||||
level_type: String,
|
||||
view_distance: u8,
|
||||
view_distance: i32,
|
||||
reduced_debug_info: bool,
|
||||
) -> GameClientBoundPacket {
|
||||
let join_game = JoinGame {
|
||||
@ -198,6 +198,7 @@ pub struct ChunkData {
|
||||
pub x: i32,
|
||||
pub z: i32,
|
||||
pub full: bool,
|
||||
#[packet(with = "var_int")]
|
||||
pub primary_mask: i32,
|
||||
pub heights: CompoundTag,
|
||||
pub data: Vec<u8>,
|
||||
|
@ -24,8 +24,9 @@ pub mod status;
|
||||
|
||||
/// Current supported protocol version.
|
||||
pub const PROTOCOL_VERSION: u32 = 498;
|
||||
/// String maximum length.
|
||||
/// Protocol limits maximum string length.
|
||||
const STRING_MAX_LENGTH: u32 = 32_768;
|
||||
const HYPHENATED_UUID_LENGTH: u32 = 36;
|
||||
|
||||
/// Possible errors while encoding packet.
|
||||
#[derive(Debug)]
|
||||
@ -477,3 +478,76 @@ macro_rules! impl_json_encoder_decoder (
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
mod var_int {
|
||||
use crate::{DecodeError, EncodeError, Encoder};
|
||||
use mc_varint::{VarIntRead, VarIntWrite};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
pub fn encode<W: Write>(value: &i32, writer: &mut W) -> Result<(), EncodeError> {
|
||||
writer.write_var_i32(*value)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode<R: Read>(reader: &mut R) -> Result<i32, DecodeError> {
|
||||
Ok(reader.read_var_i32()?)
|
||||
}
|
||||
}
|
||||
|
||||
mod var_long {
|
||||
use crate::{DecodeError, EncodeError, Encoder};
|
||||
use mc_varint::{VarIntRead, VarIntWrite};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
pub fn encode<W: Write>(value: &i64, writer: &mut W) -> Result<(), EncodeError> {
|
||||
writer.write_var_i64(*value)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode<R: Read>(reader: &mut R) -> Result<i64, DecodeError> {
|
||||
Ok(reader.read_var_i64()?)
|
||||
}
|
||||
}
|
||||
|
||||
mod rest {
|
||||
use crate::{DecodeError, Decoder, EncodeError, Encoder};
|
||||
use std::io::{Read, Write};
|
||||
|
||||
pub fn encode<W: Write>(value: &[u8], writer: &mut W) -> Result<(), EncodeError> {
|
||||
writer.write_all(value)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode<R: Read>(reader: &mut R) -> Result<Vec<u8>, DecodeError> {
|
||||
let mut data = Vec::new();
|
||||
reader.read_to_end(data.as_mut())?;
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
mod uuid_hyp_str {
|
||||
use crate::{
|
||||
DecodeError, Decoder, DecoderReadExt, EncodeError, Encoder, EncoderWriteExt,
|
||||
HYPHENATED_UUID_LENGTH,
|
||||
};
|
||||
use std::io::{Read, Write};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn encode<W: Write>(value: &Uuid, writer: &mut W) -> Result<(), EncodeError> {
|
||||
let uuid_hyphenated_string = value.to_hyphenated().to_string();
|
||||
writer.write_string(&uuid_hyphenated_string, HYPHENATED_UUID_LENGTH)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decode<R: Read>(reader: &mut R) -> Result<Uuid, DecodeError> {
|
||||
let uuid_hyphenated_string = reader.read_string(HYPHENATED_UUID_LENGTH)?;
|
||||
let uuid = Uuid::parse_str(&uuid_hyphenated_string)?;
|
||||
|
||||
Ok(uuid)
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,6 @@ use uuid::Uuid;
|
||||
|
||||
use minecraft_protocol_derive::Packet;
|
||||
|
||||
const LOGIN_MAX_LENGTH: u32 = 16;
|
||||
const SERVER_ID_MAX_LENGTH: u32 = 20;
|
||||
const HYPHENATED_UUID_LENGTH: u32 = 36;
|
||||
|
||||
pub enum LoginServerBoundPacket {
|
||||
LoginStart(LoginStart),
|
||||
EncryptionResponse(EncryptionResponse),
|
||||
@ -138,8 +134,10 @@ impl EncryptionResponse {
|
||||
|
||||
#[derive(Packet, Debug)]
|
||||
pub struct LoginPluginResponse {
|
||||
#[packet(with = "var_int")]
|
||||
pub message_id: i32,
|
||||
pub successful: bool,
|
||||
#[packet(with = "rest")]
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
@ -194,7 +192,9 @@ impl EncryptionRequest {
|
||||
|
||||
#[derive(Packet, Debug)]
|
||||
pub struct LoginSuccess {
|
||||
#[packet(with = "uuid_hyp_str")]
|
||||
pub uuid: Uuid,
|
||||
#[packet(max_length = 16)]
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ impl LoginSuccess {
|
||||
|
||||
#[derive(Packet, Debug)]
|
||||
pub struct SetCompression {
|
||||
#[packet(with = "varint")]
|
||||
#[packet(with = "var_int")]
|
||||
pub threshold: i32,
|
||||
}
|
||||
|
||||
@ -222,8 +222,10 @@ impl SetCompression {
|
||||
|
||||
#[derive(Packet, Debug)]
|
||||
pub struct LoginPluginRequest {
|
||||
#[packet(with = "var_int")]
|
||||
pub message_id: i32,
|
||||
pub channel: String,
|
||||
#[packet(with = "rest")]
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user