tf_demo_parser/demo/parser/
mod.rs1use crate::demo::data::DemoTick;
2use bitbuffer::{BitError, BitRead, BitWrite, BitWriteStream, LittleEndian};
3
4pub use self::messagetypeanalyser::MessageTypeAnalyser;
5
6use crate::demo::header::Header;
7
8use crate::demo::packet::Packet;
9use crate::demo::parser::analyser::Analyser;
10pub use crate::demo::parser::analyser::MatchState;
11pub use crate::demo::parser::handler::{DemoHandler, MessageHandler, NullHandler};
12pub use crate::demo::parser::state::ParserState;
13use crate::Stream;
14
15pub mod analyser;
16pub mod error;
17pub mod gamestateanalyser;
18pub mod handler;
19pub mod messagetypeanalyser;
20pub mod player_summary_analyzer;
21pub mod state;
22
23pub use self::error::*;
24use crate::demo::parser::handler::BorrowMessageHandler;
25
26pub trait Parse<'a>: Sized {
27 fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self>;
28}
29
30impl<'a, T: BitRead<'a, LittleEndian>> Parse<'a> for T {
31 fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
32 Self::read(stream).map_err(ParseError::from)
33 }
34}
35pub trait Encode: Sized {
36 fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()>;
37}
38
39impl<T: BitWrite<LittleEndian>> Encode for T {
40 fn encode(
41 &self,
42 stream: &mut BitWriteStream<LittleEndian>,
43 _state: &ParserState,
44 ) -> Result<()> {
45 self.write(stream).map_err(ParseError::from)
46 }
47}
48
49pub trait ParseBitSkip<'a> {
50 fn parse_skip(stream: &mut Stream<'a>, state: &ParserState) -> Result<()>;
51}
52
53impl<'a, T: BitRead<'a, LittleEndian>> ParseBitSkip<'a> for T {
54 #[inline(always)]
55 fn parse_skip(stream: &mut Stream<'a>, _state: &ParserState) -> Result<()> {
56 Self::skip(stream).map_err(ParseError::from)
57 }
58}
59
60pub struct DemoParser<'a, A: MessageHandler> {
61 handler: DemoHandler<'a, A>,
62 stream: Stream<'a>,
63}
64
65impl<'a> DemoParser<'a, Analyser> {
66 pub fn new(stream: Stream<'a>) -> Self {
67 DemoParser::new_with_analyser(stream, Analyser::new())
68 }
69
70 pub fn new_all(stream: Stream<'a>) -> Self {
71 DemoParser::new_all_with_analyser(stream, Analyser::new())
72 }
73}
74
75impl<'a, A: MessageHandler> DemoParser<'a, A> {
76 pub fn new_with_analyser(stream: Stream<'a>, analyser: A) -> Self {
77 DemoParser {
78 handler: DemoHandler::with_analyser(analyser),
79 stream,
80 }
81 }
82
83 pub fn new_all_with_analyser(stream: Stream<'a>, analyser: A) -> Self {
84 DemoParser {
85 handler: DemoHandler::parse_all_with_analyser(analyser),
86 stream,
87 }
88 }
89
90 pub fn parse(self) -> Result<(Header, A::Output)> {
91 let (header, mut ticker) = self.ticker()?;
92 while ticker.tick()? {
93 }
95 Ok((header, ticker.into_state()))
96 }
97
98 pub fn ticker(mut self) -> Result<(Header, DemoTicker<'a, A>)> {
101 let header = Header::read(&mut self.stream)?;
102 self.handler.handle_header(&header);
103 let ticker = DemoTicker {
104 handler: self.handler,
105 packets: RawPacketStream::new(self.stream),
106 };
107 Ok((header, ticker))
108 }
109}
110
111#[derive(Clone)]
112pub struct RawPacketStream<'a> {
113 stream: Stream<'a>,
114 pub ended: bool,
115 pub incomplete: bool,
116}
117
118impl<'a> RawPacketStream<'a> {
119 pub fn new(stream: Stream<'a>) -> Self {
120 RawPacketStream {
121 stream,
122 ended: false,
123 incomplete: false,
124 }
125 }
126
127 pub fn pos(&self) -> usize {
128 self.stream.pos()
129 }
130
131 pub fn next(&mut self, state: &ParserState) -> Result<Option<Packet<'a>>> {
132 if self.ended {
133 Ok(None)
134 } else {
135 match Packet::parse(&mut self.stream, state) {
136 Ok(packet @ Packet::Stop(_)) => {
137 self.ended = true;
138 Ok(Some(packet))
139 }
140 Ok(packet) => Ok(Some(packet)),
141 Err(ParseError::ReadError(BitError::NotEnoughData { .. })) => {
142 self.ended = true;
143 self.incomplete = true;
144 Ok(None)
145 }
146 Err(e) => {
147 self.ended = true;
148 Err(e)
149 }
150 }
151 }
152 }
153}
154
155#[derive(Clone)]
156pub struct DemoTicker<'a, A: MessageHandler> {
157 handler: DemoHandler<'a, A>,
158 packets: RawPacketStream<'a>,
159}
160
161impl<A: MessageHandler> DemoTicker<'_, A> {
162 pub fn tick(&mut self) -> Result<bool> {
166 Ok(
167 if let Some(packet) = self.packets.next(&self.handler.state_handler)? {
168 self.handler.handle_packet(packet)?;
169
170 true
171 } else {
172 false
173 },
174 )
175 }
176
177 pub fn into_state(self) -> A::Output {
178 self.handler.into_output()
179 }
180}
181
182impl<A: MessageHandler + BorrowMessageHandler> DemoTicker<'_, A> {
183 pub fn state(&self) -> &A::Output {
184 self.handler.borrow_output()
185 }
186
187 pub fn parser_state(&self) -> &ParserState {
188 self.handler.get_parser_state()
189 }
190
191 #[allow(clippy::should_implement_trait)]
193 pub fn next(&mut self) -> Result<Option<Tick<A::Output>>> {
194 Ok(
195 if let Some(packet) = self.packets.next(&self.handler.state_handler)? {
196 let tick = packet.tick();
197 self.handler.handle_packet(packet)?;
198
199 Some(Tick {
200 state: self.handler.borrow_output(),
201 parser_state: self.handler.get_parser_state(),
202 tick,
203 })
204 } else {
205 None
206 },
207 )
208 }
209}
210
211pub struct Tick<'a, State> {
212 pub state: &'a State,
213 pub parser_state: &'a ParserState,
214 pub tick: DemoTick,
215}