mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
generate propname mapping
This commit is contained in:
parent
e78c1f8608
commit
5976b43d56
4 changed files with 134 additions and 4 deletions
25
codegen/Cargo.lock
generated
25
codegen/Cargo.lock
generated
|
|
@ -275,6 +275,15 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
|
@ -526,6 +535,15 @@ dependencies = [
|
||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.25"
|
version = "0.6.25"
|
||||||
|
|
@ -719,7 +737,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tf-demo-parser"
|
name = "tf-demo-parser"
|
||||||
version = "0.3.3"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitbuffer",
|
"bitbuffer",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
|
|
@ -746,6 +764,7 @@ dependencies = [
|
||||||
"better-panic",
|
"better-panic",
|
||||||
"fnv",
|
"fnv",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"main_error",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -842,9 +861,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594"
|
checksum = "5d81bfa81424cc98cb034b837c985b7a290f592e5b4322f353f94a0ab0f9f594"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
|
"lazy_static",
|
||||||
|
"matchers",
|
||||||
|
"regex",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,4 @@ tempfile = "3"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
fnv = "1"
|
fnv = "1"
|
||||||
prettyplease = "0.1"
|
prettyplease = "0.1"
|
||||||
|
main_error = "0.1.2"
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::gameevent::generate_game_events;
|
use crate::gameevent::generate_game_events;
|
||||||
|
use crate::propnames::generate_prop_names;
|
||||||
|
use main_error::MainError;
|
||||||
use prettyplease::unparse;
|
use prettyplease::unparse;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
@ -6,8 +8,9 @@ use syn::{parse2, File};
|
||||||
use tf_demo_parser::Demo;
|
use tf_demo_parser::Demo;
|
||||||
|
|
||||||
mod gameevent;
|
mod gameevent;
|
||||||
|
mod propnames;
|
||||||
|
|
||||||
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
fn main() -> std::result::Result<(), MainError> {
|
||||||
better_panic::install();
|
better_panic::install();
|
||||||
|
|
||||||
let args: Vec<_> = env::args().collect();
|
let args: Vec<_> = env::args().collect();
|
||||||
|
|
@ -18,7 +21,11 @@ fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||||
let path = args[1].clone();
|
let path = args[1].clone();
|
||||||
let file = fs::read(path).expect("Unable to read file");
|
let file = fs::read(path).expect("Unable to read file");
|
||||||
let demo = Demo::new(&file);
|
let demo = Demo::new(&file);
|
||||||
let tokens = generate_game_events(demo);
|
let tokens = match args.get(2).map(|s| s.as_str()) {
|
||||||
|
None | Some("events") => generate_game_events(demo),
|
||||||
|
Some("props") => generate_prop_names(demo),
|
||||||
|
_ => panic!("unsupported"),
|
||||||
|
};
|
||||||
let file = parse2::<File>(tokens)?;
|
let file = parse2::<File>(tokens)?;
|
||||||
let code = unparse(&file);
|
let code = unparse(&file);
|
||||||
println!("{}", code);
|
println!("{}", code);
|
||||||
|
|
|
||||||
99
codegen/src/propnames.rs
Normal file
99
codegen/src/propnames.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
use fnv::{FnvHashMap, FnvHashSet};
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use tf_demo_parser::demo::message::Message;
|
||||||
|
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName, ServerClass};
|
||||||
|
use tf_demo_parser::demo::parser::MessageHandler;
|
||||||
|
use tf_demo_parser::demo::sendprop::{SendPropIdentifier, SendPropName};
|
||||||
|
use tf_demo_parser::{Demo, DemoParser, MessageType, ParserState};
|
||||||
|
|
||||||
|
struct PropInfo {
|
||||||
|
identifier: SendPropIdentifier,
|
||||||
|
table_name: String,
|
||||||
|
prop_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct PropAnalyzer {
|
||||||
|
props: FnvHashSet<SendPropIdentifier>,
|
||||||
|
prop_names: FnvHashMap<SendPropIdentifier, (SendTableName, SendPropName)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageHandler for PropAnalyzer {
|
||||||
|
type Output = Vec<PropInfo>;
|
||||||
|
|
||||||
|
fn does_handle(message_type: MessageType) -> bool {
|
||||||
|
matches!(message_type, MessageType::PacketEntities)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_message(&mut self, message: &Message, _tick: u32) {
|
||||||
|
if let Message::PacketEntities(message) = message {
|
||||||
|
for entity in &message.entities {
|
||||||
|
for prop in &entity.props {
|
||||||
|
self.props.insert(prop.identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_data_tables(
|
||||||
|
&mut self,
|
||||||
|
parse_tables: &[ParseSendTable],
|
||||||
|
_server_classes: &[ServerClass],
|
||||||
|
) {
|
||||||
|
for table in parse_tables {
|
||||||
|
for prop_def in &table.props {
|
||||||
|
self.prop_names.insert(
|
||||||
|
prop_def.identifier(),
|
||||||
|
(table.name.clone(), prop_def.name.clone()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_output(self, _state: &ParserState) -> Self::Output {
|
||||||
|
let mut props: Vec<_> = self
|
||||||
|
.prop_names
|
||||||
|
.into_iter()
|
||||||
|
.map(|(identifier, (table_name, prop_name))| PropInfo {
|
||||||
|
identifier,
|
||||||
|
table_name: table_name.to_string(),
|
||||||
|
prop_name: prop_name.to_string(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
props.sort_by(|a, b| a.identifier.cmp(&b.identifier));
|
||||||
|
props
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_prop_names(demo: Demo) -> TokenStream {
|
||||||
|
let (_, props) = DemoParser::new_with_analyser(demo.get_stream(), PropAnalyzer::default())
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let imports = quote!(
|
||||||
|
use tf_demo_parser::demo::packet::datatable::SendTableName;
|
||||||
|
use tf_demo_parser::demo::sendprop::{SendPropIdentifier, SendPropName};
|
||||||
|
);
|
||||||
|
|
||||||
|
let matches = props.into_iter().map(|prop| {
|
||||||
|
let identifier: u64 = prop.identifier.into();
|
||||||
|
let table_name = prop.table_name;
|
||||||
|
let prop_name = prop.prop_name;
|
||||||
|
quote! {
|
||||||
|
#identifier => Some((#table_name, #prop_name))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote!(
|
||||||
|
#imports
|
||||||
|
|
||||||
|
pub fn get_prop_names(identifier: SendPropIdentifier) -> Option<(&'static str, &'static str)> {
|
||||||
|
let identifier: u64 = identifier.into();
|
||||||
|
match identifier {
|
||||||
|
#(#matches,)*
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue