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