wotbreplay_parser/models/
data.rs1pub mod base_player_create;
4pub mod entity_method;
5pub mod packet;
6pub mod payload;
7
8use std::io::Read;
9
10use byteorder::{LittleEndian, ReadBytesExt};
11use serde::de::DeserializeOwned;
12use serde::Serialize;
13
14use crate::models::data::packet::Packet;
15use crate::result::Result;
16use crate::Error;
17
18#[derive(Debug, Serialize)]
20pub struct Data {
21 pub client_version: String,
23
24 pub packets: Vec<Packet>,
25}
26
27impl Data {
28 pub fn from_reader(mut reader: impl Read) -> Result<Self> {
29 assert_magic(reader.read_u32::<LittleEndian>()?, 0x12345678)?;
30
31 reader.read_u64::<LittleEndian>()?;
33
34 read_length_delimited(&mut reader)?;
36
37 let client_version = read_string(&mut reader)?;
38
39 reader.read_u8()?;
41
42 let mut packets = Vec::new();
43 while let Some(packet) = Packet::from_reader(&mut reader)? {
44 packets.push(packet);
45 }
46
47 Ok(Self { client_version, packets })
48 }
49}
50
51#[inline]
52fn assert_magic<T: Into<u32> + PartialEq>(actual: T, expected: T) -> Result {
53 if actual == expected {
54 Ok(())
55 } else {
56 Err(Error::InvalidMagic {
57 actual: actual.into(),
58 expected: expected.into(),
59 })
60 }
61}
62
63#[inline]
64fn read_length_delimited(reader: &mut impl Read) -> Result<Vec<u8>> {
65 let length = reader.read_u8()? as usize;
66 let mut buffer = vec![0; length];
67 reader.read_exact(&mut buffer)?;
68 Ok(buffer)
69}
70
71#[inline]
72fn read_string(reader: &mut impl Read) -> Result<String> {
73 Ok(String::from_utf8(read_length_delimited(reader)?)?)
74}
75
76#[inline]
77fn read_pickled<T: DeserializeOwned>(reader: &mut impl Read, length: usize) -> Result<T> {
78 let mut buffer = vec![0; length];
79 reader.read_exact(&mut buffer)?;
80 Ok(serde_pickle::from_slice(&buffer, Default::default())?)
81}
82
83#[inline]
92fn read_quirky_length(reader: &mut impl Read) -> Result<usize> {
93 match reader.read_u8()? {
94 0xFF => {
95 let length = reader.read_u16::<LittleEndian>()?;
96 assert_magic(reader.read_u8()?, 0x00)?;
97 Ok(length as usize)
98 }
99 length => Ok(length as usize),
100 }
101}