more event parsers

This commit is contained in:
Robin Appelman 2021-08-24 23:01:07 +02:00
commit 58100e5f7b
8 changed files with 418 additions and 17 deletions

View file

@ -1,20 +1,34 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{black_box, criterion_group, criterion_main, Criterion};
use std::fs::read_to_string; use std::fs::read_to_string;
use std::time::Duration; use std::time::Duration;
use tf_log_parser::{parse, RawEvent}; use tf_log_parser::{parse, GameEvent, RawEvent};
pub fn parse_benchmark(c: &mut Criterion) { pub fn parse_benchmark(c: &mut Criterion) {
let input = read_to_string("test_data/log_2892242.log").unwrap(); let input = read_to_string("test_data/log_2892242.log").unwrap();
c.bench_function("parse log 2892242", |b| b.iter(|| parse(black_box(&input)))); c.bench_function("parse log 2892242", |b| b.iter(|| parse(black_box(&input))));
} }
pub fn parse_event(c: &mut Criterion) {
let input = read_to_string("test_data/log_2892242.log").unwrap();
let raw: Vec<_> = input
.split("L ")
.filter(|line| !line.is_empty())
.flat_map(RawEvent::parse)
.collect();
c.bench_function("parse event 2892242", |b| {
b.iter(|| {
black_box(&raw).iter().flat_map(GameEvent::parse).count();
})
});
}
pub fn parse_raw(c: &mut Criterion) { pub fn parse_raw(c: &mut Criterion) {
let input = read_to_string("test_data/log_2892242.log").unwrap(); let input = read_to_string("test_data/log_2892242.log").unwrap();
c.bench_function("parse raw 2892242", |b| { c.bench_function("parse raw 2892242", |b| {
b.iter(|| { b.iter(|| {
black_box(&input) black_box(&input)
.lines() .split("L ")
.filter(|line| line.starts_with("L ")) .filter(|line| !line.is_empty())
.flat_map(RawEvent::parse) .flat_map(RawEvent::parse)
.count(); .count();
}) })
@ -24,5 +38,5 @@ pub fn parse_raw(c: &mut Criterion) {
criterion_group!( criterion_group!(
name = benches; name = benches;
config = Criterion::default().measurement_time(Duration::from_secs(10)); config = Criterion::default().measurement_time(Duration::from_secs(10));
targets = parse_benchmark, parse_raw); targets = parse_benchmark, parse_raw, parse_event);
criterion_main!(benches); criterion_main!(benches);

View file

@ -14,6 +14,7 @@ use thiserror::Error;
pub enum Team { pub enum Team {
Red, Red,
Blue, Blue,
Spectator,
} }
impl Team { impl Team {
@ -21,6 +22,7 @@ impl Team {
match self { match self {
Team::Red => "Red", Team::Red => "Red",
Team::Blue => "Blue", Team::Blue => "Blue",
Team::Spectator => "Spectator",
} }
} }
} }
@ -38,6 +40,7 @@ impl FromStr for Team {
match s { match s {
"Blue" => Ok(Team::Blue), "Blue" => Ok(Team::Blue),
"Red" => Ok(Team::Red), "Red" => Ok(Team::Red),
"Spectator" => Ok(Team::Spectator),
_ => Err(()), _ => Err(()),
} }
} }

View file

@ -1,4 +1,6 @@
use crate::event::{param_parse, param_parse_with}; use crate::event::{param_parse, param_parse_with, parse_from_str, position, u_int, ParamIter};
use crate::raw_event::{subject_parser, RawSubject};
use nom::bytes::complete::{tag, take_while};
use nom::combinator::opt; use nom::combinator::opt;
use nom::number::complete::float; use nom::number::complete::float;
use nom::IResult; use nom::IResult;
@ -22,3 +24,145 @@ pub fn round_length_event_parser(input: &str) -> IResult<&str, RoundLengthEvent>
let (input, length) = opt(param_parse_with("against", float))(input)?; let (input, length) = opt(param_parse_with("against", float))(input)?;
Ok((input, RoundLengthEvent { length })) Ok((input, RoundLengthEvent { length }))
} }
#[derive(Debug)]
pub struct LogFileStartedEvent<'a> {
pub file: Option<&'a str>,
pub game: Option<&'a str>,
pub version: Option<&'a str>,
}
pub fn log_file_started_event_parser(input: &str) -> IResult<&str, LogFileStartedEvent> {
let (input, file) = opt(param_parse("file"))(input)?;
let (input, game) = opt(param_parse("game"))(input)?;
let (input, version) = opt(param_parse("version"))(input)?;
Ok((
input,
LogFileStartedEvent {
file,
game,
version,
},
))
}
#[derive(Debug)]
pub struct TournamentModeStartedEvent<'a> {
pub blue: &'a str,
pub red: &'a str,
}
pub fn tournament_mode_started_event_parser(
input: &str,
) -> IResult<&str, TournamentModeStartedEvent> {
let (input, _) = tag("\nBlue Team: ")(input)?;
let (input, blue) = take_while(|c| c != '\n')(input)?;
let (input, _) = tag("\nRed Team: ")(input)?;
let (input, red) = take_while(|c| c != '\n')(input)?;
Ok((input, TournamentModeStartedEvent { blue, red }))
}
#[derive(Debug)]
pub struct CaptureBlockedEvent<'a> {
pub cp: Option<u8>,
pub cp_name: Option<&'a str>,
pub position: Option<(i32, i32, i32)>,
}
pub fn capture_blocked_event_parser(input: &str) -> IResult<&str, CaptureBlockedEvent> {
let (input, cp) = opt(param_parse_with("cp", u_int))(input)?;
let (input, cp_name) = opt(param_parse("map"))(input)?;
let (input, position) = opt(param_parse_with("red", position))(input)?;
Ok((
input,
CaptureBlockedEvent {
cp: cp.map(|cp| cp as u8),
cp_name,
position,
},
))
}
#[derive(Debug)]
pub struct PointCapturedEvent<'a> {
pub cp: Option<u8>,
pub cp_name: Option<&'a str>,
pub num_cappers: Option<u8>,
pub players: Vec<(RawSubject<'a>, (i32, i32, i32))>,
}
pub fn point_captures_event_parser(input: &str) -> IResult<&str, PointCapturedEvent> {
let (input, cp) = opt(param_parse_with("cp", u_int))(input)?;
let (input, cp_name) = opt(param_parse("map"))(input)?;
let (input, num_cappers) = opt(param_parse_with("numcappers", u_int))(input)?;
let mut players = Vec::new();
let mut params = ParamIter::new(input);
match (params.next(), params.next()) {
(Some((subject_key, subject)), Some((position_key, position_str)))
if subject_key.starts_with("player") && position_key.starts_with("position") =>
{
let (_, subject) = subject_parser(subject)?;
let (_, position) = position(position_str)?;
players.push((subject, position));
}
_ => {}
}
Ok((
input,
PointCapturedEvent {
cp: cp.map(|cp| cp as u8),
num_cappers: num_cappers.map(|num| num as u8),
cp_name,
players,
},
))
}
#[derive(Debug)]
pub struct CurrentScoreEvent {
pub score: u8,
pub player: u8,
}
pub fn current_score_event_parser(input: &str) -> IResult<&str, CurrentScoreEvent> {
let (input, score) = param_parse_with("cp", u_int)(input)?;
let (input, player) = param_parse_with("with", u_int)(input)?;
Ok((
input,
CurrentScoreEvent {
score: score as u8,
player: player as u8,
},
))
}
#[derive(Debug)]
pub struct GameOverEvent<'a> {
pub reason: &'a str,
}
pub fn game_over_event_parser(input: &str) -> IResult<&str, GameOverEvent> {
let (input, reason) = param_parse("reason")(input)?;
Ok((input, GameOverEvent { reason }))
}
#[derive(Debug)]
pub struct FinalScoreEvent {
pub score: u8,
pub player: u8,
}
pub fn final_score_event_parser(input: &str) -> IResult<&str, FinalScoreEvent> {
let (input, score) = param_parse_with("cp", u_int)(input)?;
let (input, player) = param_parse_with("with", u_int)(input)?;
Ok((
input,
FinalScoreEvent {
score: score as u8,
player: player as u8,
},
))
}

