event rework wip

This commit is contained in:
Robin Appelman 2021-08-07 23:25:36 +02:00
commit b2d169601c
10 changed files with 240 additions and 63 deletions

View file

@ -1,6 +1,7 @@
use crate::common::{SubjectData, SubjectId};
use crate::event::GameEvent;
use crate::module::EventHandler;
use crate::raw_event::{RawEvent, RawEventType};
use crate::raw_event::RawEventType;
use crate::SubjectMap;
use serde::Serialize;
use std::convert::Infallible;
@ -61,22 +62,22 @@ impl EventHandler for ChatHandler {
&mut self,
time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Infallible> {
if !matches!(subject, SubjectId::Player(_)) {
return Ok(());
}
match event.ty {
RawEventType::SayTeam => self.0.push(BareChatMessage {
match event {
GameEvent::SayTeam(message) => self.0.push(BareChatMessage {
time,
subject,
message: event.params.trim_matches('"').into(),
message: message.to_string(),
chat_type: ChatType::Team,
}),
RawEventType::Say => self.0.push(BareChatMessage {
GameEvent::Say(message) => self.0.push(BareChatMessage {
time,
subject,
message: event.params.trim_matches('"').into(),
message: message.to_string(),
chat_type: ChatType::All,
}),
_ => {}

View file

@ -1,32 +1,17 @@
use crate::common::{SteamId3, SubjectId};
use crate::event::healed_event_parser;
use crate::event::GameEvent;
use crate::module::EventHandler;
use crate::raw_event::{RawEvent, RawEventType};
use crate::raw_event::RawEventType;
use crate::SubjectMap;
use serde::{Serialize, Serializer};
use std::collections::HashMap;
use std::convert::TryFrom;
use thiserror::Error;
impl Serialize for SteamId3 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.steam3().serialize(serializer)
}
}
use std::convert::{Infallible, TryFrom};
#[derive(Default)]
pub struct HealSpreadHandler(HashMap<SteamId3, HashMap<SteamId3, u32>>);
#[derive(Error, Debug)]
#[error("Invalid healed event: {0}")]
pub struct InvalidHealEvent(String);
impl EventHandler for HealSpreadHandler {
type Output = HashMap<SteamId3, HashMap<SteamId3, u32>>;
type Error = InvalidHealEvent;
type Error = Infallible;
fn does_handle(&self, ty: RawEventType) -> bool {
matches!(ty, RawEventType::Healed)
@ -36,17 +21,15 @@ impl EventHandler for HealSpreadHandler {
&mut self,
_time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Self::Error> {
let healer_steam_id = if let Some(steam_id) = subject.steam_id() {
steam_id
} else {
return Ok(());
};
if matches!(event.ty, RawEventType::Healed) {
let (_, heal_event) = healed_event_parser(event.params)
.map_err(|_| InvalidHealEvent(event.params.into()))?;
if let Ok(target_subject) = SubjectId::try_from(&heal_event.subject) {
if let GameEvent::Healed(heal_event) = event {
if let Ok(target_subject) = SubjectId::try_from(&heal_event.target) {
if let Some(target_steam_id) = target_subject.steam_id() {
let healed = self
.0

View file

@ -1,6 +1,7 @@
use crate::common::SubjectId;
use crate::event::GameEvent;
use crate::module::EventHandler;
use crate::raw_event::{RawEvent, RawEventType};
use crate::raw_event::RawEventType;
use crate::SubjectMap;
use chrono::{DateTime, FixedOffset, NaiveDateTime, TimeZone, Utc};
use std::str::{FromStr, ParseBoolError};
@ -138,13 +139,12 @@ impl EventHandler for LobbySettingsHandler {
&mut self,
_time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Self::Error> {
if !matches!(subject, SubjectId::Console) {
return Ok(());
}
if matches!(event.ty, RawEventType::Say) {
let msg = event.params.trim_matches('"');
if let GameEvent::Say(msg) = event {
if let Some((id, _)) = msg
.strip_prefix("TF2Center Lobby #")
.and_then(|s| str::split_once(s, " |"))

91
src/module/medicstats.rs Normal file
View file

@ -0,0 +1,91 @@
use crate::common::{SteamId3, SubjectId};
use crate::event::GameEvent;
use crate::module::EventHandler;
use crate::raw_event::RawEventType;
use crate::SubjectMap;
use std::collections::HashMap;
use thiserror::Error;
#[derive(Default)]
pub struct MedicStatsBuilder {
advantages_lost: u32,
biggest_advantage_lost: u32,
near_full_charge_death: u32,
deaths_after_uber: u32,
total_time_before_healing: u32,
start_healing_count: u32,
total_time_to_build: u32,
uber_build_count: u32,
total_time_to_use: u32,
total_uber_length: u32,
charge_count: u32,
}
pub struct MedicStats {
advantages_lost: u32,
biggest_advantage_lost: u32,
near_full_charge_death: u32,
deaths_after_uber: u32,
avg_time_before_healing: u32,
avg_time_to_build: u32,
avg_time_to_use: u32,
avg_uber_length: u32,
charge_count: u32,
}
impl From<MedicStatsBuilder> for MedicStats {
fn from(builder: MedicStatsBuilder) -> Self {
MedicStats {
advantages_lost: builder.advantages_lost,
biggest_advantage_lost: builder.biggest_advantage_lost,
near_full_charge_death: builder.near_full_charge_death,
deaths_after_uber: builder.deaths_after_uber,
avg_time_before_healing: builder.total_time_before_healing
/ builder.start_healing_count,
avg_time_to_build: builder.total_time_to_build / builder.uber_build_count,
avg_time_to_use: builder.total_time_to_use / builder.charge_count,
avg_uber_length: builder.total_uber_length / builder.charge_count,
charge_count: builder.charge_count,
}
}
}
#[derive(Error, Debug)]
#[error("Invalid charge event: {0}")]
pub struct InvalidMedicEvent(String);
#[derive(Default)]
pub struct MedicStatsHandler(HashMap<SteamId3, MedicStatsBuilder>);
impl EventHandler for MedicStatsHandler {
type Output = HashMap<SteamId3, MedicStats>;
type Error = InvalidMedicEvent;
fn does_handle(&self, ty: RawEventType) -> bool {
matches!(
ty,
RawEventType::ChargeDeployed | RawEventType::ChargeEnd | RawEventType::ChargeReady
)
}
fn handle(
&mut self,
_time: u32,
subject: SubjectId,
event: &GameEvent,
) -> Result<(), Self::Error> {
let healer_steam_id = if let Some(steam_id) = subject.steam_id() {
steam_id
} else {
return Ok(());
};
Ok(())
}
fn finish(self, _subjects: &SubjectMap) -> Self::Output {
self.0
.into_iter()
.map(|(steam_id, builder)| (steam_id, builder.into()))
.collect()
}
}

View file

@ -1,8 +1,9 @@
use crate::common::SubjectId;
use crate::raw_event::{RawEvent, RawEventType};
use crate::event::GameEvent;
use crate::raw_event::RawEventType;
use crate::SubjectMap;
pub use chat::{ChatHandler, ChatMessage, ChatType};
pub use healspread::{HealSpreadHandler, InvalidHealEvent};
pub use healspread::HealSpreadHandler;
pub use lobbysettings::{
LobbySettingsError, LobbySettingsHandler, Location, Settings as LobbySettings,
};
@ -14,6 +15,7 @@ use thiserror::Error;
mod chat;
mod healspread;
mod lobbysettings;
mod medicstats;
pub trait EventHandler: Default {
type Output;
@ -25,7 +27,7 @@ pub trait EventHandler: Default {
&mut self,
time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Self::Error>;
fn finish(self, subjects: &SubjectMap) -> Self::Output;
@ -49,7 +51,7 @@ impl<Head: EventHandler, Tail: EventHandler> EventHandler for HandlerStack<Head,
&mut self,
time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Self::Error> {
self.head
.handle(time, subject, event)
@ -100,7 +102,7 @@ impl<Handler: EventHandler> EventHandler for OptionalHandler<Handler> {
&mut self,
time: u32,
subject: SubjectId,
event: &RawEvent,
event: &GameEvent,
) -> Result<(), Self::Error> {
let res = if let OptionalHandler::Active(handler) = self {
handler.handle(time, subject, event)