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}