WIP list field

This commit is contained in:
Vladislavs Golubs 2021-02-09 13:05:08 +03:00
parent 2d9b9dd94f
commit b043dbb07b
4 changed files with 86 additions and 43 deletions

View File

@ -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<M: Mappings>(
}
}
fn get_packet_ids(packets: &backend::Packets) -> HashMap<String, u8> {
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<M: Mappings>(
mappings: &M,
protocol: &backend::Protocol,
@ -65,7 +96,7 @@ fn transform_packets<M: Mappings>(
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<M: Mappings>(
}
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<M: Mappings>(
output_packets
}
fn get_packet_ids(packets: &backend::Packets) -> HashMap<String, u8> {
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<frontend::Field> {
fn transform_value_field(
unformatted_field_name: &str,
data: &backend::Data,
) -> Option<frontend::Field> {
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<backend::Data>,
) -> Option<frontend::Field> {
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<frontend::DataType> {
match name {
"bool" => Some(frontend::DataType::Boolean),
@ -165,7 +190,6 @@ fn transform_data_type(name: &str) -> Option<frontend::DataType> {
"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<frontend::DataType> {
"tags" => Some(frontend::DataType::RefType {
ref_name: "TagsMap".to_string(),
}),
"option" => None,
_ => {
println!("Unknown data type \"{}\"", name);
None

View File

@ -42,3 +42,6 @@ pub struct Metadata {}
#[derive(Debug)]
pub struct TagsMap {}
#[derive(Debug)]
pub struct ParticleData {}

View File

@ -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<W: Write>(&self, writer: &mut W) -> Result<(), EncodeError> {
unimplemented!()
}
}
impl Decoder for ParticleData {
type Output = Self;
fn decode<R: Read>(reader: &mut R) -> Result<Self::Output, DecodeError> {
unimplemented!()
}
}
mod var_int {
use std::io::{Read, Write};

View File

@ -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)]