Skip to main content

source2_demo/parser/demo/writer/
runner.rs

1use crate::error::ParserError;
2use crate::parser::demo::writer::commands::DemoCommandWrite;
3use crate::parser::demo::writer::{DemoWriter, MessageRewrite, RawDemoMessage, RewriteInterests};
4use crate::reader::{BitsReader, MessageReader};
5use std::io::{Seek, Write};
6
7pub(crate) enum DemoMessageRewrite {
8    Keep(Option<Vec<u8>>),
9    Drop,
10}
11
12impl<'a, R, W> DemoWriter<'a, R, W>
13where
14    R: BitsReader + MessageReader,
15    W: Write + Seek,
16{
17    /// Parses the demo while writing the rewritten stream.
18    pub fn run(&mut self) -> Result<(), ParserError> {
19        self.parser.reader.seek(0);
20        let header = self.parser.reader.read_bytes(16);
21        self.writer.write_all(&header)?;
22        self.bytes_written = header.len() as u64;
23
24        while let Some(message) = self.read_next_raw_message()? {
25            self.update_context_tick(message.tick);
26
27            let payload = match self.rewrite_demo_message(&message)? {
28                DemoMessageRewrite::Keep(payload) => payload,
29                DemoMessageRewrite::Drop => continue,
30            };
31
32            if matches!(
33                self.write_demo_command(&message, payload)?,
34                DemoCommandWrite::Dropped
35            ) {
36                continue;
37            }
38        }
39
40        self.finalize_file_info_offset()?;
41        Ok(())
42    }
43
44    fn rewrite_demo_message(
45        &mut self,
46        message: &RawDemoMessage,
47    ) -> Result<DemoMessageRewrite, ParserError> {
48        let mut payload = None;
49        if self.has_rewriters(RewriteInterests::DEMO_MESSAGE) {
50            let mut decoded = Self::decode_raw_payload(message)?;
51            let ctx = &self.parser.context;
52            for rewriter in self.rewriters.iter_mut().filter(|rewriter| {
53                rewriter
54                    .interests()
55                    .contains(RewriteInterests::DEMO_MESSAGE)
56            }) {
57                match rewriter.rewrite_demo_message(
58                    ctx,
59                    message.tick,
60                    message.msg_type,
61                    decoded.as_slice(),
62                )? {
63                    MessageRewrite::Drop => return Ok(DemoMessageRewrite::Drop),
64                    MessageRewrite::Replace(bytes) => decoded = bytes,
65                    MessageRewrite::Keep | MessageRewrite::Rewrite => {}
66                }
67            }
68            payload = Some(decoded);
69        }
70
71        Ok(DemoMessageRewrite::Keep(payload))
72    }
73
74    fn update_context_tick(&mut self, tick: u32) {
75        self.parser.context.previous_tick = self.parser.context.tick;
76        self.parser.context.tick = tick;
77    }
78}