source_demo_tool/demo_file/
packet.rs

1use std::io::Read;
2
3use crate::{
4    engine_types::Vector3F64,
5    event_data::EventData,
6    parse_tools::{ parse_i32, parse_i64, },
7    protobuf_message::{ProtobufMessage, ProtobufMessageEnumTraits},
8};
9
10use buf_redux::BufReader;
11
12pub mod netmessage;
13pub mod usermessage;
14pub mod protobuf_value;
15
16#[derive(Debug, Clone)]
17pub struct PacketData {
18    pub header: Header,
19    pub network_messages: Vec<MessageParseReturn<netmessage::NetMessage>>
20}
21
22impl PacketData {
23    pub fn from_packet_index(packet_index: PacketIndex) -> Self {
24        let header = packet_index.header;
25
26        let mut data_reader = BufReader::with_capacity
27            (packet_index.data.len(), packet_index.data.as_slice());
28
29        data_reader.read_into_buf().unwrap();
30
31        let mut network_messages = Vec::new();
32        while data_reader.buf_len() > 0 {
33            let net_result = netmessage::NetMessage::parse_from_bufredux_reader(&mut data_reader);
34
35            let mut message = None;
36            let mut warnings = None;
37            let mut err = None;
38            if let Ok((msg, warn)) = net_result {
39                message = Some(msg);
40                warnings = Some(warn);
41            } else {
42                err = Some(net_result.unwrap_err());
43            }
44
45            network_messages.push(MessageParseReturn{ message, warnings, err });
46        }
47
48        Self { header, network_messages }
49    }
50}
51
52#[derive(Debug, Clone)]
53pub struct Header {
54     pub command_info: CommandInfo,
55     pub in_seq: i32,
56     pub out_seq: i32,
57     pub data_length: i32
58}
59
60impl Header {
61    pub fn from_readable(mut reader: impl Read) -> Result<Self, String> {
62        let command_info = match CommandInfo::from_readable(&mut reader) {
63            Ok(ci) => ci,
64            Err(e) => return Err(format!("error occured parsing command info: {e}"))
65        };
66
67        let in_seq = match parse_i32(&mut reader) {
68            Ok(n) => n,
69            Err(e) => return Err(format!("error occured reading in sequence: {e}"))
70        };
71
72        let out_seq = match parse_i32(&mut reader) {
73            Ok(n) => n,
74            Err(e) => return Err(format!("error occured reading out sequence: {e}"))
75        };
76
77        let data_length = match parse_i32(&mut reader) {
78            Ok(n) => n,
79            Err(e) => return Err(format!("error occured reading data length: {e}"))
80        };
81
82        Ok(Header {
83            command_info,
84            in_seq,
85            out_seq,
86            data_length
87        })
88    }
89}
90
91pub struct PacketIndex {
92    pub header: Header,
93    pub data: Vec<u8>
94}
95
96impl PacketIndex {
97    pub fn from_readable(mut reader: impl Read) -> Result<Self, String> {
98        let header = Header::from_readable(&mut reader)?;
99
100        let mut data = Vec::new();
101
102        data.resize(header.data_length.try_into().unwrap(), 0);
103
104        match reader.read_exact(data.as_mut_slice()) {
105            Ok(()) => Ok(PacketIndex{header, data}),
106            Err(e) => Err(format!("couldn't read data into buffer: {}", e.to_string()))
107        }
108    }
109}
110
111#[derive(Debug, Clone)]
112pub struct CommandInfo {
113    pub flags: i64,
114    pub view_origin: Vector3F64,
115    pub view_angles: Vector3F64,
116    pub local_view_angles: Vector3F64,
117    pub inter_view_origin: Vector3F64,
118    pub inter_view_angles: Vector3F64,
119    pub inter_local_view_angles: Vector3F64
120}
121
122impl CommandInfo {
123    fn from_readable(mut reader: impl Read) -> Result<CommandInfo, String> {
124        let flags = match parse_i64(&mut reader) {
125            Ok(n) => n,
126            Err(e) => return Err(format!("error parsing flags: {e}"))
127        };
128
129        let view_origin = match Vector3F64::from_readable(&mut reader) {
130            Ok(v) => v,
131            Err(e) => return Err(format!("error parsing view origin: {e}"))
132        };
133
134        let view_angles = match Vector3F64::from_readable(&mut reader) {
135            Ok(v) => v,
136            Err(e) => return Err(format!("error parsing view angles: {e}"))
137        };
138
139        let local_view_angles = match Vector3F64::from_readable(&mut reader) {
140            Ok(v) => v,
141            Err(e) => return Err(format!("error parsing local view angles: {e}"))
142        };
143
144        let inter_view_origin = match Vector3F64::from_readable(&mut reader) {
145            Ok(v) => v,
146            Err(e) => return Err(format!("error parsing interpolated view origin: {e}"))
147        };
148
149        let inter_view_angles = match Vector3F64::from_readable(&mut reader) {
150            Ok(v) => v,
151            Err(e) => return Err(format!("error parsing interpolated view angles: {e}"))
152        };
153
154        let inter_local_view_angles = match Vector3F64::from_readable(&mut reader) {
155            Ok(v) => v,
156            Err(e) => return Err(format!("error parsing interpolated local view angles: {e}"))
157        };
158
159        Ok(CommandInfo {
160            flags,
161            view_origin,
162            view_angles,
163            local_view_angles,
164            inter_view_origin,
165            inter_view_angles,
166            inter_local_view_angles
167        })
168    }
169}
170
171#[derive(Debug, Clone)]
172pub enum ParseMessageErr {
173    InvalidOrCorrupt(EventData),
174    UnknownCommand(u64),
175}
176
177#[derive(Debug, Clone)]
178pub struct FromProtobufMessagesWarnings {
179    pub unknown_fields: Vec<ProtobufMessage>,
180    pub missing_fields: Vec<(u8, &'static str)>,
181    pub sub_warnings: Vec<(&'static str, FromProtobufMessagesWarnings)>,
182    pub repeated_fields: Vec<u8>,
183}
184
185impl FromProtobufMessagesWarnings {
186    pub fn has_warnings(&self) -> bool {
187        if !self.unknown_fields.is_empty() || !self.missing_fields.is_empty() || !self.repeated_fields.is_empty() {
188            return true;
189        }
190        for sub_warn in &self.sub_warnings {
191            if sub_warn.1.has_warnings() {
192                return true;
193            }
194        }
195        false
196    }
197}
198
199#[derive(Debug, Clone)]
200pub struct MessageParseReturn<MessageType: ProtobufMessageEnumTraits> {
201    pub message: Option<MessageType>,
202    pub warnings: Option<FromProtobufMessagesWarnings>,
203    pub err: Option<ParseMessageErr>
204}