source2_demo/parser/demo/
runner.rs1use crate::error::ParserError;
2use crate::parser::demo::DemoMessages;
3use crate::parser::Parser;
4use crate::proto::*;
5use crate::reader::*;
6use crate::Entity;
7use std::cmp::min;
8use std::mem;
9
10pub trait DemoRunner {
11 fn run_to_end(&mut self) -> Result<(), ParserError>;
13
14 fn run_to_tick(&mut self, target_tick: u32) -> Result<(), ParserError>;
16
17 fn jump_to_tick(&mut self, target_tick: u32) -> Result<(), ParserError>;
20}
21
22impl DemoRunner for Parser<'_> {
23 fn run_to_end(&mut self) -> Result<(), ParserError> {
24 self.prologue()?;
25
26 while let Some(message) = self.reader.read_next_message()? {
27 self.on_tick_start(message.tick)?;
28 self.on_demo_command(message.msg_type, message.buf.as_slice())?;
29 }
30 self.on_tick_end()?;
31
32 Ok(())
33 }
34
35 fn run_to_tick(&mut self, target_tick: u32) -> Result<(), ParserError> {
36 assert!(target_tick > self.context.tick || self.context.tick == u32::MAX);
37
38 self.prologue()?;
39
40 let target_tick = min(target_tick, self.last_tick);
41
42 while let Some(message) = self.reader.read_next_message()? {
43 self.on_tick_start(message.tick)?;
44 self.on_demo_command(message.msg_type, message.buf.as_slice())?;
45 if self.context.tick >= target_tick {
46 self.on_tick_end()?;
47 break;
48 }
49 }
50
51 Ok(())
52 }
53
54 fn jump_to_tick(&mut self, target_tick: u32) -> Result<(), ParserError> {
55 let fp_delta = if cfg!(feature = "deadlock") {
56 3600
57 } else {
58 1800
59 };
60
61 let target_tick = min(target_tick, self.last_tick);
62
63 if target_tick < self.context.tick {
64 self.context.last_full_packet_tick = u32::MAX;
65 self.context.tick = u32::MAX;
66 self.context.net_tick = u32::MAX;
67 self.reader.reset_to(16);
68
69 self.context.entities.entities_vec = vec![Entity::default(); 8192];
70
71 self.context.string_tables.tables.clear();
72 self.context.string_tables.name_to_table.clear();
73 self.context.game_events.list.clear();
74 }
75
76 self.prologue()?;
77
78 self.skip_deltas = true;
79 let observers = mem::take(&mut self.observers);
80
81 let mut first_fp_checked = self.context.last_full_packet_tick != u32::MAX;
82 let mut last_fp_checked = false;
83
84 while let Some(mut message) = self.reader.read_next_message()? {
85 self.context.previous_tick = self.context.tick;
86 self.context.tick = message.tick;
87
88 if message.msg_type == EDemoCommands::DemFullPacket {
89 self.context.last_full_packet_tick = self.context.tick;
90 }
91
92 let next_fp = self.context.last_full_packet_tick == u32::MAX
93 || self.context.last_full_packet_tick < target_tick
94 && (target_tick - self.context.last_full_packet_tick) > fp_delta;
95
96 if message.msg_type == EDemoCommands::DemFullPacket {
97 if next_fp && first_fp_checked {
98 message.msg_type = EDemoCommands::DemStringTables;
99 message.buf = CDemoFullPacket::decode(message.buf.as_slice())?
100 .string_table
101 .unwrap()
102 .encode_to_vec();
103 }
104
105 self.on_demo_command(message.msg_type, message.buf.as_slice())?;
106 }
107
108 if last_fp_checked {
109 self.on_demo_command(message.msg_type, message.buf.as_slice())?;
110 }
111
112 if message.msg_type == EDemoCommands::DemFullPacket && !first_fp_checked {
113 first_fp_checked = true;
114 }
115
116 if message.msg_type == EDemoCommands::DemFullPacket && !next_fp {
117 last_fp_checked = true;
118 self.skip_deltas = false;
119 }
120
121 if self.context.tick >= target_tick && first_fp_checked {
122 break;
123 }
124 }
125
126 self.skip_deltas = false;
127 self.observers = observers;
128
129 Ok(())
130 }
131}