From 87b1e7a250df8f2e473076610ec2aab5665d23fc Mon Sep 17 00:00:00 2001 From: Vladislavs Golubs Date: Sun, 7 Feb 2021 16:46:00 +0300 Subject: [PATCH] Add field data type modification --- protocol-generator/src/data/output.rs | 20 +++++++++----- protocol-generator/src/main.rs | 28 +++++++++++++++----- protocol-generator/templates/packet_enum.hbs | 2 +- protocol/src/packet/status.rs | 5 ++-- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/protocol-generator/src/data/output.rs b/protocol-generator/src/data/output.rs index a5b5680..12d80f5 100644 --- a/protocol-generator/src/data/output.rs +++ b/protocol-generator/src/data/output.rs @@ -3,6 +3,7 @@ use std::collections::HashSet; use std::fmt; use std::fmt::Display; +#[derive(Debug)] pub enum State { Handshake, Status, @@ -13,10 +14,10 @@ pub enum State { impl State { pub fn data_import(&self) -> &str { match self { - State::Handshake => "crate::packet::handshake", - State::Status => "crate::packet::status", - State::Login => "crate::packet::login", - State::Game => "crate::packet::game", + State::Handshake => "crate::data::handshake::*", + State::Status => "crate::data::status::*", + State::Login => "crate::data::login::*", + State::Game => "crate::data::game::*", } } } @@ -50,7 +51,7 @@ impl Display for Bound { } } -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct Packet { pub id: u8, pub name: String, @@ -67,7 +68,7 @@ impl Packet { } } -#[derive(Serialize)] +#[derive(Serialize, Debug)] pub struct Field { pub name: String, #[serde(flatten)] @@ -81,9 +82,13 @@ impl Field { data_type, } } + + pub fn change_type(&self, data_type: DataType) -> Field { + Field::new(&self.name, data_type) + } } -#[derive(Serialize, Eq, PartialEq)] +#[derive(Serialize, Eq, PartialEq, Debug)] #[serde(tag = "type")] pub enum DataType { #[serde(rename(serialize = "bool"))] @@ -137,6 +142,7 @@ impl DataType { } } +#[derive(Debug)] pub struct Protocol { pub state: State, pub server_bound_packets: Vec, diff --git a/protocol-generator/src/main.rs b/protocol-generator/src/main.rs index c09e7be..86dc94b 100644 --- a/protocol-generator/src/main.rs +++ b/protocol-generator/src/main.rs @@ -6,6 +6,7 @@ use heck::{CamelCase, SnakeCase}; use crate::data::input::{Container, Data, ProtocolData, ProtocolState}; use crate::data::output; +use crate::data::output::Field; use serde::Serialize; use serde_json::json; use std::collections::HashMap; @@ -132,7 +133,7 @@ fn transform_protocol_data( let id = *packet_ids .get(no_prefix_name) .expect("Failed to get packet id"); - let name = rename_packet(&no_prefix_name.to_camel_case(), &bound); + let packet_name = rename_packet(&no_prefix_name.to_camel_case(), &bound); let mut fields = vec![]; @@ -142,14 +143,14 @@ fn transform_protocol_data( match container { Container::Value { name, data } => { if let Some(field) = transform_field(name, data) { - fields.push(field); + fields.push(modify_field(&packet_name, field)); } } Container::List { name, data_vec } => { if let Some(name) = name { for data in data_vec { if let Some(field) = transform_field(name, data) { - fields.push(field); + fields.push(modify_field(&packet_name, field)); } } } @@ -159,7 +160,11 @@ fn transform_protocol_data( } } - let packet = output::Packet { id, name, fields }; + let packet = output::Packet { + id, + name: packet_name, + fields, + }; packets.push(packet); } @@ -218,8 +223,8 @@ fn format_field_name(unformatted_field_name: &str) -> String { } } -fn transform_data_type(str_type: &str) -> Option { - match str_type { +fn transform_data_type(name: &str) -> Option { + match name { "bool" => Some(output::DataType::Boolean), "i8" => Some(output::DataType::Byte), "i16" => Some(output::DataType::Short), @@ -237,12 +242,21 @@ fn transform_data_type(str_type: &str) -> Option { "buffer" => Some(output::DataType::ByteArray { rest: false }), "restBuffer" => Some(output::DataType::ByteArray { rest: true }), _ => { - println!("{}", str_type); + println!("Unknown data type \"{}\"", name); None } } } +fn modify_field(packet_name: &str, field: output::Field) -> output::Field { + match (packet_name, field.name.as_str()) { + ("StatusResponse", "response") => field.change_type(output::DataType::RefType { + ref_name: "ServerStatus".to_owned(), + }), + _ => field, + } +} + fn rename_packet(name: &str, bound: &output::Bound) -> String { match (name, bound) { ("EncryptionBegin", output::Bound::Server) => "EncryptionResponse", diff --git a/protocol-generator/templates/packet_enum.hbs b/protocol-generator/templates/packet_enum.hbs index 0b81503..c596a16 100644 --- a/protocol-generator/templates/packet_enum.hbs +++ b/protocol-generator/templates/packet_enum.hbs @@ -32,7 +32,7 @@ impl {{packet_enum_name}} { } } {{#each packets as |p|}} - pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{f.type}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { + pub fn {{snake_case p.name}}({{~#each p.fields as |f|}}{{f.name}}: {{#if (ne f.type "RefType")}}{{f.type}}{{~else}}{{f.ref_name}}{{/if}}{{#unless @last}}, {{/unless}}{{~/each}}) -> Self { {{~#if p.fields}} let {{snake_case p.name}} = {{p.name}} { {{~#each p.fields as |f|}} diff --git a/protocol/src/packet/status.rs b/protocol/src/packet/status.rs index 4beb5be..6392a83 100644 --- a/protocol/src/packet/status.rs +++ b/protocol/src/packet/status.rs @@ -1,5 +1,6 @@ // This file is automatically generated. // It is not intended for manual editing. +use crate::data::status::*; use crate::DecodeError; use crate::Decoder; use minecraft_protocol_derive::Packet; @@ -70,7 +71,7 @@ impl StatusClientBoundPacket { } } - pub fn status_response(response: String) -> Self { + pub fn status_response(response: ServerStatus) -> Self { let status_response = StatusResponse { response }; Self::StatusResponse(status_response) @@ -90,7 +91,7 @@ pub struct PingRequest { #[derive(Packet, Debug)] pub struct StatusResponse { - pub response: String, + pub response: ServerStatus, } #[derive(Packet, Debug)]