mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 18:24:09 +02:00
more event parsers
This commit is contained in:
parent
b95d68a845
commit
58100e5f7b
8 changed files with 418 additions and 17 deletions
|
|
@ -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::number::complete::float;
|
||||
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)?;
|
||||
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,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,3 +76,18 @@ pub fn medic_death_event_parser(input: &str) -> IResult<&str, MedicDeathEvent> {
|
|||
}
|
||||
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),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@ pub use medic::*;
|
|||
use nom::bytes::complete::{tag, take_while};
|
||||
use nom::character::complete::{alpha1, digit1};
|
||||
use nom::combinator::opt;
|
||||
use nom::error::ErrorKind;
|
||||
use nom::error::{ErrorKind, ParseError};
|
||||
use nom::{Err, IResult};
|
||||
pub use player::*;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
|
@ -68,12 +69,34 @@ pub enum GameEvent<'a> {
|
|||
FirstHeal(FirstHealEvent),
|
||||
ChargeReady,
|
||||
MedicDeath(MedicDeathEvent),
|
||||
MedicDeathEx(MedicDeathExEvent),
|
||||
Spawned(SpawnEvent),
|
||||
RoleChange(RoleChangeEvent),
|
||||
RoundStart,
|
||||
RoundWin(RoundWinEvent<'a>),
|
||||
RoundLength(RoundLengthEvent),
|
||||
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> {
|
||||
|
|
@ -115,6 +138,9 @@ impl<'a> GameEvent<'a> {
|
|||
RawEventType::MedicDeath => {
|
||||
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 => {
|
||||
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)?)
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
@ -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> {
|
||||
let (input, sign) = opt(tag("-"))(input)?;
|
||||
let (input, raw) = digit1(input)?;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use crate::common::Class;
|
||||
use crate::event::{param_parse, param_parse_with, position, u_int, ParamIter};
|
||||
use crate::common::{Class, Team};
|
||||
use crate::event::{param_parse, param_parse_with, parse_from_str, position, u_int, ParamIter};
|
||||
use crate::raw_event::{subject_parser, RawSubject};
|
||||
use nom::combinator::opt;
|
||||
use nom::IResult;
|
||||
use std::net::SocketAddr;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
#[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,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue