forked from Awpteamoose/demoinfocs2_lite
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.rs
More file actions
114 lines (95 loc) · 3.42 KB
/
Copy pathexample.rs
File metadata and controls
114 lines (95 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use demoinfocs2_lite::{
CsDemoParserState, entity::EntityClass, event::DemoStartEvent, game_event::derive::GameEvent,
};
use std::io::BufReader;
fn main() -> Result<(), std::io::Error> {
env_logger::init();
let file = std::env::args()
.nth(1)
.expect("Please provide a demo file path as the first argument");
let file = std::fs::File::open(file).expect("Failed to open demo file");
let time = std::time::Instant::now();
let mut parser =
demoinfocs2_lite::CsDemoParser::new(BufReader::with_capacity(1024 * 128, file))?;
parser
.event_manager
.register_listener(|event: &DemoStartEvent, _state: &CsDemoParserState| {
println!("Map changed: {}", event.map_name);
Ok(())
});
parser.register_game_event_serializer_factory("player_death", PlayerDeathEvent::factory)?;
parser.event_manager.register_listener(
|event: &PlayerDeathEvent, state: &CsDemoParserState| {
let attacker_name = state
.get_player_info(event.attacker)
.map_or("unknown", |p| p.name.as_ref().unwrap());
let victim_name = state
.get_player_info(event.userid)
.map_or("unknown", |p| p.name.as_ref().unwrap());
let player = state
.entities
.get_entity_by_index::<CCSPlayerController>(event.attacker as u32 + 1);
println!(
"Player {} killed {} with {} (headshot: {}, penetrated: {}, noscope: {}, thrusmoke: {}, distance: {:.2}, ping: {}ms)",
attacker_name,
victim_name,
event.weapon,
event.headshot,
event.penetrated > 0,
event.noscope,
event.thrusmoke,
event.distance,
player.map_or(0, |p| p.ping)
);
Ok(())
},
);
parser.register_entity_serializer("CCSPlayerController", CCSPlayerController::new_serializer);
parser.register_entity_serializer("CCSGameRulesProxy", CCSGameRulesProxy::new_serializer);
parser.register_entity_serializer("CCSGameRules", CCSGameRules::new_serializer);
loop {
if !parser.read_frame()? {
break;
}
}
println!("time: {:?}", time.elapsed());
Ok(())
}
#[derive(GameEvent, Default, Debug)]
#[game_event(crate_path = demoinfocs2_lite)]
pub struct PlayerDeathEvent {
pub attacker: u16,
pub userid: u16,
pub weapon: String,
pub headshot: bool,
pub penetrated: u16,
pub noscope: bool,
pub thrusmoke: bool,
pub distance: f32,
}
#[derive(EntityClass, Clone, Default)]
#[entity(crate_path = demoinfocs2_lite)]
pub struct CCSPlayerController {
#[entity(name = "m_iPing")]
pub ping: u64,
#[entity(name = "m_iszPlayerName", on_changed = Self::on_changed)]
pub player_name: String,
}
#[derive(EntityClass, Clone, Default)]
#[entity(crate_path = demoinfocs2_lite)]
pub struct CCSGameRulesProxy {
#[entity(name = "m_pGameRules")]
pub game_rules: Option<CCSGameRules>,
}
#[derive(EntityClass, Clone, Default)]
#[entity(crate_path = demoinfocs2_lite)]
pub struct CCSGameRules {
#[entity(name = "m_pGameModeRules")]
pub game_mode_rules: usize,
}
impl CCSPlayerController {
fn on_changed(&mut self) -> Result<(), std::io::Error> {
println!("Name changed: {} (ping {}ms)", self.player_name, self.ping);
Ok(())
}
}