photon_decode/
decode.rs

1use std::collections::HashMap;
2use std::io::{Cursor, Read};
3use std::mem::size_of;
4
5use bytes::Buf;
6
7use crate::error::*;
8use crate::layout::*;
9
10pub type PhotonCursor<'a> = Cursor<&'a [u8]>;
11
12pub trait Decode<T> {
13    fn decode(&mut self) -> PhotonDecodeResult<T>;
14}
15
16trait TypedDecode {
17    fn typed_decode(&mut self, type_code: u8) -> PhotonDecodeResult<Value>;
18}
19
20macro_rules! impl_decode {
21    ($type:ty, $decode_func:ident, $bytes_to_consume:expr) => {
22        impl Decode<$type> for PhotonCursor<'_> {
23            fn decode(&mut self) -> PhotonDecodeResult<$type> {
24                let v = if self.remaining() >= $bytes_to_consume {
25                    self.$decode_func()
26                } else {
27                    return Err(PhotonDecodeError::from(concat!(
28                        "Failed to decode ",
29                        stringify!($type),
30                        ", not enough bytes"
31                    )));
32                };
33                Ok(v)
34            }
35        }
36    };
37}
38
39impl_decode!(u8, get_u8, 1);
40impl_decode!(f32, get_f32_be, 4);
41impl_decode!(u32, get_u32_be, 4);
42impl_decode!(i64, get_i64_be, 8);
43impl_decode!(i16, get_i16_be, 2);
44impl_decode!(f64, get_f64_be, 8);
45
46impl Decode<bool> for PhotonCursor<'_> {
47    fn decode(&mut self) -> PhotonDecodeResult<bool> {
48        let v = if self.remaining() >= 1 {
49            self.get_u8()
50        } else {
51            return Err(PhotonDecodeError::from(
52                "Failed to decode bool, not enough bytes",
53            ));
54        };
55        Ok(v != 0)
56    }
57}
58
59impl Decode<String> for PhotonCursor<'_> {
60    fn decode(&mut self) -> PhotonDecodeResult<String> {
61        let size: i16 = self.decode()?;
62        if size < 0 {
63            return Err(PhotonDecodeError::from(
64                "Failed to decode String, unreasonable size",
65            ));
66        }
67
68        let mut local_buffer = vec![0; size as usize];
69        if let Ok(_) = self.read_exact(&mut local_buffer[..]) {
70            if let Ok(s) = String::from_utf8(local_buffer) {
71                return Ok(s);
72            }
73        }
74
75        Err(PhotonDecodeError::from(
76            "Failed to decode String, not enough bytes",
77        ))
78    }
79}
80
81impl Decode<Vec<String>> for PhotonCursor<'_> {
82    fn decode(&mut self) -> PhotonDecodeResult<Vec<String>> {
83        let size: i16 = self.decode()?;
84        if size < 0 {
85            return Err(PhotonDecodeError::from(
86                "Failed to decode String, unreasonable size",
87            ));
88        }
89        let mut value: Vec<String> = vec![];
90        for _ in 0..size {
91            value.push(self.decode()?);
92        }
93
94        Ok(value)
95    }
96}
97
98impl Decode<Vec<u8>> for PhotonCursor<'_> {
99    fn decode(&mut self) -> PhotonDecodeResult<Vec<u8>> {
100        let size: u32 = self.decode()?;
101        let mut value: Vec<u8> = vec![];
102        for _ in 0..size {
103            value.push(self.decode()?);
104        }
105
106        Ok(value)
107    }
108}
109
110impl Decode<Vec<Value>> for PhotonCursor<'_> {
111    fn decode(&mut self) -> PhotonDecodeResult<Vec<Value>> {
112        let size: i16 = self.decode()?;
113        if size < 0 {
114            return Err(PhotonDecodeError::from(
115                "Failed to decode Vec<Value>, unreasonable size",
116            ));
117        }
118        let type_code: u8 = self.decode()?;
119
120        let mut value: Vec<Value> = vec![];
121        for _ in 0..size {
122            if let Ok(v) = self.typed_decode(type_code) {
123                value.push(v);
124            } else {
125                break;
126            }
127        }
128
129        Ok(value)
130    }
131}
132
133impl Decode<HashMap<String, Value>> for PhotonCursor<'_> {
134    fn decode(&mut self) -> PhotonDecodeResult<HashMap<String, Value>> {
135        let key_type_code: u8 = self.decode()?;
136        let value_type_code: u8 = self.decode()?;
137        let size: i16 = self.decode()?;
138        if size < 0 {
139            return Err(PhotonDecodeError::from(
140                "Failed to decode HashMap<String, Value>, unreasonable size",
141            ));
142        }
143
144        let mut value: HashMap<String, Value> = HashMap::new();
145        for _ in 0..size {
146            let key_code: u8 = if key_type_code == 0 || key_type_code == 42 {
147                self.decode()?
148            } else {
149                key_type_code
150            };
151
152            let key = self.typed_decode(key_code);
153
154            let value_code: u8 = if value_type_code == 0 || value_type_code == 42 {
155                self.decode()?
156            } else {
157                value_type_code
158            };
159            let val = self.typed_decode(value_code);
160            if let (Ok(key), Ok(val)) = (key, val) {
161                value.insert(format!("{}", key), val);
162            }
163        }
164
165        Ok(value)
166    }
167}
168
169impl Decode<HashMap<u8, Value>> for PhotonCursor<'_> {
170    fn decode(&mut self) -> PhotonDecodeResult<HashMap<u8, Value>> {
171        let size: i16 = self.decode()?;
172        if size < 0 {
173            return Err(PhotonDecodeError::from(
174                "Failed to decode HashMap<u8, Value>, unreasonable size",
175            ));
176        }
177
178        let mut value: HashMap<u8, Value> = HashMap::new();
179        for _ in 0..size {
180            let key_type_code: u8 = if let Ok(v) = self.decode() {
181                v
182            } else {
183                break;
184            };
185            let val: Value = if let Ok(v) = self.decode() {
186                v
187            } else {
188                break;
189            };
190            value.insert(key_type_code, val);
191        }
192
193        Ok(value)
194    }
195}
196
197impl Decode<EventData> for PhotonCursor<'_> {
198    fn decode(&mut self) -> PhotonDecodeResult<EventData> {
199        let code: u8 = self.decode()?;
200        let parameters: HashMap<u8, Value> = self.decode()?;
201        Ok(EventData { code, parameters })
202    }
203}
204
205impl Decode<OperationResponse> for PhotonCursor<'_> {
206    fn decode(&mut self) -> PhotonDecodeResult<OperationResponse> {
207        let code: u8 = self.decode()?;
208        let return_code: i16 = self.decode()?;
209        let maybe_debug_message: Value = self.decode()?;
210        let debug_message = if let Value::String(s) = maybe_debug_message {
211            s
212        } else {
213            "None".to_owned()
214        };
215        let parameters: HashMap<u8, Value> = self.decode()?;
216
217        Ok(OperationResponse {
218            code,
219            return_code,
220            debug_message,
221            parameters,
222        })
223    }
224}
225
226impl Decode<OperationRequest> for PhotonCursor<'_> {
227    fn decode(&mut self) -> PhotonDecodeResult<OperationRequest> {
228        let code: u8 = self.decode()?;
229        let parameters: HashMap<u8, Value> = self.decode()?;
230        Ok(OperationRequest { code, parameters })
231    }
232}
233
234impl Decode<Vec<Box<Value>>> for PhotonCursor<'_> {
235    fn decode(&mut self) -> PhotonDecodeResult<Vec<Box<Value>>> {
236        let size: i16 = self.decode()?;
237        if size < 0 {
238            return Err(PhotonDecodeError::from(
239                "Failed to decode Vec<Box<Value>>, unreasonable size",
240            ));
241        }
242        let mut value = vec![];
243        for _ in 0..size {
244            let type_code: u8 = if let Ok(v) = self.decode() {
245                v
246            } else {
247                break;
248            };
249            if let Ok(val) = self.typed_decode(type_code) {
250                value.push(Box::new(val));
251            }
252        }
253        Ok(value)
254    }
255}
256
257impl Decode<Vec<bool>> for PhotonCursor<'_> {
258    fn decode(&mut self) -> PhotonDecodeResult<Vec<bool>> {
259        let size: i16 = self.decode()?;
260        if size < 0 {
261            return Err(PhotonDecodeError::from(
262                "Failed to decode Vec<bool>, unreasonable size",
263            ));
264        }
265        let mut value = vec![];
266        for _ in 0..size {
267            value.push(self.decode()?);
268        }
269        Ok(value)
270    }
271}
272
273impl TypedDecode for PhotonCursor<'_> {
274    fn typed_decode(&mut self, type_code: u8) -> PhotonDecodeResult<Value> {
275        match TypeCode::from(type_code) {
276            TypeCode::None => Ok(Value::None),
277            TypeCode::Null => Ok(Value::None),
278            TypeCode::Boolean => Ok(Value::Boolean(self.decode()?)),
279            TypeCode::Byte => Ok(Value::Byte(self.decode()?)),
280            TypeCode::Double => Ok(Value::Double(self.decode()?)),
281            TypeCode::Float => Ok(Value::Float(self.decode()?)),
282            TypeCode::Integer => Ok(Value::Integer(self.decode()?)),
283            TypeCode::Long => Ok(Value::Long(self.decode()?)),
284            TypeCode::Short => Ok(Value::Short(self.decode()?)),
285            TypeCode::String => Ok(Value::String(self.decode()?)),
286            TypeCode::StringArray => Ok(Value::StringArray(self.decode()?)),
287            TypeCode::ByteArray => Ok(Value::ByteArray(self.decode()?)),
288            TypeCode::Dictionary => Ok(Value::Dictionary(self.decode()?)),
289            TypeCode::EventData => Ok(Value::EventData(self.decode()?)),
290            TypeCode::OperationRequest => Ok(Value::OperationRequest(self.decode()?)),
291            TypeCode::OperationResponse => Ok(Value::OperationResponse(self.decode()?)),
292            TypeCode::BooleanArray => Ok(Value::BooleanArray(self.decode()?)),
293            TypeCode::Array => Ok(Value::Array(self.decode()?)),
294            TypeCode::ObjectArray => Ok(Value::ObjectArray(self.decode()?)),
295            _ => Err(PhotonDecodeError::from(format!(
296                "Failed to decode Value, unknown type code ({:#X})",
297                type_code
298            ))),
299        }
300    }
301}
302
303impl Decode<Value> for PhotonCursor<'_> {
304    fn decode(&mut self) -> PhotonDecodeResult<Value> {
305        let type_code: u8 = self.decode()?;
306        self.typed_decode(type_code)
307    }
308}
309
310impl Decode<PhotonHeader> for PhotonCursor<'_> {
311    fn decode(&mut self) -> PhotonDecodeResult<PhotonHeader> {
312        let peer_id = self.decode()?;
313        let crc_enabled = self.decode()?;
314        let command_count = self.decode()?;
315        let timestamp = self.decode()?;
316        let challenge = self.decode()?;
317
318        Ok(PhotonHeader {
319            peer_id,
320            crc_enabled,
321            command_count,
322            timestamp,
323            challenge,
324        })
325    }
326}
327
328impl Decode<ReliableCommand> for PhotonCursor<'_> {
329    fn decode(&mut self) -> PhotonDecodeResult<ReliableCommand> {
330        let channel_id = self.decode()?;
331        let flags = self.decode()?;
332        let reserved_byte = self.decode()?;
333        let length: u32 = self.decode()?;
334        let reliable_sequence_number = self.decode()?;
335        let msg_len = length.checked_sub(size_of::<ReliableCommand>() as u32)
336            .map_or(Err(PhotonDecodeError::from("Invalid ReliableCommand length")), |v| Ok(v))?;
337        Ok(ReliableCommand {
338            channel_id,
339            flags,
340            reserved_byte,
341            msg_len,
342            reliable_sequence_number,
343        })
344    }
345}
346
347impl Decode<UnreliableCommand> for PhotonCursor<'_> {
348    fn decode(&mut self) -> PhotonDecodeResult<UnreliableCommand> {
349        let mut reliable_command: ReliableCommand = self.decode()?;
350        let unknown = self.decode()?;
351        reliable_command.msg_len = reliable_command.msg_len.checked_sub(size_of::<u32>() as u32)
352            .map_or(Err(PhotonDecodeError::from("Invalid UnreliableCommand length")), |v| Ok(v))?;
353        Ok(UnreliableCommand {
354            reliable_command,
355            unknown,
356        })
357    }
358}
359
360impl Decode<ReliableFragment> for PhotonCursor<'_> {
361    fn decode(&mut self) -> PhotonDecodeResult<ReliableFragment> {
362        let mut reliable_command: ReliableCommand = self.decode()?;
363        let sequence_number = self.decode()?;
364        let fragment_count = self.decode()?;
365        let fragment_number = self.decode()?;
366        let total_length = self.decode()?;
367        let operation_length = self.decode()?;
368
369        reliable_command.msg_len = reliable_command.msg_len.checked_sub((size_of::<u32>() * 5) as u32)
370            .map_or(Err(PhotonDecodeError::from("Invalid ReliableFragment length")), |v| Ok(v))?;
371        let mut payload = vec![0u8; reliable_command.msg_len as usize];
372        self.read_exact(&mut payload)
373            .map_err(|e| PhotonDecodeError::from(format!("{}", e)))?;
374
375        Ok(ReliableFragment {
376            reliable_command,
377            sequence_number,
378            fragment_count,
379            fragment_number,
380            total_length,
381            operation_length,
382            payload,
383        })
384    }
385}
386
387impl Decode<Command> for PhotonCursor<'_> {
388    fn decode(&mut self) -> PhotonDecodeResult<Command> {
389        let cmd_type_id: u8 = self.decode()?;
390        match cmd_type_id {
391            4 => Ok(Command::LogOut),
392            6 => Ok(Command::SendReliable(self.decode()?)),
393            7 => Ok(Command::SendUnreliable(
394                Decode::<UnreliableCommand>::decode(self)?.reliable_command,
395            )),
396            8 => Ok(Command::SendReliableFragment(self.decode()?)),
397            _ => Ok(Command::SendReliable(self.decode()?)),
398        }
399    }
400}
401
402pub enum TypeCode {
403    None = 0x00,
404    Null = 0x2A,
405    Dictionary = 0x44,
406    StringArray = 0x61,
407    Byte = 0x62,
408    Double = 0x64,
409    EventData = 0x65,
410    Float = 0x66,
411    Integer = 0x69,
412    Short = 0x6B,
413    Long = 0x6C,
414    BooleanArray = 0x6E,
415    Boolean = 0x6F,
416    OperationResponse = 0x70,
417    OperationRequest = 0x71,
418    String = 0x73,
419    ByteArray = 0x78,
420    Array = 0x79,
421    ObjectArray = 0x7A,
422    Unknown,
423}
424
425impl From<u8> for TypeCode {
426    fn from(v: u8) -> Self {
427        match v {
428            0x00 => TypeCode::None,
429            0x2A => TypeCode::Null,
430            0x44 => TypeCode::Dictionary,
431            0x61 => TypeCode::StringArray,
432            0x62 => TypeCode::Byte,
433            0x64 => TypeCode::Double,
434            0x65 => TypeCode::EventData,
435            0x66 => TypeCode::Float,
436            0x69 => TypeCode::Integer,
437            0x6B => TypeCode::Short,
438            0x6C => TypeCode::Long,
439            0x6E => TypeCode::BooleanArray,
440            0x6F => TypeCode::Boolean,
441            0x70 => TypeCode::OperationResponse,
442            0x71 => TypeCode::OperationRequest,
443            0x73 => TypeCode::String,
444            0x78 => TypeCode::ByteArray,
445            0x79 => TypeCode::Array,
446            0x7A => TypeCode::ObjectArray,
447            _ => TypeCode::Unknown,
448        }
449    }
450}
451
452impl std::ops::Index<usize> for Value {
453    type Output = Value;
454
455    fn index(&self, index: usize) -> &Self::Output {
456        match self {
457            Value::Array(v) => &v[index],
458            _ => panic!("Non indexable type"),
459        }
460    }
461}
462
463impl std::fmt::Display for Value {
464    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465        match self {
466            Value::String(v) => write!(f, "{}", v),
467            Value::Byte(v) => write!(f, "{}", v),
468            Value::Integer(v) => write!(f, "{}", v),
469            v => write!(f, "{:?}", v),
470        }
471    }
472}