dem/netmsg_doer/
mod.rs

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
35// main stuffs
36mod 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    // This one means the struct name has to be the same as enum name
104    ($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    // This one means the struct name has to be the same as enum name
117    ($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; // equivalent to -1
155
156        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), // mutate max_client
211            12 => wrap!(SvcLightStyle, i, aux),
212            13 => wrap!(SvcUpdateUserInfo, i, aux),
213            14 => wrap!(SvcDeltaDescription, i, aux), // mutate delta_decoders
214            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), // mutate custom_messages
239            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    // repeat because of code being fragmented
330    // for good purposes tho
331    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}