aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md18
-rw-r--r--Cargo.toml2
-rw-r--r--src/analyzers/raids/w5.rs2
-rw-r--r--src/event.rs3
-rw-r--r--src/lib.rs23
-rw-r--r--src/raw/types.rs2
6 files changed, 40 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f51a115..45e8aca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,20 +3,32 @@
All notable changes to this project will be documented in this file.
## Unreleased
+
+## 0.6.0 - 2021-11-19
### Added
- Boss and encounter definitions for the training golems (`StandardKittyGolem`,
- `MediumKittyGolem`, `LargeKittyGolem`)
+ `MediumKittyGolem`, `LargeKittyGolem`).
- Missing encounters and bosses:
- `Encounter::BanditTrio` (`Boss::Berg`, `Boss::Zane`, `Boss::Narella`)
- `Encounter::RiverOfSouls` (no bosses)
- `Encounter::BrokenKing` (`Boss::BrokenKing`)
- `Encounter::EaterOfSouls` (`Boss::EaterOfSouls`)
- `Encounter::StatueOfDarkness` (`Boss::EyeOfJudgment` and `Boss::EyeOfFate`)
-- `Log::is_generic` to check whether a log is generic (WvW)
+- `Log::is_generic` to check whether a log is generic (WvW).
- `gamedata::GameMode` and the `Encounter::game_mode` and `Log::game_mode`
- methods
+ methods.
- `FromRawEventError::UnknownLanguage` has been added to deal with an invalid
language byte.
+- The `CbtStateChange::BarrierUpdate` and `CbtResult::Breakbar` low-level
+ variants.
+- The `EventKind::{BuffInitial, StackActive, StackReset}` events.
+
+### Changes
+- Internal changes that lead to some small speedups, especially in the
+ *Soulless Horror* outcome analyzer (~50x speedup) as well as most other
+ analyzers (up to a 2.77x speedup).
+- An internal parsing change to speed up log processing (by around 50%).
+- `EventKind` has been marked non-exhaustive.
### Fixed
- `evtclib` will no longer choke on WvW logs where player names might not contain the expected
diff --git a/Cargo.toml b/Cargo.toml
index 4b22460..95272aa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "evtclib"
-version = "0.5.0"
+version = "0.6.0"
authors = ["Daniel"]
edition = "2018"
description = "An evtc parsing library"
diff --git a/src/analyzers/raids/w5.rs b/src/analyzers/raids/w5.rs
index 747bda2..d00eab8 100644
--- a/src/analyzers/raids/w5.rs
+++ b/src/analyzers/raids/w5.rs
@@ -46,7 +46,7 @@ impl<'log> Analyzer for SoullessHorror<'log> {
..
} = event.kind()
{
- self.log.is_boss(*destination_agent_addr) && *buff_id == DESMINA_DEATH_BUFF
+ *buff_id == DESMINA_DEATH_BUFF && self.log.is_boss(*destination_agent_addr)
} else {
false
}
diff --git a/src/event.rs b/src/event.rs
index ee561f8..b6caa5d 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -32,6 +32,7 @@ pub enum FromRawEventError {
/// This makes dealing with [`CbtEvent`][raw::CbtEvent] a bit saner (and safer).
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq)]
+#[non_exhaustive]
pub enum EventKind {
// State change events
/// The agent has entered combat.
@@ -579,7 +580,7 @@ pub enum WeaponSet {
Land1,
/// An unknown weapon set.
///
- /// This can be caused bundles or anything else that uses the "weapon swap"
+ /// This can be caused by bundles or anything else that uses the "weapon swap"
/// event but is not a normal weapon set.
Unknown(u8),
}
diff --git a/src/lib.rs b/src/lib.rs
index ccf6692..3677871 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,7 +19,7 @@
//! # Crate Structure
//!
//! The crate consists of two main parts: The [`raw`][raw] parser, which is used to read structured
-//! data from binary input streams, and the higher-level abstrations provided in the root and
+//! data from binary input streams, and the higher-level abstractions provided in the root and
//! [`event`][event] submodules.
//!
//! Additionally, there are some defintions (such as IDs for various game items) in the
@@ -88,6 +88,7 @@
//! While there are legitimate use cases for writing/modification support, they are currently not
//! implemented (but might be in a future version).
+use num_traits::FromPrimitive;
use thiserror::Error;
pub mod raw;
@@ -102,6 +103,7 @@ mod processing;
pub use processing::{process, process_file, process_stream, Compression};
pub mod gamedata;
+use gamedata::Boss;
pub use gamedata::{EliteSpec, Encounter, GameMode, Profession};
pub mod analyzers;
@@ -138,6 +140,8 @@ pub enum EvtcError {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct Log {
+ // evtclib assumes that the agents in this vector are sorted by their address. This information
+ // is used to speed up the agent_by_addr search.
agents: Vec<Agent>,
events: Vec<Event>,
boss_id: u16,
@@ -152,7 +156,12 @@ impl Log {
/// Return an agent based on its address.
pub fn agent_by_addr(&self, addr: u64) -> Option<&Agent> {
- self.agents.iter().find(|a| a.addr() == addr)
+ // We know that the agents are sorted because processing::process puts them like that. We
+ // can use the same trick here to achieve a faster agent searching:
+ self.agents
+ .binary_search_by_key(&addr, Agent::addr)
+ .ok()
+ .map(|i| &self.agents[i])
}
/// Return an agent based on the instance ID.
@@ -217,7 +226,15 @@ impl Log {
/// Check whether the given address is a boss agent.
pub fn is_boss(&self, addr: u64) -> bool {
- self.boss_agents().into_iter().any(|a| a.addr() == addr)
+ let bosses = self
+ .encounter()
+ .map(Encounter::bosses)
+ .unwrap_or(&[] as &[_]);
+ let agent = self
+ .agent_by_addr(addr)
+ .and_then(Agent::as_character)
+ .and_then(|c| Boss::from_u16(c.id()));
+ agent.map(|e| bosses.contains(&e)).unwrap_or(false)
}
/// Returns the encounter id.
diff --git a/src/raw/types.rs b/src/raw/types.rs
index 6339ed8..ce22f5f 100644
--- a/src/raw/types.rs
+++ b/src/raw/types.rs
@@ -382,7 +382,7 @@ pub struct Agent {
pub addr: u64,
/// Agent profession id.
pub prof: u32,
- /// Agent elite specialisation.
+ /// Agent elite specialization.
pub is_elite: u32,
/// Toughnes.
pub toughness: i16,