Compare commits

..
11 changed files with 126 additions and 23 deletions

No files matched your search

+6
View File
@@ -49,3 +49,9 @@ jobs:
with: with:
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
args: --all-targets --all-features --tests -- -D warnings args: --all-targets --all-features --tests -- -D warnings
- name: Publish the crates (dry run)
run: |
cargo publish --allow-dirty --dry-run
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
-1
View File
@@ -45,7 +45,6 @@ jobs:
- name: Publish the crates - name: Publish the crates
run: | run: |
cargo login
cargo publish --allow-dirty cargo publish --allow-dirty
env: env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+4 -5
View File
@@ -4,7 +4,7 @@ World of Tanks Blitz replay parser in Rust.
[![Crates.io](https://img.shields.io/crates/v/wotbreplay-parser)](https://crates.io/crates/wotbreplay-parser) [![Crates.io](https://img.shields.io/crates/v/wotbreplay-parser)](https://crates.io/crates/wotbreplay-parser)
[![Last commit](https://img.shields.io/github/last-commit/eigenein/wotbreplay-parser)](https://github.com/eigenein/wotbreplay-parser/commits/main) [![Last commit](https://img.shields.io/github/last-commit/eigenein/wotbreplay-parser)](https://github.com/eigenein/wotbreplay-parser/commits/main)
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/eigenein/wotbreplay-parser/Check)](https://github.com/eigenein/wotbreplay-parser/actions) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/eigenein/wotbreplay-parser/check.yaml)](https://github.com/eigenein/wotbreplay-parser/actions)
![License: MIT](https://img.shields.io/crates/l/wotbreplay-parser) ![License: MIT](https://img.shields.io/crates/l/wotbreplay-parser)
[![docs.rs](https://img.shields.io/docsrs/wotbreplay-parser)](https://docs.rs/wotbreplay-parser) [![docs.rs](https://img.shields.io/docsrs/wotbreplay-parser)](https://docs.rs/wotbreplay-parser)
@@ -14,8 +14,7 @@ World of Tanks Blitz replay parser in Rust.
use std::fs::File; use std::fs::File;
use anyhow::Result; use anyhow::Result;
use wotbreplay_parser::Replay; use wotbreplay_parser::prelude::*;
use wotbreplay_parser::models::TeamNumber;
fn main() -> Result<()> { fn main() -> Result<()> {
let battle_results = Replay::open(File::open("tests/replays/battle_results.wotbreplay")?)? let battle_results = Replay::open(File::open("tests/replays/battle_results.wotbreplay")?)?
@@ -26,11 +25,11 @@ fn main() -> Result<()> {
assert_eq!(battle_results.players[0].account_id, 520886428); assert_eq!(battle_results.players[0].account_id, 520886428);
assert_eq!(battle_results.players[0].info.nickname, "77mmmr"); assert_eq!(battle_results.players[0].info.nickname, "77mmmr");
assert_eq!(battle_results.players[0].info.team_number(), TeamNumber::Two); assert_eq!(battle_results.players[0].info.team(), TeamNumber::Two);
assert_eq!(battle_results.players[0].info.platoon_id, None); assert_eq!(battle_results.players[0].info.platoon_id, None);
assert_eq!(battle_results.players[1].info.nickname, "SNAK_THE_RIPPER"); assert_eq!(battle_results.players[1].info.nickname, "SNAK_THE_RIPPER");
assert_eq!(battle_results.players[1].info.team_number(), TeamNumber::One); assert_eq!(battle_results.players[1].info.team(), TeamNumber::One);
assert_eq!(battle_results.players[1].info.platoon_id, Some(547466834)); assert_eq!(battle_results.players[1].info.platoon_id, Some(547466834));
Ok(()) Ok(())
+8 -10
View File
@@ -2,23 +2,21 @@
#![warn( #![warn(
clippy::all, clippy::all,
clippy::missing_const_for_fn,
clippy::trivially_copy_pass_by_ref,
clippy::map_unwrap_or,
clippy::explicit_into_iter_loop, clippy::explicit_into_iter_loop,
clippy::unused_self, clippy::manual_let_else,
clippy::needless_pass_by_value clippy::map_unwrap_or,
clippy::missing_const_for_fn,
clippy::needless_pass_by_value,
clippy::trivially_copy_pass_by_ref,
clippy::unused_self
)] )]
mod error; mod error;
pub mod models; mod models;
pub mod prelude;
mod replay; mod replay;
mod result; mod result;
pub use crate::error::Error;
pub use crate::replay::Replay;
pub use crate::result::Result;
#[cfg(doctest)] #[cfg(doctest)]
mod test_readme { mod test_readme {
macro_rules! external_doc_test { macro_rules! external_doc_test {
+55 -3
View File
@@ -9,7 +9,7 @@ impl BattleResults {
/// Parse battle results from the buffer. /// Parse battle results from the buffer.
/// ///
/// Note, that this does NOT parse `battle_results.dat` itself, but the un-pickled tuple element. /// Note, that this does NOT parse `battle_results.dat` itself, but the un-pickled tuple element.
pub fn parse(buffer: impl Buf) -> Result<Self> { pub fn from_buffer(buffer: impl Buf) -> Result<Self> {
Self::decode(buffer).map_err(Error::DecodeFailed) Self::decode(buffer).map_err(Error::DecodeFailed)
} }
} }
@@ -21,6 +21,17 @@ pub struct BattleResults {
#[prost(int64, tag = "2")] #[prost(int64, tag = "2")]
pub timestamp: i64, pub timestamp: i64,
#[prost(enumeration = "TeamNumber", tag = "3")]
pub winning_team: i32,
/// Replay's author results.
#[prost(message, required, tag = "8")]
pub author: Author,
/// Author's free XP, including premium.
#[prost(uint32, tag = "137")]
pub free_xp: u32,
/// Players in the battle. /// Players in the battle.
#[prost(message, repeated, tag = "201")] #[prost(message, repeated, tag = "201")]
pub players: Vec<Player>, pub players: Vec<Player>,
@@ -57,10 +68,13 @@ pub struct PlayerInfo {
/// Player's team assignment. /// Player's team assignment.
#[prost(enumeration = "TeamNumber", tag = "3")] #[prost(enumeration = "TeamNumber", tag = "3")]
pub team_number: i32, pub team: i32,
#[prost(string, optional, tag = "5")] #[prost(string, optional, tag = "5")]
pub clan_tag: Option<String>, pub clan_tag: Option<String>,
#[prost(message, required, tag = "7")]
pub avatar: Avatar,
} }
#[derive( #[derive(
@@ -90,7 +104,7 @@ pub struct PlayerResults {
pub struct PlayerResultsInfo { pub struct PlayerResultsInfo {
/// Credits earned – without special awards and medals and premium account excluded. /// Credits earned – without special awards and medals and premium account excluded.
#[prost(uint32, tag = "2")] #[prost(uint32, tag = "2")]
pub credits: u32, pub credits_earned: u32,
/// Base XP (the total without multipliers). /// Base XP (the total without multipliers).
#[prost(uint32, tag = "3")] #[prost(uint32, tag = "3")]
@@ -163,3 +177,41 @@ impl PlayerResultsInfo {
.map(|mm_rating| (mm_rating * 10.0 + 3000.0) as u32) .map(|mm_rating| (mm_rating * 10.0 + 3000.0) as u32)
} }
} }
#[derive(Message, Serialize)]
pub struct Author {
/// Earned credits, including premium and special awards and medals.
#[prost(uint32, tag = "2")]
pub credits_earned: u32,
/// Combat XP, including premium.
#[prost(uint32, tag = "3")]
pub combat_xp: u32,
#[prost(uint32, tag = "8")]
pub damage_dealt: u32,
#[prost(uint32, tag = "101")]
pub account_id: u32,
#[prost(enumeration = "TeamNumber", tag = "102")]
pub team_number: i32,
}
#[derive(Message, Serialize)]
pub struct Avatar {
#[prost(message, required, tag = "2")]
pub info: AvatarInfo,
}
#[derive(Message, Serialize)]
pub struct AvatarInfo {
#[prost(string, tag = "2")]
pub gfx_url: String,
#[prost(string, tag = "3")]
pub gfx2_url: String,
#[prost(string, tag = "4")]
pub kind: String,
}
+10 -1
View File
@@ -4,8 +4,9 @@ use prost::Message;
use serde::Deserialize; use serde::Deserialize;
use serde_bytes::ByteBuf; use serde_bytes::ByteBuf;
use crate::error::Error;
use crate::models::BattleResults; use crate::models::BattleResults;
use crate::{Error, Result}; use crate::result::Result;
/// Represents un-pickled `battle_results.dat`. /// Represents un-pickled `battle_results.dat`.
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@@ -29,3 +30,11 @@ impl BattleResultsDat {
BattleResults::decode(self.1.as_ref()).map_err(Error::DecodeFailed) BattleResults::decode(self.1.as_ref()).map_err(Error::DecodeFailed)
} }
} }
impl TryInto<BattleResults> for BattleResultsDat {
type Error = Error;
fn try_into(self) -> Result<BattleResults> {
self.decode_battle_results()
}
}
+4
View File
@@ -0,0 +1,4 @@
pub use crate::error::Error;
pub use crate::models::*;
pub use crate::replay::Replay;
pub use crate::result::Result;
+38 -3
View File
@@ -1,7 +1,7 @@
use std::fs::File; use std::fs::File;
use anyhow::Result; use anyhow::Result;
use wotbreplay_parser::Replay; use wotbreplay_parser::prelude::*;
#[test] #[test]
fn player_results_ok() -> Result<()> { fn player_results_ok() -> Result<()> {
@@ -37,7 +37,7 @@ fn player_results_ok() -> Result<()> {
assert_eq!(zeekrab_info.victory_points_earned, 40); assert_eq!(zeekrab_info.victory_points_earned, 40);
assert_eq!(zeekrab_info.victory_points_seized, 40); assert_eq!(zeekrab_info.victory_points_seized, 40);
assert_eq!(zeekrab_info.tank_id, 26657); assert_eq!(zeekrab_info.tank_id, 26657);
assert_eq!(zeekrab_info.credits, 37679); assert_eq!(zeekrab_info.credits_earned, 37679);
assert_eq!(zeekrab_info.n_enemies_damaged, 2); assert_eq!(zeekrab_info.n_enemies_damaged, 2);
assert_eq!(zeekrab_info.n_enemies_destroyed, 1); assert_eq!(zeekrab_info.n_enemies_destroyed, 1);
@@ -67,12 +67,23 @@ fn player_results_ok() -> Result<()> {
} }
#[test] #[test]
fn clan_tags_ok() -> Result<()> { fn player_info_ok() -> Result<()> {
let battle_results = Replay::open(File::open("tests/replays/player_results.wotbreplay")?)? let battle_results = Replay::open(File::open("tests/replays/player_results.wotbreplay")?)?
.read_battle_results()?; .read_battle_results()?;
assert_eq!(battle_results.players[1].info.clan_tag.as_deref(), Some("AN0NY")); assert_eq!(battle_results.players[1].info.clan_tag.as_deref(), Some("AN0NY"));
assert_eq!(battle_results.players[10].info.clan_tag.as_deref(), Some("BBS")); assert_eq!(battle_results.players[10].info.clan_tag.as_deref(), Some("BBS"));
assert_eq!(battle_results.players[10].info.avatar.info.kind, "legendary");
assert_eq!(
battle_results.players[10].info.avatar.info.gfx_url,
"https://stufficons.wgcdn.co/Gfx/avatar_UFO_legendary_anim/220523_104739_752791.webp"
);
assert_eq!(
battle_results.players[10].info.avatar.info.gfx2_url,
"https://stufficons.wgcdn.co/Gfx2/avatar_UFO_legendary_anim/220523_104755_251331.webp"
);
assert_eq!(battle_results.players[11].info.clan_tag, None); assert_eq!(battle_results.players[11].info.clan_tag, None);
Ok(()) Ok(())
@@ -94,3 +105,27 @@ fn victory_points_ok() -> Result<()> {
Ok(()) Ok(())
} }
#[test]
fn winning_team_ok() -> Result<()> {
let battle_results = Replay::open(File::open("tests/replays/winning_team.wotbreplay")?)?
.read_battle_results()?;
assert_eq!(battle_results.winning_team(), TeamNumber::One);
Ok(())
}
#[test]
fn author_results_ok() -> Result<()> {
let battle_results = Replay::open(File::open("tests/replays/author_results.wotbreplay")?)?
.read_battle_results()?;
assert_eq!(battle_results.author.credits_earned, 53623);
assert_eq!(battle_results.author.combat_xp, 2370);
assert_eq!(battle_results.author.damage_dealt, 1738);
assert_eq!(battle_results.author.account_id, 594778041);
assert_eq!(battle_results.free_xp, 116);
Ok(())
}
+1
View File
@@ -0,0 +1 @@
*.wotbreplay linguist-generated
Binary file not shown.
Binary file not shown.