1use nom::bytes::complete::take;
2use nom::combinator::{fail, map};
3use nom::error::context;
4use nom::number::complete::le_u8;
5
6use nom::{
7 multi::count,
8 number::complete::{le_f32, le_i16, le_i32, le_i8, le_u16, le_u32},
9 sequence::tuple,
10};
11
12use crate::nom_helper::{null_string, Result};
13
14use crate::bit::{BitReader, BitSliceCast};
15use crate::byte_writer::ByteWriter;
16
17use crate::types::{AuxRefCell, NetMessage, UserMessage};
18use crate::{
19 bit::BitWriter,
20 delta::{parse_delta, write_delta},
21 types::{
22 BitVec, ByteVec, EngineMessage, SvcAddAngle, SvcCdTrack, SvcCenterPrint, SvcClientData,
23 SvcCrosshairAngle, SvcCustomization, SvcCutscene, SvcDecalName, SvcDeltaDescription,
24 SvcDeltaPacketEntities, SvcDirector, SvcDisconnect, SvcEvent, SvcEventReliable,
25 SvcFileTxferFailed, SvcFinale, SvcHltv, SvcLightStyle, SvcNewMovevars, SvcNewUserMsg,
26 SvcPacketEntities, SvcParticle, SvcPings, SvcPrint, SvcResourceList, SvcResourceLocation,
27 SvcResourceRequest, SvcRestore, SvcRoomType, SvcSendCvarValue, SvcSendCvarValue2,
28 SvcSendExtraInfo, SvcServerInfo, SvcSetAngle, SvcSetPause, SvcSetView, SvcSignOnNum,
29 SvcSound, SvcSoundFade, SvcSpawnBaseline, SvcSpawnStatic, SvcSpawnStaticSound,
30 SvcStopSound, SvcStuffText, SvcTempEntity, SvcTime, SvcTimeScale, SvcUpdateUserInfo,
31 SvcVersion, SvcVoiceData, SvcVoiceInit, SvcWeaponAnim,
32 },
33};
34
35mod add_angle;
37mod cd_track;
38mod center_print;
39mod client_data;
40mod crosshair_angle;
41mod customization;
42mod cutscene;
43mod decal_name;
44mod delta_description;
45mod delta_packet_entities;
46mod director;
47mod disconnect;
48mod event;
49mod event_reliable;
50mod file_txfer_failed;
51mod finale;
52mod hltv;
53mod light_style;
54mod new_movevars;
55mod new_user_msg;
56mod packet_entities;
57mod particle;
58mod pings;
59mod print;
60mod resource_list;
61mod resource_location;
62mod resource_request;
63mod restore;
64mod room_type;
65mod send_cvar_value;
66mod send_cvar_value_2;
67mod send_extra_info;
68mod server_info;
69mod set_angle;
70mod set_pause;
71mod set_view;
72mod sign_on_num;
73mod sound;
74mod sound_fade;
75mod spawn_baseline;
76mod spawn_static;
77mod spawn_static_sound;
78mod stop_sound;
79mod stuff_text;
80mod temp_entity;
81mod time;
82mod time_scale;
83mod update_user_info;
84mod version;
85mod voice_data;
86mod voice_init;
87mod weapon_anim;
88
89pub trait Doer {
90 fn id(&self) -> u8;
91 fn parse(i: &[u8], aux: AuxRefCell) -> Result<Self>
92 where
93 Self: Sized;
94 fn write(&self, aux: AuxRefCell) -> ByteVec;
95}
96
97macro_rules! wrap {
98 ($svc:ident, $parser:ident, $input:ident, $aux:ident) => {{
99 let ($input, res) = $parser::parse($input, $aux)?;
100 ($input, EngineMessage::$svc(res))
101 }};
102
103 ($svc:ident, $input:ident, $aux:ident) => {{
105 let ($input, res) = $svc::parse($input, $aux)?;
106 ($input, EngineMessage::$svc(res))
107 }};
108}
109
110macro_rules! wrap_box {
111 ($svc:ident, $parser:ident, $input:ident, $aux:ident) => {{
112 let ($input, res) = $parser::parse($input, $aux)?;
113 ($input, EngineMessage::$svc(Box::new(res)))
114 }};
115
116 ($svc:ident, $input:ident, $aux:ident) => {{
118 let ($input, res) = $svc::parse($input, $aux)?;
119 ($input, EngineMessage::$svc(Box::new(res)))
120 }};
121}
122
123impl NetMessage {
124 pub fn parse(i: &[u8], aux: AuxRefCell) -> Result<NetMessage> {
125 let (i, type_) = le_u8(i)?;
126
127 match type_ {
128 0..=63 => {
129 let (i, res) = EngineMessage::parse(i, type_, aux)?;
130 Ok((i, NetMessage::EngineMessage(Box::new(res))))
131 }
132 _ => {
133 let (i, res) = UserMessage::parse(i, type_, aux)?;
134 Ok((i, NetMessage::UserMessage(res)))
135 }
136 }
137 }
138
139 pub fn write(&self, aux: AuxRefCell) -> ByteVec {
140 match self {
141 NetMessage::UserMessage(what) => what.write(aux),
142 NetMessage::EngineMessage(what) => what.write(aux),
143 }
144 }
145}
146
147impl UserMessage {
148 fn parse(i: &[u8], id: u8, aux: AuxRefCell) -> Result<UserMessage> {
149 let aux = aux.borrow();
150
151 let custom_message = aux.custom_messages.get(&id);
152
153 let is_set = custom_message.is_some();
154 let is_size = custom_message.is_some() && custom_message.unwrap().size > -1; let (i, data) = if is_size {
157 take(custom_message.unwrap().size as usize)(i)?
158 } else {
159 let (i, length) = le_u8(i)?;
160 take(length as usize)(i)?
161 };
162
163 Ok((
164 i,
165 UserMessage {
166 id,
167 name: if is_set {
168 custom_message.unwrap().name.clone().into()
169 } else {
170 b"\0".to_vec()
171 },
172 data: data.to_vec(),
173 },
174 ))
175 }
176
177 fn write(&self, aux: AuxRefCell) -> ByteVec {
178 let aux = aux.borrow();
179
180 let mut writer = ByteWriter::new();
181
182 writer.append_u8(self.id);
183
184 if let Some(message) = aux.custom_messages.get(&self.id) {
185 if message.size == -1 {
186 writer.append_u8(self.data.len() as u8);
187 }
188 }
189
190 writer.append_u8_slice(&self.data);
191
192 writer.data
193 }
194}
195
196impl EngineMessage {
197 fn parse(i: &[u8], type_: u8, aux: AuxRefCell) -> Result<EngineMessage> {
198 let (i, res) = match type_ {
199 0 => (i, EngineMessage::SvcBad),
200 1 => (i, EngineMessage::SvcNop),
201 2 => wrap!(SvcDisconnect, i, aux),
202 3 => wrap!(SvcEvent, i, aux),
203 4 => wrap!(SvcVersion, i, aux),
204 5 => wrap!(SvcSetView, i, aux),
205 6 => wrap_box!(SvcSound, i, aux),
206 7 => wrap!(SvcTime, i, aux),
207 8 => wrap!(SvcPrint, i, aux),
208 9 => wrap!(SvcStuffText, i, aux),
209 10 => wrap!(SvcSetAngle, i, aux),
210 11 => wrap!(SvcServerInfo, i, aux), 12 => wrap!(SvcLightStyle, i, aux),
212 13 => wrap!(SvcUpdateUserInfo, i, aux),
213 14 => wrap!(SvcDeltaDescription, i, aux), 15 => wrap!(SvcClientData, i, aux),
215 16 => wrap!(SvcStopSound, i, aux),
216 17 => wrap!(SvcPings, i, aux),
217 18 => wrap!(SvcParticle, i, aux),
218 19 => (i, EngineMessage::SvcDamage),
219 20 => wrap!(SvcSpawnStatic, i, aux),
220 21 => wrap!(SvcEventReliable, i, aux),
221 22 => wrap!(SvcSpawnBaseline, i, aux),
222 23 => wrap!(SvcTempEntity, i, aux),
223 24 => wrap!(SvcSetPause, i, aux),
224 25 => wrap!(SvcSignOnNum, i, aux),
225 26 => wrap!(SvcCenterPrint, i, aux),
226 27 => (i, EngineMessage::SvcKilledMonster),
227 28 => (i, EngineMessage::SvcFoundSecret),
228 29 => wrap!(SvcSpawnStaticSound, i, aux),
229 30 => (i, EngineMessage::SvcIntermission),
230 31 => wrap!(SvcFinale, i, aux),
231 32 => wrap!(SvcCdTrack, i, aux),
232 33 => wrap!(SvcRestore, i, aux),
233 34 => wrap!(SvcCutscene, i, aux),
234 35 => wrap!(SvcWeaponAnim, i, aux),
235 36 => wrap!(SvcDecalName, i, aux),
236 37 => wrap!(SvcRoomType, i, aux),
237 38 => wrap!(SvcAddAngle, i, aux),
238 39 => wrap!(SvcNewUserMsg, i, aux), 40 => wrap!(SvcPacketEntities, i, aux),
240 41 => wrap!(SvcDeltaPacketEntities, i, aux),
241 42 => (i, EngineMessage::SvcChoke),
242 43 => wrap!(SvcResourceList, i, aux),
243 44 => wrap!(SvcNewMovevars, i, aux),
244 45 => wrap!(SvcResourceRequest, i, aux),
245 46 => wrap!(SvcCustomization, i, aux),
246 47 => wrap!(SvcCrosshairAngle, i, aux),
247 48 => wrap!(SvcSoundFade, i, aux),
248 49 => wrap!(SvcFileTxferFailed, i, aux),
249 50 => wrap!(SvcHltv, i, aux),
250 51 => wrap!(SvcDirector, i, aux),
251 52 => wrap!(SvcVoiceInit, i, aux),
252 53 => wrap!(SvcVoiceData, i, aux),
253 54 => wrap!(SvcSendExtraInfo, i, aux),
254 55 => wrap!(SvcTimeScale, i, aux),
255 56 => wrap!(SvcResourceLocation, i, aux),
256 57 => wrap!(SvcSendCvarValue, i, aux),
257 58 => wrap!(SvcSendCvarValue2, i, aux),
258 59..=63 => (i, EngineMessage::SvcBad),
259 _ => context("Bad engine message number", fail)(i)?,
260 };
261
262 Ok((i, res))
263 }
264
265 fn write(&self, aux: AuxRefCell) -> ByteVec {
266 match self {
267 EngineMessage::SvcBad => vec![self.id()],
268 EngineMessage::SvcNop => vec![self.id()],
269 EngineMessage::SvcDisconnect(what) => what.write(aux),
270 EngineMessage::SvcEvent(what) => what.write(aux),
271 EngineMessage::SvcVersion(what) => what.write(aux),
272 EngineMessage::SvcSetView(what) => what.write(aux),
273 EngineMessage::SvcSound(what) => what.write(aux),
274 EngineMessage::SvcTime(what) => what.write(aux),
275 EngineMessage::SvcPrint(what) => what.write(aux),
276 EngineMessage::SvcStuffText(what) => what.write(aux),
277 EngineMessage::SvcSetAngle(what) => what.write(aux),
278 EngineMessage::SvcServerInfo(what) => what.write(aux),
279 EngineMessage::SvcLightStyle(what) => what.write(aux),
280 EngineMessage::SvcUpdateUserInfo(what) => what.write(aux),
281 EngineMessage::SvcDeltaDescription(what) => what.write(aux),
282 EngineMessage::SvcClientData(what) => what.write(aux),
283 EngineMessage::SvcStopSound(what) => what.write(aux),
284 EngineMessage::SvcPings(what) => what.write(aux),
285 EngineMessage::SvcParticle(what) => what.write(aux),
286 EngineMessage::SvcDamage => vec![self.id()],
287 EngineMessage::SvcSpawnStatic(what) => what.write(aux),
288 EngineMessage::SvcEventReliable(what) => what.write(aux),
289 EngineMessage::SvcSpawnBaseline(what) => what.write(aux),
290 EngineMessage::SvcTempEntity(what) => what.write(aux),
291 EngineMessage::SvcSetPause(what) => what.write(aux),
292 EngineMessage::SvcSignOnNum(what) => what.write(aux),
293 EngineMessage::SvcCenterPrint(what) => what.write(aux),
294 EngineMessage::SvcKilledMonster => vec![self.id()],
295 EngineMessage::SvcFoundSecret => vec![self.id()],
296 EngineMessage::SvcSpawnStaticSound(what) => what.write(aux),
297 EngineMessage::SvcIntermission => vec![self.id()],
298 EngineMessage::SvcFinale(what) => what.write(aux),
299 EngineMessage::SvcCdTrack(what) => what.write(aux),
300 EngineMessage::SvcRestore(what) => what.write(aux),
301 EngineMessage::SvcCutscene(what) => what.write(aux),
302 EngineMessage::SvcWeaponAnim(what) => what.write(aux),
303 EngineMessage::SvcDecalName(what) => what.write(aux),
304 EngineMessage::SvcRoomType(what) => what.write(aux),
305 EngineMessage::SvcAddAngle(what) => what.write(aux),
306 EngineMessage::SvcNewUserMsg(what) => what.write(aux),
307 EngineMessage::SvcPacketEntities(what) => what.write(aux),
308 EngineMessage::SvcDeltaPacketEntities(what) => what.write(aux),
309 EngineMessage::SvcChoke => vec![self.id()],
310 EngineMessage::SvcResourceList(what) => what.write(aux),
311 EngineMessage::SvcNewMovevars(what) => what.write(aux),
312 EngineMessage::SvcResourceRequest(what) => what.write(aux),
313 EngineMessage::SvcCustomization(what) => what.write(aux),
314 EngineMessage::SvcCrosshairAngle(what) => what.write(aux),
315 EngineMessage::SvcSoundFade(what) => what.write(aux),
316 EngineMessage::SvcFileTxferFailed(what) => what.write(aux),
317 EngineMessage::SvcHltv(what) => what.write(aux),
318 EngineMessage::SvcDirector(what) => what.write(aux),
319 EngineMessage::SvcVoiceInit(what) => what.write(aux),
320 EngineMessage::SvcVoiceData(what) => what.write(aux),
321 EngineMessage::SvcSendExtraInfo(what) => what.write(aux),
322 EngineMessage::SvcTimeScale(what) => what.write(aux),
323 EngineMessage::SvcResourceLocation(what) => what.write(aux),
324 EngineMessage::SvcSendCvarValue(what) => what.write(aux),
325 EngineMessage::SvcSendCvarValue2(what) => what.write(aux),
326 }
327 }
328
329 fn id(&self) -> u8 {
332 match self {
333 EngineMessage::SvcBad => 0,
334 EngineMessage::SvcNop => 1,
335 EngineMessage::SvcDisconnect(_) => 2,
336 EngineMessage::SvcEvent(_) => 3,
337 EngineMessage::SvcVersion(_) => 4,
338 EngineMessage::SvcSetView(_) => 5,
339 EngineMessage::SvcSound(_) => 6,
340 EngineMessage::SvcTime(_) => 7,
341 EngineMessage::SvcPrint(_) => 8,
342 EngineMessage::SvcStuffText(_) => 9,
343 EngineMessage::SvcSetAngle(_) => 10,
344 EngineMessage::SvcServerInfo(_) => 11,
345 EngineMessage::SvcLightStyle(_) => 12,
346 EngineMessage::SvcUpdateUserInfo(_) => 13,
347 EngineMessage::SvcDeltaDescription(_) => 14,
348 EngineMessage::SvcClientData(_) => 15,
349 EngineMessage::SvcStopSound(_) => 16,
350 EngineMessage::SvcPings(_) => 17,
351 EngineMessage::SvcParticle(_) => 18,
352 EngineMessage::SvcDamage => 19,
353 EngineMessage::SvcSpawnStatic(_) => 20,
354 EngineMessage::SvcEventReliable(_) => 21,
355 EngineMessage::SvcSpawnBaseline(_) => 22,
356 EngineMessage::SvcTempEntity(_) => 23,
357 EngineMessage::SvcSetPause(_) => 24,
358 EngineMessage::SvcSignOnNum(_) => 25,
359 EngineMessage::SvcCenterPrint(_) => 26,
360 EngineMessage::SvcKilledMonster => 27,
361 EngineMessage::SvcFoundSecret => 28,
362 EngineMessage::SvcSpawnStaticSound(_) => 29,
363 EngineMessage::SvcIntermission => 30,
364 EngineMessage::SvcFinale(_) => 31,
365 EngineMessage::SvcCdTrack(_) => 32,
366 EngineMessage::SvcRestore(_) => 33,
367 EngineMessage::SvcCutscene(_) => 34,
368 EngineMessage::SvcWeaponAnim(_) => 35,
369 EngineMessage::SvcDecalName(_) => 36,
370 EngineMessage::SvcRoomType(_) => 37,
371 EngineMessage::SvcAddAngle(_) => 38,
372 EngineMessage::SvcNewUserMsg(_) => 39,
373 EngineMessage::SvcPacketEntities(_) => 40,
374 EngineMessage::SvcDeltaPacketEntities(_) => 41,
375 EngineMessage::SvcChoke => 42,
376 EngineMessage::SvcResourceList(_) => 43,
377 EngineMessage::SvcNewMovevars(_) => 44,
378 EngineMessage::SvcResourceRequest(_) => 45,
379 EngineMessage::SvcCustomization(_) => 46,
380 EngineMessage::SvcCrosshairAngle(_) => 47,
381 EngineMessage::SvcSoundFade(_) => 48,
382 EngineMessage::SvcFileTxferFailed(_) => 49,
383 EngineMessage::SvcHltv(_) => 50,
384 EngineMessage::SvcDirector(_) => 51,
385 EngineMessage::SvcVoiceInit(_) => 52,
386 EngineMessage::SvcVoiceData(_) => 53,
387 EngineMessage::SvcSendExtraInfo(_) => 54,
388 EngineMessage::SvcTimeScale(_) => 55,
389 EngineMessage::SvcResourceLocation(_) => 56,
390 EngineMessage::SvcSendCvarValue(_) => 57,
391 EngineMessage::SvcSendCvarValue2(_) => 58,
392 }
393 }
394}