New: initial functionality

This commit is contained in:
Pavel Perestoronin committed 2022-12-02 23:56:42 +01:00
1 parent 31b3c21b65
commit 3e5ad63679
19 files changed
+309 -1

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("failed to open the ZIP-archive")]
OpenArchiveFailed(#[source] zip::result::ZipError),
#[error("failed to open the battle results entry in the replay archive")]
OpenBattleResultsFailed(#[source] zip::result::ZipError),
#[error("failed to read the archive entry")]
ReadEntryFailed(#[source] std::io::Error),
#[error("failed to decode")]
DecodeFailed(#[source] prost::DecodeError),
#[error("failed to un-pickle")]
UnpickleFailed(#[source] serde_pickle::Error),
}
+8
View File
@@ -0,0 +1,8 @@
mod error;
pub mod models;
mod replay;
mod result;
pub use crate::error::Error;
pub use crate::replay::Replay;
pub use crate::result::Result;
+31
View File
@@ -0,0 +1,31 @@
use ::prost::Message;
#[derive(Message)]
pub struct BattleResults {
#[prost(int64, tag = "2")]
pub timestamp: i64,
#[prost(message, repeated, tag = "201")]
pub players: Vec<Player>,
}
#[derive(Message)]
pub struct Player {
#[prost(uint32, tag = "1")]
pub account_id: u32,
#[prost(message, required, tag = "2")]
pub info: PlayerInfo,
}
#[derive(Message)]
pub struct PlayerInfo {
#[prost(string, tag = "1")]
pub nickname: String,
#[prost(uint32, optional, tag = "2")]
pub platoon_id: Option<u32>,
#[prost(uint32, tag = "3")]
pub team_number: u32,
}
+35
View File
@@ -0,0 +1,35 @@
use std::io::{Read, Seek};
use prost::Message;
use serde_bytes::ByteBuf;
use zip::ZipArchive;
use crate::error::Error;
use crate::models::BattleResults;
use crate::result::Result;
pub struct Replay<R>(pub(crate) ZipArchive<R>);
impl<R: Read + Seek> Replay<R> {
/// Opens a replay from the reader.
pub fn open(reader: R) -> Result<Self> {
ZipArchive::new(reader)
.map_err(Error::OpenArchiveFailed)
.map(Self)
}
pub fn read_battle_results(&mut self) -> Result<BattleResults> {
let mut pickled_battle_results = self
.0
.by_name("battle_results.dat")
.map_err(Error::OpenBattleResultsFailed)?;
let mut serialized_battle_results = Vec::new();
pickled_battle_results
.read_to_end(&mut serialized_battle_results)
.map_err(Error::ReadEntryFailed)?;
let (_, battle_results): (u64, ByteBuf) =
serde_pickle::from_slice(&serialized_battle_results, Default::default())
.map_err(Error::UnpickleFailed)?;
BattleResults::decode(battle_results.as_ref()).map_err(Error::DecodeFailed)
}
}
+3
View File
@@ -0,0 +1,3 @@
use crate::error::Error;
pub type Result<T = ()> = std::result::Result<T, Error>;