mirror of
https://codeberg.org/icewind/tf-log-parser.git
synced 2026-06-03 18:24:09 +02:00
more edge case handling
This commit is contained in:
parent
a30a3d3683
commit
f1213a5664
5 changed files with 15 additions and 9 deletions
|
|
@ -138,7 +138,8 @@ impl<'a> Iterator for ParamIter<'a> {
|
||||||
fn param_pair_parse(input: &str) -> IResult<'_, (&str, &str)> {
|
fn param_pair_parse(input: &str) -> IResult<'_, (&str, &str)> {
|
||||||
let (input, open_tag) = skip_matches(input, b'(');
|
let (input, open_tag) = skip_matches(input, b'(');
|
||||||
|
|
||||||
let (key, input) = split_once(input, b' ', 2)?;
|
let (key, input) = split_once(input, b' ', 1)?;
|
||||||
|
let input = skip(input, 1)?;
|
||||||
let (value, input) = split_once(input, b'"', 1)?;
|
let (value, input) = split_once(input, b'"', 1)?;
|
||||||
|
|
||||||
let input = if open_tag { skip(input, 1)? } else { input };
|
let input = if open_tag { skip(input, 1)? } else { input };
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ pub struct ShotHitEvent<'a> {
|
||||||
#[derive(Debug, Event)]
|
#[derive(Debug, Event)]
|
||||||
pub struct DamageEvent<'a> {
|
pub struct DamageEvent<'a> {
|
||||||
#[event(name = "against")]
|
#[event(name = "against")]
|
||||||
pub target: RawSubject<'a>,
|
pub target: Option<RawSubject<'a>>,
|
||||||
pub damage: Option<NonZeroU32>,
|
pub damage: Option<NonZeroU32>,
|
||||||
#[event(name = "realdamage")]
|
#[event(name = "realdamage")]
|
||||||
pub real_damage: Option<NonZeroU32>,
|
pub real_damage: Option<NonZeroU32>,
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ impl EventHandler for ClassStatsHandler {
|
||||||
}
|
}
|
||||||
GameEvent::Damage(DamageEvent {
|
GameEvent::Damage(DamageEvent {
|
||||||
damage: Some(damage),
|
damage: Some(damage),
|
||||||
target,
|
target: Some(target),
|
||||||
..
|
..
|
||||||
}) if self.active => {
|
}) if self.active => {
|
||||||
if let Some(target_class) = self.get_class(target) {
|
if let Some(target_class) = self.get_class(target) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use once_cell::unsync::Lazy;
|
||||||
|
|
||||||
pub fn split_once(input: &str, delim: u8, offset: usize) -> Result<(&str, &str)> {
|
pub fn split_once(input: &str, delim: u8, offset: usize) -> Result<(&str, &str)> {
|
||||||
debug_assert!(delim < 128); // only basic ascii
|
debug_assert!(delim < 128); // only basic ascii
|
||||||
|
debug_assert!(offset <= 1);
|
||||||
let end = memchr(delim, input.as_bytes()).ok_or(Error::Incomplete)?;
|
let end = memchr(delim, input.as_bytes()).ok_or(Error::Incomplete)?;
|
||||||
// safety, memchr returns indices that are inside the input length and we only split on ascii
|
// safety, memchr returns indices that are inside the input length and we only split on ascii
|
||||||
Ok(unsafe {
|
Ok(unsafe {
|
||||||
|
|
@ -22,6 +23,7 @@ thread_local! {
|
||||||
pub fn split_subject_end<'a>(input: &'a str, offset: usize) -> Result<(&'a str, &'a str)> {
|
pub fn split_subject_end<'a>(input: &'a str, offset: usize) -> Result<(&'a str, &'a str)> {
|
||||||
let start_offset = 1;
|
let start_offset = 1;
|
||||||
let end_offset = start_offset + offset;
|
let end_offset = start_offset + offset;
|
||||||
|
debug_assert!(offset <= 2);
|
||||||
let end = SUBJECT_END_FINDER
|
let end = SUBJECT_END_FINDER
|
||||||
.with(|finder| finder.find(input.as_bytes()))
|
.with(|finder| finder.find(input.as_bytes()))
|
||||||
.ok_or(Error::Incomplete)?;
|
.ok_or(Error::Incomplete)?;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::common::Team;
|
use crate::common::Team;
|
||||||
use crate::parsing::{split_once, split_subject_end};
|
use crate::parsing::{skip, split_once, split_subject_end};
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
use crate::{SubjectError, SubjectId};
|
use crate::{SubjectError, SubjectId};
|
||||||
use chrono::{NaiveDate, NaiveDateTime};
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
|
|
@ -19,7 +19,6 @@ pub struct RawEvent<'a> {
|
||||||
|
|
||||||
impl<'a> RawEvent<'a> {
|
impl<'a> RawEvent<'a> {
|
||||||
pub fn parse(line: &'a str) -> Result<Self> {
|
pub fn parse(line: &'a str) -> Result<Self> {
|
||||||
debug_assert!(!line.ends_with("\n"));
|
|
||||||
event_parser(line)
|
event_parser(line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +28,7 @@ fn event_parser(input: &str) -> Result<RawEvent> {
|
||||||
|
|
||||||
let (input, subject) = subject_parser(&input[23..])?;
|
let (input, subject) = subject_parser(&input[23..])?;
|
||||||
|
|
||||||
let (input, ty) = event_type_parser(&input[1..])?;
|
let (input, ty) = event_type_parser(input)?;
|
||||||
|
|
||||||
let params = &input[(!input.is_empty() as usize)..];
|
let params = &input[(!input.is_empty() as usize)..];
|
||||||
|
|
||||||
|
|
@ -133,6 +132,7 @@ pub fn subject_parser(input: &str) -> Result<(&str, RawSubject)> {
|
||||||
let Ok((player, input)) = split_subject_end(input, 1) else {
|
let Ok((player, input)) = split_subject_end(input, 1) else {
|
||||||
return Ok((full, RawSubject::Console))
|
return Ok((full, RawSubject::Console))
|
||||||
};
|
};
|
||||||
|
let input = skip(input, 1)?;
|
||||||
if player.ends_with("le>") {
|
if player.ends_with("le>") {
|
||||||
Ok((input, RawSubject::Console))
|
Ok((input, RawSubject::Console))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -141,15 +141,18 @@ pub fn subject_parser(input: &str) -> Result<(&str, RawSubject)> {
|
||||||
} else if input.starts_with("Te") {
|
} else if input.starts_with("Te") {
|
||||||
// Team "red" or Team "blue"
|
// Team "red" or Team "blue"
|
||||||
if &input[6..7] == "r" {
|
if &input[6..7] == "r" {
|
||||||
Ok((&input[10..], RawSubject::Team(Team::Red)))
|
Ok((&input[11..], RawSubject::Team(Team::Red)))
|
||||||
} else if &input[6..7] == "b" {
|
} else if &input[6..7] == "b" {
|
||||||
Ok((&input[11..], RawSubject::Team(Team::Blue)))
|
Ok((&input[12..], RawSubject::Team(Team::Blue)))
|
||||||
} else {
|
} else {
|
||||||
let (_, input) = split_once(&input[7..], b'"', 1)?;
|
let (_, input) = split_once(&input[7..], b'"', 1)?;
|
||||||
|
let input = skip(input, 1)?;
|
||||||
Ok((input, RawSubject::Team(Team::Spectator)))
|
Ok((input, RawSubject::Team(Team::Spectator)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let (system, input) = split_once(input, b' ', 0)?;
|
let Ok((system, input)) = split_once(input, b' ', 1) else {
|
||||||
|
return Ok(("", RawSubject::System(input)))
|
||||||
|
};
|
||||||
Ok((input, RawSubject::System(system)))
|
Ok((input, RawSubject::System(system)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue