1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-04 02:24:12 +02:00

Add analyzer to extract player scoreboard information

This commit is contained in:
Yep 2022-12-28 12:57:57 -05:00
commit df793083aa
6 changed files with 405 additions and 13 deletions

View file

@ -3,6 +3,8 @@ use std::fs;
use main_error::MainError;
pub use tf_demo_parser::{Demo, DemoParser, Parse, ParseError, ParserState, Stream};
use tf_demo_parser::demo::parser::player_summary_analyzer::PlayerSummaryAnalyzer;
#[cfg(feature = "jemallocator")]
#[global_allocator]
@ -21,18 +23,81 @@ fn main() -> Result<(), MainError> {
return Ok(());
}
let path = args[1].clone();
let all = args
.get(2)
.map(|arg| arg.as_str() == "all")
.unwrap_or_default();
let all = args.contains(&std::string::String::from("all"));
let detailed_summaries = args.contains(&std::string::String::from("detailed_summaries"));
let file = fs::read(path)?;
let demo = Demo::new(&file);
let parser = if all {
DemoParser::new_all(demo.get_stream())
if !detailed_summaries {
// Use the default (simple) analyzer to track kills, assists, and deaths
let parser = if all {
DemoParser::new_all(demo.get_stream())
} else {
DemoParser::new(demo.get_stream())
};
let (_, state) = parser.parse()?;
println!("{}", serde_json::to_string(&state)?);
} else {
DemoParser::new(demo.get_stream())
};
let (_, state) = parser.parse()?;
println!("{}", serde_json::to_string(&state)?);
let parser = if all {
DemoParser::new_all_with_analyser(demo.get_stream(), PlayerSummaryAnalyzer::new())
} else {
DemoParser::new_with_analyser(demo.get_stream(), PlayerSummaryAnalyzer::new())
};
let (header, state) = parser.parse()?;
println!("{:?}", header);
let table_header = "Player | Points | Kills | Deaths | Assists | Destruction | Captures | Defenses | Domination | Revenge | Ubers | Headshots | Teleports | Healing | Backstabs | Bonus | Support | Damage Dealt";
let divider = "---------------------------------|------------|------------|------------|------------|-------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|-------------";
println!("{}", table_header);
println!("{}", divider);
for (user_id, user_data) in state.users {
let player_name = user_data.name;
let summary = state.player_summaries.get(&user_id);
match summary {
Some(s) => {
let (color_code_start, color_code_end) = if player_name == header.nick {
// Give the line for the player a green background with white text
// ANSI color codes are in hex, since rust doesn't support octal literals in strings
// See: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
("\x1b[1;42;37m", "\x1b[0m")
} else {
("", "")
};
println!(
"{}{:32} | {:10} | {:10} | {:10} | {:10} | {:11} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:10} | {:12}{}",
color_code_start,
player_name,
s.points,
s.kills,
s.deaths,
s.assists,
s.buildings_destroyed,
s.captures,
s.defenses,
s.dominations,
s.revenges,
s.ubercharges,
s.headshots,
s.teleports,
s.healing,
s.backstabs,
s.bonus_points,
s.support,
s.damage_dealt,
color_code_end,
);
},
None => {
// No summary for this player - they likely joined at the end of the match, or left before they did anything noteworthy
}
}
}
}
Ok(())
}