From b65630871a5c14489270d1e6bfe19879f1010587 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 21 May 2020 12:46:02 +0200 Subject: ignore unknown statechanges in parse_events The reason why we "unwrap" the error so late is because we want to recover from this error, which means the file pointer has to be at the right position. Unwrapping early would leave the pointer in the middle of an event, which is not what we want. If we want to bullet-proof this, it might be good to read the whole event first into a buffer, and then read from that buffer instead. --- src/event.rs | 3 +-- src/raw/parser.rs | 16 ++++++++++++---- src/raw/types.rs | 10 ---------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/event.rs b/src/event.rs index a598d3d..971a1a3 100644 --- a/src/event.rs +++ b/src/event.rs @@ -378,8 +378,7 @@ impl TryFrom<&raw::CbtEvent> for Event { | CbtStateChange::SkillInfo | CbtStateChange::SkillTiming | CbtStateChange::BreakbarState - | CbtStateChange::BreakbarPercent - | CbtStateChange::Unknown => { + | CbtStateChange::BreakbarPercent => { return Err(FromRawEventError::UnknownStateChange( raw_event.is_statechange, )) diff --git a/src/raw/parser.rs b/src/raw/parser.rs index 8401146..05f6711 100644 --- a/src/raw/parser.rs +++ b/src/raw/parser.rs @@ -155,6 +155,9 @@ pub enum ParseError { /// The revision used by the file is not known. #[error("unknown revision: {0}")] UnknownRevision(u8), + /// The event contains a statechange that we don't know about. + #[error("unknown statechange event: {0}")] + UnknownStateChange(u8), /// The given ZIP archive is invalid. #[error("invalid archive: {0}")] InvalidZip(#[from] zip::result::ZipError), @@ -312,6 +315,9 @@ pub fn parse_events( let event = parser(&mut input); match event { Ok(x) => result.push(x), + Err(ParseError::UnknownStateChange(_)) => { + // Ignore unknown statechanges, as advised by arcdps. + }, Err(ParseError::Io(ref e)) if e.kind() == ErrorKind::UnexpectedEof => { return Ok(result) } @@ -349,8 +355,9 @@ pub fn parse_event_rev0(mut input: R) -> ParseResult { let is_ninety = input.read_u8()? != 0; let is_fifty = input.read_u8()? != 0; let is_moving = input.read_u8()? != 0; + let statechange = input.read_u8()?; let is_statechange = - CbtStateChange::from_u8(input.read_u8()?).unwrap_or(CbtStateChange::Unknown); + CbtStateChange::from_u8(statechange).ok_or(ParseError::UnknownStateChange(statechange)); let is_flanking = input.read_u8()? != 0; let is_shields = input.read_u8()? != 0; @@ -377,7 +384,7 @@ pub fn parse_event_rev0(mut input: R) -> ParseResult { is_ninety, is_fifty, is_moving, - is_statechange, + is_statechange: is_statechange?, is_flanking, is_shields, is_offcycle: false, @@ -410,8 +417,9 @@ pub fn parse_event_rev1(mut input: R) -> ParseResult { let is_ninety = input.read_u8()? != 0; let is_fifty = input.read_u8()? != 0; let is_moving = input.read_u8()? != 0; + let statechange = input.read_u8()?; let is_statechange = - CbtStateChange::from_u8(input.read_u8()?).unwrap_or(CbtStateChange::Unknown); + CbtStateChange::from_u8(statechange).ok_or(ParseError::UnknownStateChange(statechange)); let is_flanking = input.read_u8()? != 0; let is_shields = input.read_u8()? != 0; let is_offcycle = input.read_u8()? != 0; @@ -439,7 +447,7 @@ pub fn parse_event_rev1(mut input: R) -> ParseResult { is_ninety, is_fifty, is_moving, - is_statechange, + is_statechange: is_statechange?, is_flanking, is_shields, is_offcycle, diff --git a/src/raw/types.rs b/src/raw/types.rs index 9931ea9..820d7a5 100644 --- a/src/raw/types.rs +++ b/src/raw/types.rs @@ -201,16 +201,6 @@ pub enum CbtStateChange { BreakbarPercent, /// `time` is the start of the error string. Error, - /// The given state change is unknown. - /// - /// Note that this is not defined by arcdps itself, we just use this value as an easy way out - /// for when unknown statechanges are introduces. - /// - /// This is for future proofing, whenever a new event is added, we'd otherwise have to update - /// `evtclib` as well. The arcdps evtc README states to *make sure to ignore unknown - /// statechange types.* - // Keep this as the highest value, so we don't clash with future statechange additions. - Unknown = 255, } impl Default for CbtStateChange { -- cgit v1.2.3