From 6f049aa5e1524169b302db4c6b8b9f5edb82df87 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Fri, 12 Nov 2021 17:42:32 +0100 Subject: Fix player name parsing logic The old code seemed to choke on WvW players, as the subgroup-calculating code did 0 - b'0', which underflowed. The proper way to parse a subgroup is not to take a single character anyway, because subgroups can be bigger than 10. The new code fixes that by properly extracting the "subgroup str literal" and then parsing it as an integer, with some special logic to detect an "empty" subgroup as it is in WvW. --- CHANGELOG.md | 4 ++++ src/agent.rs | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 512fa23..9b916e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ All notable changes to this project will be documented in this file. - Boss and encounter definitions for the training golems (`StandardKittyGolem`, `MediumKittyGolem`, `LargeKittyGolem`) +### Fixed +- `evtclib` will no longer choke on WvW logs where player names might not contain the expected + information. + ## 0.5.0 - 2020-10-07 ### Added - `Boss::Ai` to represent Ai, Keeper of the Peak in the Sunqua Peak fractal. diff --git a/src/agent.rs b/src/agent.rs index 60c16e3..4dece3e 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -39,6 +39,8 @@ pub struct Player { impl Player { /// The player's character name. + /// + /// **Note**: Hostile WvW agents will have a randomly generated player name. pub fn character_name(&self) -> &str { &self.character_name } @@ -46,6 +48,8 @@ impl Player { /// The player's account name. /// /// This includes the leading colon and the 4-digit denominator. + /// + /// **Note**: Hostile WvW agents will have an empty account name. pub fn account_name(&self) -> &str { &self.account_name } @@ -158,10 +162,19 @@ impl AgentKind { let character_name = raw::cstr_up_to_nul(&raw_agent.name) .ok_or(EvtcError::InvalidData)? .to_str()?; - let account_name = raw::cstr_up_to_nul(&raw_agent.name[character_name.len() + 1..]) + let remainder = &raw_agent.name[character_name.len() + 1..]; + let account_name = raw::cstr_up_to_nul(remainder) + .ok_or(EvtcError::InvalidData)? + .to_str()?; + let remainder = &remainder[account_name.len() + 1..]; + let subgroup = raw::cstr_up_to_nul(remainder) .ok_or(EvtcError::InvalidData)? .to_str()?; - let subgroup = raw_agent.name[character_name.len() + account_name.len() + 2] - b'0'; + let subgroup = if subgroup.is_empty() { + 0 + } else { + subgroup.parse().map_err(|_| EvtcError::InvalidData)? + }; let elite = if raw_agent.is_elite == 0 { None } else { -- cgit v1.2.3