View file

@ -76,3 +76,18 @@ pub fn medic_death_event_parser(input: &str) -> IResult<&str, MedicDeathEvent> {
} }
Ok((input, MedicDeathEvent { charge })) Ok((input, MedicDeathEvent { charge }))
} }
#[derive(Debug)]
pub struct MedicDeathExEvent {
pub charge_percentage: Option<u8>,
}
pub fn medic_death_ex_event_parser(input: &str) -> IResult<&str, MedicDeathExEvent> {
let (input, charge_percentage) = opt(param_parse_with("time", quoted(u_int)))(input)?;
Ok((
input,
MedicDeathExEvent {
charge_percentage: charge_percentage.map(|charge: u32| charge as u8),
},
))
}

View file

@ -9,9 +9,10 @@ pub use medic::*;
use nom::bytes::complete::{tag, take_while}; use nom::bytes::complete::{tag, take_while};
use nom::character::complete::{alpha1, digit1}; use nom::character::complete::{alpha1, digit1};
use nom::combinator::opt; use nom::combinator::opt;
use nom::error::ErrorKind; use nom::error::{ErrorKind, ParseError};
use nom::{Err, IResult}; use nom::{Err, IResult};
pub use player::*; pub use player::*;
use std::str::FromStr;
use thiserror::Error; use thiserror::Error;
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -68,12 +69,34 @@ pub enum GameEvent<'a> {
FirstHeal(FirstHealEvent), FirstHeal(FirstHealEvent),
ChargeReady, ChargeReady,
MedicDeath(MedicDeathEvent), MedicDeath(MedicDeathEvent),
MedicDeathEx(MedicDeathExEvent),
Spawned(SpawnEvent), Spawned(SpawnEvent),
RoleChange(RoleChangeEvent), RoleChange(RoleChangeEvent),
RoundStart, RoundStart,
RoundWin(RoundWinEvent<'a>), RoundWin(RoundWinEvent<'a>),
RoundLength(RoundLengthEvent), RoundLength(RoundLengthEvent),
RoundOverTime, RoundOverTime,
LogFileStarted(LogFileStartedEvent<'a>),
Connected(ConnectedEvent),
Disconnect(DisconnectEvent<'a>),
SteamIdValidated,
Entered,
Joined(JoinedTeamEvent),
Suicide(CommittedSuicideEvent<'a>),
PickedUp(PickedUpEvent<'a>),
Domination(DominationEvent<'a>),
EmptyUber,
Revenge(RevengeEvent<'a>),
TournamentModeStarted(TournamentModeStartedEvent<'a>),
CaptureBlocked(CaptureBlockedEvent<'a>),
PointCaptured(PointCapturedEvent<'a>),
CurrentScore(CurrentScoreEvent),
BuiltObject(BuiltObjectEvent<'a>),
KilledObject(KilledObjectEvent<'a>),
Extinguished(ExtinguishedEvent<'a>),
GameOver(GameOverEvent<'a>),
FinalScore(FinalScoreEvent),
LogFileClosed,
} }
impl<'a> GameEvent<'a> { impl<'a> GameEvent<'a> {
@ -115,6 +138,9 @@ impl<'a> GameEvent<'a> {
RawEventType::MedicDeath => { RawEventType::MedicDeath => {
GameEvent::MedicDeath(medic_death_event_parser(raw.params).with_type(raw.ty)?) GameEvent::MedicDeath(medic_death_event_parser(raw.params).with_type(raw.ty)?)
} }
RawEventType::MedicDeathEx => {
GameEvent::MedicDeathEx(medic_death_ex_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::Spawned => { RawEventType::Spawned => {
GameEvent::Spawned(spawn_event_parser(raw.params).with_type(raw.ty)?) GameEvent::Spawned(spawn_event_parser(raw.params).with_type(raw.ty)?)
} }
@ -129,6 +155,61 @@ impl<'a> GameEvent<'a> {
GameEvent::RoundWin(round_win_event_parser(raw.params).with_type(raw.ty)?) GameEvent::RoundWin(round_win_event_parser(raw.params).with_type(raw.ty)?)
} }
RawEventType::RoundOvertime => GameEvent::RoundOverTime, RawEventType::RoundOvertime => GameEvent::RoundOverTime,
RawEventType::LogFileStarted => GameEvent::LogFileStarted(
log_file_started_event_parser(raw.params).with_type(raw.ty)?,
),
RawEventType::Connected => {
GameEvent::Connected(connected_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::Disconnected => {
GameEvent::Disconnect(disconnected_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::SteamIdValidated => GameEvent::SteamIdValidated,
RawEventType::Entered => GameEvent::Entered,
RawEventType::Joined => {
GameEvent::Joined(joined_team_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::Suicide => {
GameEvent::Suicide(committed_suicide_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::PickedUp => {
GameEvent::PickedUp(picked_up_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::Domination => {
GameEvent::Domination(domination_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::EmptyUber => GameEvent::EmptyUber,
RawEventType::Revenge => {
GameEvent::Revenge(revenge_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::TournamentStart => GameEvent::TournamentModeStarted(
tournament_mode_started_event_parser(raw.params).with_type(raw.ty)?,
),
RawEventType::CaptureBlocked => GameEvent::CaptureBlocked(
capture_blocked_event_parser(raw.params).with_type(raw.ty)?,
),
RawEventType::PointCaptured => {
GameEvent::PointCaptured(point_captures_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::CurrentScore => {
GameEvent::CurrentScore(current_score_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::PlayerBuiltObject => {
GameEvent::BuiltObject(built_object_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::PlayerKilledObject => {
GameEvent::KilledObject(killed_object_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::PlayerExtinguished => {
GameEvent::Extinguished(extinguished_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::GameOver => {
GameEvent::GameOver(game_over_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::FinalScore => {
GameEvent::FinalScore(final_score_event_parser(raw.params).with_type(raw.ty)?)
}
RawEventType::LogFileClosed => GameEvent::LogFileClosed,
_ => { _ => {
todo!("{:?} not parsed yet", raw.ty); todo!("{:?} not parsed yet", raw.ty);
} }
@ -205,6 +286,12 @@ fn param_parse_with<'a, T, P: Fn(&'a str) -> IResult<&'a str, T>>(
} }
} }
fn parse_from_str<T: FromStr>(input: &str) -> IResult<&str, T> {
T::from_str(input)
.map(|res| ("", res))
.map_err(|_| nom::Err::Error(nom::error::Error::from_error_kind(input, ErrorKind::IsNot)))
}
fn int(input: &str) -> IResult<&str, i32> { fn int(input: &str) -> IResult<&str, i32> {
let (input, sign) = opt(tag("-"))(input)?; let (input, sign) = opt(tag("-"))(input)?;
let (input, raw) = digit1(input)?; let (input, raw) = digit1(input)?;

View file

@ -1,8 +1,9 @@
use crate::common::Class; use crate::common::{Class, Team};
use crate::event::{param_parse, param_parse_with, position, u_int, ParamIter}; use crate::event::{param_parse, param_parse_with, parse_from_str, position, u_int, ParamIter};
use crate::raw_event::{subject_parser, RawSubject}; use crate::raw_event::{subject_parser, RawSubject};
use nom::combinator::opt; use nom::combinator::opt;
use nom::IResult; use nom::IResult;
use std::net::SocketAddr;
use std::num::NonZeroU32; use std::num::NonZeroU32;
#[derive(Debug)] #[derive(Debug)]
@ -132,3 +133,141 @@ pub fn role_changed_event_parser(input: &str) -> IResult<&str, RoleChangeEvent>
}, },
)) ))
} }
#[derive(Debug)]
pub struct ConnectedEvent {
pub address: SocketAddr,
}
pub fn connected_event_parser(input: &str) -> IResult<&str, ConnectedEvent> {
let (input, address) = param_parse_with("to", parse_from_str)(input)?;
Ok((input, ConnectedEvent { address }))
}
#[derive(Debug)]
pub struct JoinedTeamEvent {
pub team: Team,
}
pub fn joined_team_event_parser(input: &str) -> IResult<&str, JoinedTeamEvent> {
let (input, team) = param_parse_with("team", parse_from_str)(input)?;
Ok((input, JoinedTeamEvent { team }))
}
#[derive(Debug)]
pub struct CommittedSuicideEvent<'a> {
pub weapon: &'a str,
pub attacker_position: Option<(i32, i32, i32)>,
}
pub fn committed_suicide_event_parser(input: &str) -> IResult<&str, CommittedSuicideEvent> {
let (input, weapon) = param_parse("with")(input)?;
let (input, attacker_position) = opt(param_parse_with("attacker_position", position))(input)?;
Ok((
input,
CommittedSuicideEvent {
weapon,
attacker_position,
},
))
}
#[derive(Debug)]
pub struct PickedUpEvent<'a> {
pub item: &'a str,
}
pub fn picked_up_event_parser(input: &str) -> IResult<&str, PickedUpEvent> {
let (input, item) = param_parse("item")(input)?;
Ok((input, PickedUpEvent { item }))
}
#[derive(Debug)]
pub struct DominationEvent<'a> {
pub against: RawSubject<'a>,
}
pub fn domination_event_parser(input: &str) -> IResult<&str, DominationEvent> {
let (input, against) = param_parse_with("against", subject_parser)(input)?;
Ok((input, DominationEvent { against }))
}
#[derive(Debug)]
pub struct RevengeEvent<'a> {
pub against: RawSubject<'a>,
}
pub fn revenge_event_parser(input: &str) -> IResult<&str, RevengeEvent> {
let (input, against) = param_parse_with("against", subject_parser)(input)?;
Ok((input, RevengeEvent { against }))
}
#[derive(Debug)]
pub struct DisconnectEvent<'a> {
pub reason: Option<&'a str>,
}
pub fn disconnected_event_parser(input: &str) -> IResult<&str, DisconnectEvent> {
let (input, reason) = opt(param_parse("reason"))(input)?;
Ok((input, DisconnectEvent { reason }))
}
#[derive(Debug)]
pub struct BuiltObjectEvent<'a> {
pub object: Option<&'a str>,
pub position: Option<(i32, i32, i32)>,
}
pub fn built_object_event_parser(input: &str) -> IResult<&str, BuiltObjectEvent> {
let (input, object) = opt(param_parse("object"))(input)?;
let (input, position) = opt(param_parse_with("position", position))(input)?;
Ok((input, BuiltObjectEvent { object, position }))
}
#[derive(Debug)]
pub struct KilledObjectEvent<'a> {
pub object: Option<&'a str>,
pub weapon: Option<&'a str>,
pub object_owner: Option<RawSubject<'a>>,
pub attacker_position: Option<(i32, i32, i32)>,
}
pub fn killed_object_event_parser(input: &str) -> IResult<&str, KilledObjectEvent> {
let (input, object) = opt(param_parse("object"))(input)?;
let (input, weapon) = opt(param_parse("weapon"))(input)?;
let (input, object_owner) = opt(param_parse_with("objectowner", subject_parser))(input)?;
let (input, attacker_position) = opt(param_parse_with("attacker_position", position))(input)?;
Ok((
input,
KilledObjectEvent {
object,
weapon,
object_owner,
attacker_position,
},
))
}
#[derive(Debug)]
pub struct ExtinguishedEvent<'a> {
pub against: RawSubject<'a>,
pub with: &'a str,
pub attacker_position: Option<(i32, i32, i32)>,
pub victim_position: Option<(i32, i32, i32)>,
}
pub fn extinguished_event_parser(input: &str) -> IResult<&str, ExtinguishedEvent> {
let (input, against) = param_parse_with("against", subject_parser)(input)?;
let (input, with) = param_parse("with")(input)?;
let (input, attacker_position) = opt(param_parse_with("attacker_position", position))(input)?;
let (input, victim_position) = opt(param_parse_with("victim_position", position))(input)?;
Ok((
input,
ExtinguishedEvent {
against,
with,
attacker_position,
victim_position,
},
))
}

View file

@ -61,8 +61,8 @@ pub fn parse_with_handler<Handler: EventHandler>(
Error, Error,
> { > {
let events = log let events = log
.lines() .split("L ")
.filter(|line| line.starts_with("L ")) .filter(|line| !line.is_empty())
.map(RawEvent::parse); .map(RawEvent::parse);
let mut handler = Handler::default(); let mut handler = Handler::default();

View file

@ -27,7 +27,6 @@ impl<'a> RawEvent<'a> {
} }
fn event_parser(input: &str) -> IResult<&str, RawEvent> { fn event_parser(input: &str) -> IResult<&str, RawEvent> {
let (input, _) = tag("L ")(input)?;
let (input, date) = date_parser(input)?; let (input, date) = date_parser(input)?;
let (input, _) = tag(": ")(input)?; let (input, _) = tag(": ")(input)?;
@ -190,7 +189,7 @@ pub fn subject_parser(input: &str) -> IResult<&str, RawSubject> {
#[derive(IntoEnumIterator, Copy, Clone, Debug, PartialEq)] #[derive(IntoEnumIterator, Copy, Clone, Debug, PartialEq)]
pub enum RawEventType { pub enum RawEventType {
JoinedTeam, Joined,
ChangedRole, ChangedRole,
ShotFired, ShotFired,
ShotHit, ShotHit,
@ -212,7 +211,7 @@ pub enum RawEventType {
PlayerKilledObject, PlayerKilledObject,
PlayerExtinguished, PlayerExtinguished,
ObjectDetonated, ObjectDetonated,
PickedUpItem, PickedUp,
MedicDeath, MedicDeath,
MedicDeathEx, MedicDeathEx,
ChargeEnd, ChargeEnd,
@ -253,7 +252,7 @@ pub enum RawEventType {
impl RawEventType { impl RawEventType {
pub fn tag(self) -> &'static str { pub fn tag(self) -> &'static str {
match self { match self {
RawEventType::JoinedTeam => r#"joined team"#, RawEventType::Joined => r#"joined"#,
RawEventType::ChangedRole => r#"changed role"#, RawEventType::ChangedRole => r#"changed role"#,
RawEventType::ShotFired => r#"triggered "shot_fired""#, RawEventType::ShotFired => r#"triggered "shot_fired""#,
RawEventType::ShotHit => r#"triggered "shot_hit""#, RawEventType::ShotHit => r#"triggered "shot_hit""#,
@ -275,7 +274,7 @@ impl RawEventType {
RawEventType::PlayerKilledObject => r#"triggered "killedobject""#, RawEventType::PlayerKilledObject => r#"triggered "killedobject""#,
RawEventType::ObjectDetonated => r#"triggered "object_detonated""#, RawEventType::ObjectDetonated => r#"triggered "object_detonated""#,
RawEventType::PlayerExtinguished => r#"triggered "player_extinguished""#, RawEventType::PlayerExtinguished => r#"triggered "player_extinguished""#,
RawEventType::PickedUpItem => r#"picked up item"#, RawEventType::PickedUp => r#"picked up"#,
RawEventType::MedicDeath => r#"triggered "medic_death""#, RawEventType::MedicDeath => r#"triggered "medic_death""#,
RawEventType::MedicDeathEx => r#"triggered "medic_death_ex""#, RawEventType::MedicDeathEx => r#"triggered "medic_death_ex""#,
RawEventType::ChargeEnd => r#"triggered "chargeended""#, RawEventType::ChargeEnd => r#"triggered "chargeended""#,
@ -295,8 +294,8 @@ impl RawEventType {
RawEventType::PointCaptured => r#"triggered "pointcaptured""#, RawEventType::PointCaptured => r#"triggered "pointcaptured""#,
RawEventType::CaptureBlocked => r#"triggered "captureblocked""#, RawEventType::CaptureBlocked => r#"triggered "captureblocked""#,
RawEventType::GameOver => r#"triggered "Game_Over""#, RawEventType::GameOver => r#"triggered "Game_Over""#,
RawEventType::CurrentScore => r#"current score"#, RawEventType::CurrentScore => r#"current"#,
RawEventType::FinalScore => r#"final score"#, RawEventType::FinalScore => r#"final"#,
RawEventType::WinLimit => r#"triggered "Intermission_Win_Limit""#, RawEventType::WinLimit => r#"triggered "Intermission_Win_Limit""#,
RawEventType::Paused => r#"triggered "Game_Paused""#, RawEventType::Paused => r#"triggered "Game_Paused""#,
RawEventType::UnPaused => r#"triggered "Game_Unpaused""#, RawEventType::UnPaused => r#"triggered "Game_Unpaused""#,