diff --git a/protocol-generator/src/transformers.rs b/protocol-generator/src/transformers.rs index 20cb518..155bb8e 100644 --- a/protocol-generator/src/transformers.rs +++ b/protocol-generator/src/transformers.rs @@ -1,3 +1,4 @@ +use crate::backend::Data; use crate::mappings::Mappings; use crate::{backend, frontend}; use heck::{CamelCase, SnakeCase}; @@ -29,6 +30,36 @@ pub fn transform_protocol( } } +fn get_packet_ids(packets: &backend::Packets) -> HashMap { + let reversed_packet_ids = packets + .types + .get("packet") + .and_then(|d| d.get(1)) + .and_then(|d| match d { + backend::Data::Container(data) => data.get(0), + _ => None, + }) + .and_then(|c| match c { + backend::Container::List { data_vec, .. } => data_vec.get(1), + _ => None, + }) + .and_then(|d| match d { + backend::Data::Mapper { mappings, .. } => Some(mappings), + _ => None, + }) + .expect("Failed to get packet ids"); + + reversed_packet_ids + .into_iter() + .map(|(k, v)| { + ( + v.clone(), + u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), + ) + }) + .collect() +} + fn transform_packets( mappings: &M, protocol: &backend::Protocol, @@ -65,7 +96,7 @@ fn transform_packets( for container in container_vec { match container { backend::Container::Value { name, data } => { - match transform_field(&name, &data) { + match transform_value_field(&name, &data) { Some(field) => { fields.push(mappings.change_field_type(&packet_name, field)) } @@ -77,15 +108,11 @@ fn transform_packets( } backend::Container::List { name, data_vec } => { if let Some(name) = name { - for data in data_vec { - match transform_field(&name, &data) { - Some(field) => fields - .push(mappings.change_field_type(&packet_name, field)), - None => println!( - "[{}] Field \"{}\" are skipped ({:?})", - packet_name, name, data_vec - ), + match transform_list_field(&name, data_vec) { + Some(field) => { + fields.push(mappings.change_field_type(&packet_name, field)) } + None => {} } } } @@ -106,37 +133,10 @@ fn transform_packets( output_packets } -fn get_packet_ids(packets: &backend::Packets) -> HashMap { - let reversed_packet_ids = packets - .types - .get("packet") - .and_then(|d| d.get(1)) - .and_then(|d| match d { - backend::Data::Container(data) => data.get(0), - _ => None, - }) - .and_then(|c| match c { - backend::Container::List { data_vec, .. } => data_vec.get(1), - _ => None, - }) - .and_then(|d| match d { - backend::Data::Mapper { mappings, .. } => Some(mappings), - _ => None, - }) - .expect("Failed to get packet ids"); - - reversed_packet_ids - .into_iter() - .map(|(k, v)| { - ( - v.clone(), - u8::from_str_radix(k.trim_start_matches("0x"), 16).expect("Invalid packet id"), - ) - }) - .collect() -} - -fn transform_field(unformatted_field_name: &str, data: &backend::Data) -> Option { +fn transform_value_field( + unformatted_field_name: &str, + data: &backend::Data, +) -> Option { match data { backend::Data::Type(name) => match transform_data_type(name) { Some(data_type) => Some(frontend::Field { @@ -149,6 +149,31 @@ fn transform_field(unformatted_field_name: &str, data: &backend::Data) -> Option } } +fn transform_list_field( + unformatted_field_name: &str, + data_vec: &Vec, +) -> Option { + match &data_vec[0] { + backend::Data::Type(name) => match name.as_ref() { + "buffer" => Some(frontend::Field { + name: format_field_name(unformatted_field_name), + data_type: frontend::DataType::ByteArray { rest: false }, + }), + "array" => None, + "switch" => None, + "particleData" => Some(frontend::Field { + name: format_field_name(unformatted_field_name), + data_type: frontend::DataType::RefType { + ref_name: "ParticleData".to_string(), + }, + }), + "option" => transform_value_field(unformatted_field_name, &data_vec[1]), + _ => None, + }, + _ => None, + } +} + fn transform_data_type(name: &str) -> Option { match name { "bool" => Some(frontend::DataType::Boolean), @@ -165,7 +190,6 @@ fn transform_data_type(name: &str) -> Option { "string" => Some(frontend::DataType::String { max_length: 0 }), "nbt" | "optionalNbt" => Some(frontend::DataType::CompoundTag), "UUID" => Some(frontend::DataType::Uuid { hyphenated: false }), - "buffer" => Some(frontend::DataType::ByteArray { rest: false }), "restBuffer" => Some(frontend::DataType::ByteArray { rest: true }), "position" => Some(frontend::DataType::RefType { ref_name: "Position".to_string(), @@ -179,7 +203,6 @@ fn transform_data_type(name: &str) -> Option { "tags" => Some(frontend::DataType::RefType { ref_name: "TagsMap".to_string(), }), - "option" => None, _ => { println!("Unknown data type \"{}\"", name); None diff --git a/protocol/src/data/game.rs b/protocol/src/data/game.rs index cf94310..fdc6860 100644 --- a/protocol/src/data/game.rs +++ b/protocol/src/data/game.rs @@ -42,3 +42,6 @@ pub struct Metadata {} #[derive(Debug)] pub struct TagsMap {} + +#[derive(Debug)] +pub struct ParticleData {} diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index cb858c1..9c3adbd 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -10,7 +10,7 @@ use uuid::Uuid; use data::chat::Message; -use crate::data::game::{Metadata, Position, Slot, TagsMap}; +use crate::data::game::{Metadata, ParticleData, Position, Slot, TagsMap}; use crate::error::{DecodeError, EncodeError}; pub mod data; @@ -613,6 +613,20 @@ impl Decoder for TagsMap { } } +impl Encoder for ParticleData { + fn encode(&self, writer: &mut W) -> Result<(), EncodeError> { + unimplemented!() + } +} + +impl Decoder for ParticleData { + type Output = Self; + + fn decode(reader: &mut R) -> Result { + unimplemented!() + } +} + mod var_int { use std::io::{Read, Write}; diff --git a/protocol/src/packet/game.rs b/protocol/src/packet/game.rs index 290aea1..cb6dc25 100644 --- a/protocol/src/packet/game.rs +++ b/protocol/src/packet/game.rs @@ -1908,6 +1908,7 @@ impl GameClientBoundPacket { offset_z: f32, particle_data: f32, particles: i32, + data: ParticleData, ) -> Self { let world_particles = WorldParticles { particle_id, @@ -1920,6 +1921,7 @@ impl GameClientBoundPacket { offset_z, particle_data, particles, + data, }; Self::WorldParticles(world_particles) @@ -3157,6 +3159,7 @@ pub struct WorldParticles { pub offset_z: f32, pub particle_data: f32, pub particles: i32, + pub data: ParticleData, } #[derive(Packet, Debug)]