Refactor
This commit is contained in:
parent
e8a061e672
commit
c6d1cdecc7
@ -1,7 +1,11 @@
|
|||||||
|
use crate::frontend;
|
||||||
|
use handlebars::{Handlebars, TemplateRenderError};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use serde_json::json;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum State {
|
pub enum State {
|
||||||
@ -172,3 +176,48 @@ impl Protocol {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct GenerateContext<'a> {
|
||||||
|
packet_enum_name: String,
|
||||||
|
packets: &'a Vec<frontend::Packet>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_rust_file<W: Write>(
|
||||||
|
protocol: &frontend::Protocol,
|
||||||
|
template_engine: &Handlebars,
|
||||||
|
mut writer: W,
|
||||||
|
) -> Result<(), TemplateRenderError> {
|
||||||
|
let server_bound_ctx = GenerateContext {
|
||||||
|
packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server),
|
||||||
|
packets: &protocol.server_bound_packets,
|
||||||
|
};
|
||||||
|
|
||||||
|
let client_bound_ctx = GenerateContext {
|
||||||
|
packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client),
|
||||||
|
packets: &protocol.client_bound_packets,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut imports = vec![
|
||||||
|
"crate::DecodeError",
|
||||||
|
"crate::Decoder",
|
||||||
|
"std::io::Read",
|
||||||
|
"minecraft_protocol_derive::Packet",
|
||||||
|
];
|
||||||
|
|
||||||
|
imports.extend(protocol.data_type_imports().iter());
|
||||||
|
|
||||||
|
template_engine.render_to_write(
|
||||||
|
"packet_imports",
|
||||||
|
&json!({ "imports": imports }),
|
||||||
|
&mut writer,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?;
|
||||||
|
template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?;
|
||||||
|
|
||||||
|
template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?;
|
||||||
|
template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
use crate::mappings::CodeMappings;
|
use crate::mappings::CodeMappings;
|
||||||
use crate::transformer::transform_protocol;
|
|
||||||
use handlebars::*;
|
|
||||||
use heck::SnakeCase;
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde_json::json;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod frontend;
|
pub mod frontend;
|
||||||
pub mod mappings;
|
pub mod mappings;
|
||||||
pub mod transformer;
|
pub mod templates;
|
||||||
|
pub mod transformers;
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
#[structopt(name = "protocol-generator")]
|
#[structopt(name = "protocol-generator")]
|
||||||
@ -23,7 +18,7 @@ struct Opt {
|
|||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let opt: Opt = Opt::from_args();
|
let opt: Opt = Opt::from_args();
|
||||||
let template_engine = create_template_engine();
|
let template_engine = templates::create_template_engine();
|
||||||
|
|
||||||
let protocol_data_file_name = format!(
|
let protocol_data_file_name = format!(
|
||||||
"protocol-generator/minecraft-data/data/pc/{}/protocol.json",
|
"protocol-generator/minecraft-data/data/pc/{}/protocol.json",
|
||||||
@ -40,7 +35,7 @@ pub fn main() {
|
|||||||
|
|
||||||
let protocols = vec![
|
let protocols = vec![
|
||||||
(
|
(
|
||||||
transform_protocol(
|
transformers::transform_protocol(
|
||||||
&mappings,
|
&mappings,
|
||||||
frontend::State::Handshake,
|
frontend::State::Handshake,
|
||||||
&protocol_input.handshaking,
|
&protocol_input.handshaking,
|
||||||
@ -48,15 +43,27 @@ pub fn main() {
|
|||||||
frontend::State::Handshake,
|
frontend::State::Handshake,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
transform_protocol(&mappings, frontend::State::Status, &protocol_input.status),
|
transformers::transform_protocol(
|
||||||
|
&mappings,
|
||||||
|
frontend::State::Status,
|
||||||
|
&protocol_input.status,
|
||||||
|
),
|
||||||
frontend::State::Status,
|
frontend::State::Status,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
transform_protocol(&mappings, frontend::State::Login, &protocol_input.login),
|
transformers::transform_protocol(
|
||||||
|
&mappings,
|
||||||
|
frontend::State::Login,
|
||||||
|
&protocol_input.login,
|
||||||
|
),
|
||||||
frontend::State::Login,
|
frontend::State::Login,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
transform_protocol(&mappings, frontend::State::Game, &protocol_input.game),
|
transformers::transform_protocol(
|
||||||
|
&mappings,
|
||||||
|
frontend::State::Game,
|
||||||
|
&protocol_input.game,
|
||||||
|
),
|
||||||
frontend::State::Game,
|
frontend::State::Game,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -68,123 +75,7 @@ pub fn main() {
|
|||||||
);
|
);
|
||||||
let file = File::create(file_name).expect("Failed to create file");
|
let file = File::create(file_name).expect("Failed to create file");
|
||||||
|
|
||||||
generate_rust_file(&protocol, &template_engine, &file)
|
frontend::generate_rust_file(&protocol, &template_engine, &file)
|
||||||
.expect("Failed to generate rust file");
|
.expect("Failed to generate rust file");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_template_engine() -> Handlebars<'static> {
|
|
||||||
let mut template_engine = Handlebars::new();
|
|
||||||
|
|
||||||
template_engine.register_helper("snake_case", Box::new(format_snake_case));
|
|
||||||
template_engine.register_helper("packet_id", Box::new(format_packet_id));
|
|
||||||
template_engine.register_escape_fn(|s| s.to_owned());
|
|
||||||
|
|
||||||
template_engine
|
|
||||||
.register_template_file(
|
|
||||||
"packet_imports",
|
|
||||||
"protocol-generator/templates/packet_imports.hbs",
|
|
||||||
)
|
|
||||||
.expect("Failed to register template");
|
|
||||||
|
|
||||||
template_engine
|
|
||||||
.register_template_file(
|
|
||||||
"packet_enum",
|
|
||||||
"protocol-generator/templates/packet_enum.hbs",
|
|
||||||
)
|
|
||||||
.expect("Failed to register template");
|
|
||||||
|
|
||||||
template_engine
|
|
||||||
.register_template_file(
|
|
||||||
"packet_structs",
|
|
||||||
"protocol-generator/templates/packet_structs.hbs",
|
|
||||||
)
|
|
||||||
.expect("Failed to register template");
|
|
||||||
|
|
||||||
template_engine
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
struct GenerateContext<'a> {
|
|
||||||
packet_enum_name: String,
|
|
||||||
packets: &'a Vec<frontend::Packet>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_rust_file<W: Write>(
|
|
||||||
protocol: &frontend::Protocol,
|
|
||||||
template_engine: &Handlebars,
|
|
||||||
mut writer: W,
|
|
||||||
) -> Result<(), TemplateRenderError> {
|
|
||||||
let server_bound_ctx = GenerateContext {
|
|
||||||
packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Server),
|
|
||||||
packets: &protocol.server_bound_packets,
|
|
||||||
};
|
|
||||||
|
|
||||||
let client_bound_ctx = GenerateContext {
|
|
||||||
packet_enum_name: format!("{}{}BoundPacket", &protocol.state, frontend::Bound::Client),
|
|
||||||
packets: &protocol.client_bound_packets,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut imports = vec![
|
|
||||||
"crate::DecodeError",
|
|
||||||
"crate::Decoder",
|
|
||||||
"std::io::Read",
|
|
||||||
"minecraft_protocol_derive::Packet",
|
|
||||||
];
|
|
||||||
|
|
||||||
imports.extend(protocol.data_type_imports().iter());
|
|
||||||
|
|
||||||
template_engine.render_to_write(
|
|
||||||
"packet_imports",
|
|
||||||
&json!({ "imports": imports }),
|
|
||||||
&mut writer,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
template_engine.render_to_write("packet_enum", &server_bound_ctx, &mut writer)?;
|
|
||||||
template_engine.render_to_write("packet_enum", &client_bound_ctx, &mut writer)?;
|
|
||||||
|
|
||||||
template_engine.render_to_write("packet_structs", &server_bound_ctx, &mut writer)?;
|
|
||||||
template_engine.render_to_write("packet_structs", &client_bound_ctx, &mut writer)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_snake_case(
|
|
||||||
h: &Helper,
|
|
||||||
_: &Handlebars,
|
|
||||||
_: &Context,
|
|
||||||
_: &mut RenderContext,
|
|
||||||
out: &mut dyn Output,
|
|
||||||
) -> Result<(), RenderError> {
|
|
||||||
let str = h
|
|
||||||
.param(0)
|
|
||||||
.and_then(|v| v.value().as_str())
|
|
||||||
.ok_or(RenderError::new(
|
|
||||||
"Param 0 with str type is required for snake case helper.",
|
|
||||||
))? as &str;
|
|
||||||
|
|
||||||
let snake_case_str = str.to_snake_case();
|
|
||||||
|
|
||||||
out.write(snake_case_str.as_ref())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_packet_id(
|
|
||||||
h: &Helper,
|
|
||||||
_: &Handlebars,
|
|
||||||
_: &Context,
|
|
||||||
_: &mut RenderContext,
|
|
||||||
out: &mut dyn Output,
|
|
||||||
) -> Result<(), RenderError> {
|
|
||||||
let id = h
|
|
||||||
.param(0)
|
|
||||||
.and_then(|v| v.value().as_u64())
|
|
||||||
.ok_or(RenderError::new(
|
|
||||||
"Param 0 with u64 type is required for packet id helper.",
|
|
||||||
))? as u64;
|
|
||||||
|
|
||||||
let packet_id_str = format!("{:#04X}", id);
|
|
||||||
|
|
||||||
out.write(packet_id_str.as_ref())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
73
protocol-generator/src/templates.rs
Normal file
73
protocol-generator/src/templates.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError};
|
||||||
|
use heck::SnakeCase;
|
||||||
|
|
||||||
|
pub fn create_template_engine() -> Handlebars<'static> {
|
||||||
|
let mut template_engine = Handlebars::new();
|
||||||
|
|
||||||
|
template_engine.register_helper("snake_case", Box::new(format_snake_case));
|
||||||
|
template_engine.register_helper("packet_id", Box::new(format_packet_id));
|
||||||
|
template_engine.register_escape_fn(|s| s.to_owned());
|
||||||
|
|
||||||
|
template_engine
|
||||||
|
.register_template_file(
|
||||||
|
"packet_imports",
|
||||||
|
"protocol-generator/templates/packet_imports.hbs",
|
||||||
|
)
|
||||||
|
.expect("Failed to register template");
|
||||||
|
|
||||||
|
template_engine
|
||||||
|
.register_template_file(
|
||||||
|
"packet_enum",
|
||||||
|
"protocol-generator/templates/packet_enum.hbs",
|
||||||
|
)
|
||||||
|
.expect("Failed to register template");
|
||||||
|
|
||||||
|
template_engine
|
||||||
|
.register_template_file(
|
||||||
|
"packet_structs",
|
||||||
|
"protocol-generator/templates/packet_structs.hbs",
|
||||||
|
)
|
||||||
|
.expect("Failed to register template");
|
||||||
|
|
||||||
|
template_engine
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_snake_case(
|
||||||
|
h: &Helper,
|
||||||
|
_: &Handlebars,
|
||||||
|
_: &Context,
|
||||||
|
_: &mut RenderContext,
|
||||||
|
out: &mut dyn Output,
|
||||||
|
) -> Result<(), RenderError> {
|
||||||
|
let str = h
|
||||||
|
.param(0)
|
||||||
|
.and_then(|v| v.value().as_str())
|
||||||
|
.ok_or(RenderError::new(
|
||||||
|
"Param 0 with str type is required for snake case helper.",
|
||||||
|
))? as &str;
|
||||||
|
|
||||||
|
let snake_case_str = str.to_snake_case();
|
||||||
|
|
||||||
|
out.write(snake_case_str.as_ref())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_packet_id(
|
||||||
|
h: &Helper,
|
||||||
|
_: &Handlebars,
|
||||||
|
_: &Context,
|
||||||
|
_: &mut RenderContext,
|
||||||
|
out: &mut dyn Output,
|
||||||
|
) -> Result<(), RenderError> {
|
||||||
|
let id = h
|
||||||
|
.param(0)
|
||||||
|
.and_then(|v| v.value().as_u64())
|
||||||
|
.ok_or(RenderError::new(
|
||||||
|
"Param 0 with u64 type is required for packet id helper.",
|
||||||
|
))? as u64;
|
||||||
|
|
||||||
|
let packet_id_str = format!("{:#04X}", id);
|
||||||
|
|
||||||
|
out.write(packet_id_str.as_ref())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user