Skip to content

Commit

Permalink
💥 Hide raw payloads behind the feature flag, and improve the performance
Browse files Browse the repository at this point in the history
  • Loading branch information
eigenein committed May 8, 2023
1 parent 2d2c85c commit a177447
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 45 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ categories = ["parsing"]

[features]
default = []
meta = ["dep:serde_json"]
meta = ["dep:serde_json"] # `meta.json` parsing
raw-payload = [] # save raw packet payloads, enabling increases memory usage and decreases performance

[dependencies]
bytes = "1.4.0"
Expand Down
35 changes: 12 additions & 23 deletions src/models/data/entity_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,37 @@ pub mod update_arena;
#[serde_as]
#[derive(Debug, Serialize)]
pub enum EntityMethod {
/// Subtype `0x2F`.
/// Subtype 47.
UpdateArena {
field_number: u64,
arguments: UpdateArena,

/// Original payload for investigation.
#[serde_as(as = "serde_with::hex::Hex")]
payload: Vec<u8>,
},

/// Default variant when subtype is not known by the parser.
Unknown {
sub_type: u32,

/// Whole packet payload (including the sub-type).
#[serde_as(as = "serde_with::hex::Hex")]
payload: Vec<u8>,
},
Unknown { sub_type: u32 },
}

impl EntityMethod {
/// Parse the entity method payload.
pub fn new(payload: Vec<u8>) -> Result<Self> {
let mut reader = payload.as_slice();
pub fn new(payload: &[u8]) -> Result<Self> {
let mut payload = payload;

reader.read_u32::<LittleEndian>()?;
let sub_type = reader.read_u32::<LittleEndian>()?;
payload.read_u32::<LittleEndian>()?;
let sub_type = payload.read_u32::<LittleEndian>()?;

let this = match sub_type {
0x2F => {
let _inner_length = reader.read_u32::<LittleEndian>()?;
47 => {
let _inner_length = payload.read_u32::<LittleEndian>()?;

let field_number = decode_varint(&mut reader)?;
let message_length = read_quirky_length(&mut reader)?;
let field_number = decode_varint(&mut payload)?;
let message_length = read_quirky_length(&mut payload)?;
Self::UpdateArena {
field_number,
arguments: UpdateArena::decode(&reader[..message_length])?,
payload,
arguments: UpdateArena::decode(&payload[..message_length])?,
}
}

_ => Self::Unknown { sub_type, payload },
_ => Self::Unknown { sub_type },
};
Ok(this)
}
Expand Down
15 changes: 13 additions & 2 deletions src/models/data/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ use std::io::Read;

use byteorder::{LittleEndian, ReadBytesExt};
use serde::Serialize;
use serde_with::serde_as;

use crate::models::data::payload::Payload;
use crate::result::Result;

#[serde_as]
#[derive(Debug, Serialize)]
pub struct Packet {
pub clock: f32,
pub payload: Payload,

#[cfg(feature = "raw-payload")]
#[serde_as(as = "serde_with::hex::Hex")]
pub raw_payload: Vec<u8>,
}

impl Packet {
Expand All @@ -18,8 +24,13 @@ impl Packet {
let type_ = reader.read_u32::<LittleEndian>()?;
let clock = reader.read_f32::<LittleEndian>()?;
let payload = Self::read_payload(reader, length as usize)?;
let payload = Payload::new(type_, payload)?;
let this = Self { clock, payload };
let this = Self {
clock,
payload: Payload::new(type_, &payload)?,

#[cfg(feature = "raw-payload")]
raw_payload: payload,
};
Ok(Some(this))
}

Expand Down
33 changes: 14 additions & 19 deletions src/models/data/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,27 @@ pub enum Payload {
EntityMethod(EntityMethod),

/// Default payload when type is not known by the parser.
Unknown {
packet_type: u32,

/// Whole packet payload.
#[serde_as(as = "serde_with::hex::Hex")]
raw: Vec<u8>,
},
Unknown { packet_type: u32 },
}

impl Payload {
/// Parse the packet payload.
pub fn new(packet_type: u32, payload: Vec<u8>) -> Result<Self> {
pub fn new(packet_type: u32, payload: &[u8]) -> Result<Self> {
let mut payload = payload;

let this = match packet_type {
0 => {
let mut reader = payload.as_slice();
reader.read_exact(&mut [0; 10])?;

let author_nickname = read_string(&mut reader)?;
let arena_unique_id = reader.read_u64::<LittleEndian>()?;
let arena_type_id = reader.read_u32::<LittleEndian>()?;
let type_0 = {
let pickled_length = read_quirky_length(&mut reader)?;
read_pickled(&mut reader, pickled_length)?
payload.read_exact(&mut [0; 10])?;

let author_nickname = read_string(&mut payload)?;
let arena_unique_id = payload.read_u64::<LittleEndian>()?;
let arena_type_id = payload.read_u32::<LittleEndian>()?;
let arguments = {
let pickled_length = read_quirky_length(&mut payload)?;
read_pickled(&mut payload, pickled_length)?
};
Self::BasePlayerCreate {
arguments: type_0,
arguments,
author_nickname,
arena_unique_id,
arena_type_id,
Expand All @@ -59,7 +54,7 @@ impl Payload {

8 => Self::EntityMethod(EntityMethod::new(payload)?),

_ => Self::Unknown { raw: payload, packet_type },
_ => Self::Unknown { packet_type },
};
Ok(this)
}
Expand Down

0 comments on commit a177447

Please sign in to comment.