Skip to main content

tf_demo_parser/demo/message/
mod.rs

1pub use generated::*;
2
3pub use crate::demo::message::bspdecal::*;
4pub use crate::demo::message::classinfo::*;
5pub use crate::demo::message::gameevent::*;
6pub use crate::demo::message::packetentities::*;
7pub use crate::demo::message::prefetch::*;
8pub use crate::demo::message::serverinfo::*;
9pub use crate::demo::message::setconvar::*;
10pub use crate::demo::message::stringtable::*;
11pub use crate::demo::message::tempentities::*;
12pub use crate::demo::message::usermessage::*;
13pub use crate::demo::message::voice::*;
14#[cfg(feature = "write")]
15use crate::demo::parser::Encode;
16use crate::demo::parser::ParseBitSkip;
17use crate::{Parse, ParserState, Result, Stream};
18use bitbuffer::BitRead;
19#[cfg(feature = "write")]
20use bitbuffer::{BitWrite, BitWriteStream, LittleEndian};
21use serde::{Deserialize, Serialize};
22use serde_repr::{Deserialize_repr, Serialize_repr};
23
24pub mod bspdecal;
25pub mod classinfo;
26pub mod gameevent;
27pub mod generated;
28pub mod packetentities;
29pub mod prefetch;
30mod serverinfo;
31pub mod setconvar;
32pub mod stringtable;
33pub mod tempentities;
34pub mod usermessage;
35pub mod voice;
36
37#[cfg_attr(feature = "schema", derive(schemars::JsonSchema_repr))]
38#[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
39#[cfg_attr(feature = "write", derive(BitWrite))]
40#[repr(u8)]
41#[discriminant_bits = 6]
42pub enum MessageType {
43    Empty = 0,
44    File = 2,
45    NetTick = 3,
46    StringCmd = 4,
47    SetConVar = 5,
48    SignOnState = 6,
49    Print = 7,
50    ServerInfo = 8,
51    ClassInfo = 10,
52    SetPause = 11,
53    CreateStringTable = 12,
54    UpdateStringTable = 13,
55    VoiceInit = 14,
56    VoiceData = 15,
57    ParseSounds = 17,
58    SetView = 18,
59    FixAngle = 19,
60    BspDecal = 21,
61    UserMessage = 23,
62    EntityMessage = 24,
63    GameEvent = 25,
64    PacketEntities = 26,
65    TempEntities = 27,
66    PreFetch = 28,
67    Menu = 29,
68    GameEventList = 30,
69    GetCvarValue = 31,
70    CmdKeyValues = 32,
71}
72
73#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
74#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
75#[serde(bound(deserialize = "'a: 'static"))]
76#[serde(tag = "type")]
77pub enum Message<'a> {
78    Empty,
79    File(FileMessage),
80    NetTick(NetTickMessage),
81    StringCmd(StringCmdMessage),
82    SetConVar(SetConVarMessage),
83    SignOnState(SignOnStateMessage),
84    Print(PrintMessage),
85    ServerInfo(Box<ServerInfoMessage>),
86    ClassInfo(ClassInfoMessage),
87    SetPause(SetPauseMessage),
88    CreateStringTable(CreateStringTableMessage<'a>),
89    UpdateStringTable(UpdateStringTableMessage<'a>),
90    VoiceInit(VoiceInitMessage),
91    VoiceData(VoiceDataMessage<'a>),
92    ParseSounds(ParseSoundsMessage<'a>),
93    SetView(SetViewMessage),
94    FixAngle(FixAngleMessage),
95    BspDecal(BSPDecalMessage),
96    UserMessage(UserMessage<'a>),
97    EntityMessage(EntityMessage<'a>),
98    GameEvent(GameEventMessage),
99    PacketEntities(PacketEntitiesMessage),
100    TempEntities(TempEntitiesMessage),
101    PreFetch(PreFetchMessage),
102    Menu(MenuMessage<'a>),
103    GameEventList(GameEventListMessage),
104    GetCvarValue(GetCvarValueMessage),
105    CmdKeyValues(CmdKeyValuesMessage<'a>),
106}
107
108impl<'a> Parse<'a> for Message<'a> {
109    fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
110        let message_type = MessageType::parse(stream, state)?;
111        Self::from_type(message_type, stream, state)
112    }
113}
114
115impl<'a> Message<'a> {
116    pub fn get_message_type(&self) -> MessageType {
117        match self {
118            Message::Empty => MessageType::Empty,
119            Message::File(_) => MessageType::File,
120            Message::NetTick(_) => MessageType::NetTick,
121            Message::StringCmd(_) => MessageType::StringCmd,
122            Message::SetConVar(_) => MessageType::SetConVar,
123            Message::SignOnState(_) => MessageType::SignOnState,
124            Message::Print(_) => MessageType::Print,
125            Message::ServerInfo(_) => MessageType::ServerInfo,
126            Message::ClassInfo(_) => MessageType::ClassInfo,
127            Message::SetPause(_) => MessageType::SetPause,
128            Message::CreateStringTable(_) => MessageType::CreateStringTable,
129            Message::UpdateStringTable(_) => MessageType::UpdateStringTable,
130            Message::VoiceInit(_) => MessageType::VoiceInit,
131            Message::VoiceData(_) => MessageType::VoiceData,
132            Message::ParseSounds(_) => MessageType::ParseSounds,
133            Message::SetView(_) => MessageType::SetView,
134            Message::FixAngle(_) => MessageType::FixAngle,
135            Message::BspDecal(_) => MessageType::BspDecal,
136            Message::UserMessage(_) => MessageType::UserMessage,
137            Message::EntityMessage(_) => MessageType::EntityMessage,
138            Message::GameEvent(_) => MessageType::GameEvent,
139            Message::PacketEntities(_) => MessageType::PacketEntities,
140            Message::TempEntities(_) => MessageType::TempEntities,
141            Message::PreFetch(_) => MessageType::PreFetch,
142            Message::Menu(_) => MessageType::Menu,
143            Message::GameEventList(_) => MessageType::GameEventList,
144            Message::GetCvarValue(_) => MessageType::GetCvarValue,
145            Message::CmdKeyValues(_) => MessageType::CmdKeyValues,
146        }
147    }
148
149    pub fn from_type(
150        message_type: MessageType,
151        stream: &mut Stream<'a>,
152        state: &ParserState,
153    ) -> Result<Self> {
154        Ok(match message_type {
155            MessageType::Empty => Message::Empty,
156            MessageType::File => Message::File(FileMessage::parse(stream, state)?),
157            MessageType::NetTick => Message::NetTick(NetTickMessage::parse(stream, state)?),
158            MessageType::StringCmd => Message::StringCmd(StringCmdMessage::parse(stream, state)?),
159            MessageType::SetConVar => Message::SetConVar(SetConVarMessage::parse(stream, state)?),
160            MessageType::SignOnState => {
161                Message::SignOnState(SignOnStateMessage::parse(stream, state)?)
162            }
163            MessageType::Print => Message::Print(PrintMessage::parse(stream, state)?),
164            MessageType::ServerInfo => {
165                Message::ServerInfo(Box::new(ServerInfoMessage::parse(stream, state)?))
166            }
167            MessageType::ClassInfo => Message::ClassInfo(ClassInfoMessage::parse(stream, state)?),
168            MessageType::SetPause => Message::SetPause(SetPauseMessage::parse(stream, state)?),
169            MessageType::CreateStringTable => {
170                Message::CreateStringTable(CreateStringTableMessage::parse(stream, state)?)
171            }
172            MessageType::UpdateStringTable => {
173                Message::UpdateStringTable(UpdateStringTableMessage::parse(stream, state)?)
174            }
175            MessageType::VoiceInit => Message::VoiceInit(VoiceInitMessage::parse(stream, state)?),
176            MessageType::VoiceData => Message::VoiceData(VoiceDataMessage::parse(stream, state)?),
177            MessageType::ParseSounds => {
178                Message::ParseSounds(ParseSoundsMessage::parse(stream, state)?)
179            }
180            MessageType::SetView => Message::SetView(SetViewMessage::parse(stream, state)?),
181            MessageType::FixAngle => Message::FixAngle(FixAngleMessage::parse(stream, state)?),
182            MessageType::BspDecal => Message::BspDecal(BSPDecalMessage::parse(stream, state)?),
183            MessageType::UserMessage => Message::UserMessage(UserMessage::parse(stream, state)?),
184            MessageType::EntityMessage => {
185                Message::EntityMessage(EntityMessage::parse(stream, state)?)
186            }
187            MessageType::GameEvent => Message::GameEvent(GameEventMessage::parse(stream, state)?),
188            MessageType::PacketEntities => {
189                Message::PacketEntities(PacketEntitiesMessage::parse(stream, state)?)
190            }
191            MessageType::TempEntities => {
192                Message::TempEntities(TempEntitiesMessage::parse(stream, state)?)
193            }
194            MessageType::PreFetch => Message::PreFetch(PreFetchMessage::parse(stream, state)?),
195            MessageType::Menu => Message::Menu(MenuMessage::parse(stream, state)?),
196            MessageType::GameEventList => {
197                Message::GameEventList(GameEventListMessage::parse(stream, state)?)
198            }
199            MessageType::GetCvarValue => {
200                Message::GetCvarValue(GetCvarValueMessage::parse(stream, state)?)
201            }
202            MessageType::CmdKeyValues => {
203                Message::CmdKeyValues(CmdKeyValuesMessage::parse(stream, state)?)
204            }
205        })
206    }
207
208    pub fn skip_type(
209        message_type: MessageType,
210        stream: &mut Stream,
211        state: &ParserState,
212    ) -> Result<()> {
213        match message_type {
214            MessageType::Empty => Ok(()),
215            MessageType::File => FileMessage::parse_skip(stream, state),
216            MessageType::NetTick => NetTickMessage::parse_skip(stream, state),
217            MessageType::StringCmd => StringCmdMessage::parse_skip(stream, state),
218            MessageType::SetConVar => SetConVarMessage::parse_skip(stream, state),
219            MessageType::SignOnState => SignOnStateMessage::parse_skip(stream, state),
220            MessageType::Print => PrintMessage::parse_skip(stream, state),
221            MessageType::ServerInfo => ServerInfoMessage::parse_skip(stream, state),
222            MessageType::ClassInfo => ClassInfoMessage::parse_skip(stream, state),
223            MessageType::SetPause => SetPauseMessage::parse_skip(stream, state),
224            MessageType::CreateStringTable => CreateStringTableMessage::parse_skip(stream, state),
225            MessageType::UpdateStringTable => UpdateStringTableMessage::parse_skip(stream, state),
226            MessageType::VoiceInit => VoiceInitMessage::parse_skip(stream, state),
227            MessageType::VoiceData => VoiceDataMessage::parse_skip(stream, state),
228            MessageType::ParseSounds => ParseSoundsMessage::parse_skip(stream, state),
229            MessageType::SetView => SetViewMessage::parse_skip(stream, state),
230            MessageType::FixAngle => FixAngleMessage::parse_skip(stream, state),
231            MessageType::BspDecal => BSPDecalMessage::parse_skip(stream, state),
232            MessageType::UserMessage => UserMessage::parse_skip(stream, state),
233            MessageType::EntityMessage => EntityMessage::parse_skip(stream, state),
234            MessageType::GameEvent => GameEventMessage::parse_skip(stream, state),
235            MessageType::PacketEntities => PacketEntitiesMessage::parse_skip(stream, state),
236            MessageType::TempEntities => TempEntitiesMessage::parse_skip(stream, state),
237            MessageType::PreFetch => PreFetchMessage::parse_skip(stream, state),
238            MessageType::Menu => MenuMessage::parse_skip(stream, state),
239            MessageType::GameEventList => GameEventListMessage::parse_skip(stream, state),
240            MessageType::GetCvarValue => GetCvarValueMessage::parse_skip(stream, state),
241            MessageType::CmdKeyValues => CmdKeyValuesMessage::parse_skip(stream, state),
242        }
243    }
244}
245
246#[cfg(feature = "write")]
247impl Encode for Message<'_> {
248    fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> {
249        match self {
250            Message::Empty => Ok(()),
251            Message::File(message) => message.encode(stream, state),
252            Message::NetTick(message) => message.encode(stream, state),
253            Message::StringCmd(message) => message.encode(stream, state),
254            Message::SetConVar(message) => message.encode(stream, state),
255            Message::SignOnState(message) => message.encode(stream, state),
256            Message::Print(message) => message.encode(stream, state),
257            Message::ServerInfo(message) => message.encode(stream, state),
258            Message::ClassInfo(message) => message.encode(stream, state),
259            Message::SetPause(message) => message.encode(stream, state),
260            Message::CreateStringTable(message) => message.encode(stream, state),
261            Message::UpdateStringTable(message) => message.encode(stream, state),
262            Message::VoiceInit(message) => message.encode(stream, state),
263            Message::VoiceData(message) => message.encode(stream, state),
264            Message::ParseSounds(message) => message.encode(stream, state),
265            Message::SetView(message) => message.encode(stream, state),
266            Message::FixAngle(message) => message.encode(stream, state),
267            Message::BspDecal(message) => message.encode(stream, state),
268            Message::UserMessage(message) => message.encode(stream, state),
269            Message::EntityMessage(message) => message.encode(stream, state),
270            Message::GameEvent(message) => message.encode(stream, state),
271            Message::PacketEntities(message) => message.encode(stream, state),
272            Message::TempEntities(message) => message.encode(stream, state),
273            Message::PreFetch(message) => message.encode(stream, state),
274            Message::Menu(message) => message.encode(stream, state),
275            Message::GameEventList(message) => message.encode(stream, state),
276            Message::GetCvarValue(message) => message.encode(stream, state),
277            Message::CmdKeyValues(message) => message.encode(stream, state),
278        }
279    }
280}