diff --git a/README.md b/README.md index 2884467..da7a252 100644 --- a/README.md +++ b/README.md @@ -36,26 +36,3 @@ fn main() -> Result<()> { Ok(()) } ``` - -## Replay structure - -`*.wotbreplay` is a ZIP-archive containing: -- `battle_results.dat` -- `meta.json` -- `data.wotreplay` - -### `battle_results.dat` - -This is a [pickled](https://docs.python.org/3/library/pickle.html) 2-tuple: -- Some big number -- Battle results serialized with [Protocol Buffers](https://developers.google.com/protocol-buffers) - -#### Useful tools - -- [Protobuf Decoder](https://protobuf-decoder.netlify.app/) -- [`protobuf-inspector`](https://github.com/mildsunrise/protobuf-inspector) -- [Hex Fiend](https://hexfiend.com/) - -### `meta.json` - -### `data.wotreplay` diff --git a/src/models/battle_results.rs b/src/models/battle_results.rs index a8c61cd..484574e 100644 --- a/src/models/battle_results.rs +++ b/src/models/battle_results.rs @@ -7,7 +7,10 @@ use crate::result::Result; impl BattleResults { /// Parse battle results from the buffer. /// - /// Note, that this does NOT parse `battle_results.dat` itself, but the un-pickled tuple element. + /// # Note + /// + /// This does **not** parse `battle_results.dat` itself, but the un-pickled tuple element. + /// To parse `battle_results.dat`, use [`crate::models::battle_results_dat::BattleResultsDat`]. pub fn from_buffer(buffer: impl Buf) -> Result { Ok(Self::decode(buffer)?) } diff --git a/src/models/battle_results_dat.rs b/src/models/battle_results_dat.rs index 7ac0f95..cfd8c98 100644 --- a/src/models/battle_results_dat.rs +++ b/src/models/battle_results_dat.rs @@ -8,7 +8,14 @@ use crate::error::Error; use crate::models::battle_results::BattleResults; use crate::result::Result; -/// Represents un-pickled `battle_results.dat`. +/// Un-pickled `battle_results.dat`. +/// +/// # `battle_results.dat` structure +/// +/// Entire file is a [pickled](https://docs.python.org/3/library/pickle.html) 2-tuple: +/// +/// - Arena unique ID +/// - Battle results serialized with [Protocol Buffers](https://developers.google.com/protocol-buffers) #[derive(Debug, Deserialize)] #[serde(from = "(u64, ByteBuf)")] pub struct BattleResultsDat { @@ -20,15 +27,12 @@ pub struct BattleResultsDat { impl From<(u64, ByteBuf)> for BattleResultsDat { fn from((arena_unique_id, buffer): (u64, ByteBuf)) -> Self { - Self { - arena_unique_id, - buffer, - } + Self { arena_unique_id, buffer } } } impl BattleResultsDat { - /// Parses the pickled structure from the reader which contains `battle_results.dat`. + /// Parse the pickled structure from the reader which contains `battle_results.dat`. /// /// It can be used either on the `battle_results.dat` for a replay archive, /// or directly on `**/DAVAProject/battle_results/*/*_full.dat`. @@ -40,7 +44,7 @@ impl BattleResultsDat { impl TryInto for BattleResultsDat { type Error = Error; - /// Decodes the battle results from the internal buffer. + /// Decode the battle results from the internal buffer. fn try_into(self) -> Result { Ok(BattleResults::decode(self.buffer.as_ref())?) } diff --git a/src/models/data/entity_method.rs b/src/models/data/entity_method.rs index 586657e..ccea881 100644 --- a/src/models/data/entity_method.rs +++ b/src/models/data/entity_method.rs @@ -1,3 +1,5 @@ +//! Structures for «entity method» call packets. + use byteorder::{LittleEndian, ReadBytesExt}; use prost::encoding::decode_varint; use prost::Message; diff --git a/src/models/data/payload.rs b/src/models/data/payload.rs index f19b763..b803d23 100644 --- a/src/models/data/payload.rs +++ b/src/models/data/payload.rs @@ -9,6 +9,7 @@ use crate::models::data::entity_method::EntityMethod; use crate::models::data::{read_pickled, read_quirky_length, read_string}; use crate::result::Result; +/// Packet payload. #[serde_as] #[derive(Debug, Serialize)] pub enum Payload { @@ -25,7 +26,7 @@ pub enum Payload { /// Default payload when type is not known by the parser. Unknown { - type_: u32, + packet_type: u32, /// Whole packet payload. #[serde_as(as = "serde_with::hex::Hex")] @@ -34,8 +35,9 @@ pub enum Payload { } impl Payload { - pub fn new(type_: u32, payload: Vec) -> Result { - let this = match type_ { + /// Parse the packet payload. + pub fn new(packet_type: u32, payload: Vec) -> Result { + let this = match packet_type { 0 => { let mut reader = payload.as_slice(); reader.read_exact(&mut [0; 10])?; @@ -57,7 +59,7 @@ impl Payload { 8 => Self::EntityMethod(EntityMethod::new(payload)?), - _ => Self::Unknown { raw: payload, type_ }, + _ => Self::Unknown { raw: payload, packet_type }, }; Ok(this) } diff --git a/src/replay.rs b/src/replay.rs index 1b3d215..89ad361 100644 --- a/src/replay.rs +++ b/src/replay.rs @@ -9,7 +9,15 @@ use crate::models::data::Data; use crate::models::meta::Meta; use crate::result::Result; -/// Opened (but not yet parsed) replay. +/// World of Tanks Blitz replay. +/// +/// # Replay structure +/// +/// `*.wotbreplay` is a ZIP-archive containing: +/// +/// - `battle_results.dat` +/// - `meta.json` +/// - `data.wotreplay` pub struct Replay(pub(crate) ZipArchive); impl Replay { @@ -18,22 +26,24 @@ impl Replay { Ok(Self(ZipArchive::new(reader)?)) } - /// Reads and parses the battle results from the replay. + /// Read and parse the full battle results structure from `battle_results.dat`. pub fn read_battle_results(&mut self) -> Result { self.read_battle_results_dat()?.try_into() } - /// Reads and parses the included `battle_results.dat`. + /// Read and parse the root 2-tuple from `battle_results.dat`. pub fn read_battle_results_dat(&mut self) -> Result { let pickled_battle_results = self.0.by_name("battle_results.dat")?; BattleResultsDat::from_reader(pickled_battle_results) } + /// Read and parse the included `meta.json`. #[cfg(feature = "meta")] pub fn read_meta(&mut self) -> Result { Meta::from_reader(self.0.by_name("meta.json")?) } + /// Read and parse the included `data.wotreplay`. pub fn read_data(&mut self) -> Result { Data::from_reader(self.0.by_name("data.wotreplay")?) }