From a177447ca11a9f5c2dc3805f7f57eceea6aaa01e Mon Sep 17 00:00:00 2001 From: Pavel Perestoronin Date: Mon, 8 May 2023 23:00:40 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20Hide=20raw=20payloads=20behind?= =?UTF-8?q?=20the=20feature=20flag,=20and=20improve=20the=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 3 ++- src/models/data/entity_method.rs | 35 +++++++++++--------------------- src/models/data/packet.rs | 15 ++++++++++++-- src/models/data/payload.rs | 31 ++++++++++++---------------- 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c6e02c9..ab2dbc2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/models/data/entity_method.rs b/src/models/data/entity_method.rs index ccea881..2dcfaee 100644 --- a/src/models/data/entity_method.rs +++ b/src/models/data/entity_method.rs @@ -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, }, /// 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, - }, + Unknown { sub_type: u32 }, } impl EntityMethod { /// Parse the entity method payload. - pub fn new(payload: Vec) -> Result { - let mut reader = payload.as_slice(); + pub fn new(payload: &[u8]) -> Result { + let mut payload = payload; - reader.read_u32::()?; - let sub_type = reader.read_u32::()?; + payload.read_u32::()?; + let sub_type = payload.read_u32::()?; let this = match sub_type { - 0x2F => { - let _inner_length = reader.read_u32::()?; + 47 => { + let _inner_length = payload.read_u32::()?; - 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) } diff --git a/src/models/data/packet.rs b/src/models/data/packet.rs index 18489d6..0ad0302 100644 --- a/src/models/data/packet.rs +++ b/src/models/data/packet.rs @@ -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, } impl Packet { @@ -18,8 +24,13 @@ impl Packet { let type_ = reader.read_u32::()?; let clock = reader.read_f32::()?; 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)) } diff --git a/src/models/data/payload.rs b/src/models/data/payload.rs index b803d23..4078f3e 100644 --- a/src/models/data/payload.rs +++ b/src/models/data/payload.rs @@ -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, - }, + Unknown { packet_type: u32 }, } impl Payload { /// Parse the packet payload. - pub fn new(packet_type: u32, payload: Vec) -> Result { + pub fn new(packet_type: u32, payload: &[u8]) -> Result { + let mut payload = payload; + let this = match packet_type { 0 => { - let mut reader = payload.as_slice(); - reader.read_exact(&mut [0; 10])?; + payload.read_exact(&mut [0; 10])?; - let author_nickname = read_string(&mut reader)?; - let arena_unique_id = reader.read_u64::()?; - let arena_type_id = reader.read_u32::()?; - let type_0 = { - let pickled_length = read_quirky_length(&mut reader)?; - read_pickled(&mut reader, pickled_length)? + let author_nickname = read_string(&mut payload)?; + let arena_unique_id = payload.read_u64::()?; + let arena_type_id = payload.read_u32::()?; + 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, @@ -59,7 +54,7 @@ impl Payload { 8 => Self::EntityMethod(EntityMethod::new(payload)?), - _ => Self::Unknown { raw: payload, packet_type }, + _ => Self::Unknown { packet_type }, }; Ok(this) }