1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 18:24:05 +02:00

fix parsing demos that have game events before the definitions

This commit is contained in:
Robin Appelman 2020-01-20 11:46:20 +01:00
commit d952c5c4bc
4 changed files with 24 additions and 6 deletions

0
src/bin/all_test.rs Normal file
View file

View file

@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::iter::FromIterator;
use bitstream_reader::{BitRead, LittleEndian};
use parse_display::Display;
use crate::demo::gameevent_gen::GameEventType;
use crate::demo::gamevent::{
@ -34,6 +35,17 @@ impl Parse for GameEventMessage {
let length: u16 = stream.read_sized(11)?;
let mut data = stream.read_bits(length as usize)?;
let event_type: GameEventTypeId = data.read()?;
// game event definitions haven't been sent yet, ignore
if state.event_definitions.len() == 0 {
return Ok(GameEventMessage {
event: Box::new(GameEvent::Unknown(RawGameEvent {
event_type: GameEventType::Unknown,
values: Vec::new(),
})),
});
}
let raw_event = match state.event_definitions.get(usize::from(event_type)) {
Some(definition) => {
let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
@ -46,7 +58,12 @@ impl Parse for GameEventMessage {
values,
}
}
None => return Err(ParseError::MalformedGameEvent(GameEventError::UnknownType)),
None => {
dbg!(state.event_definitions.len());
return Err(ParseError::MalformedGameEvent(GameEventError::UnknownType(
event_type,
)));
}
};
let event = GameEvent::from_raw_event(raw_event)?;
Ok(GameEventMessage {
@ -62,7 +79,7 @@ impl ParseBitSkip for GameEventMessage {
}
}
#[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Display)]
pub struct GameEventTypeId(#[size = 9] u16);
impl From<GameEventTypeId> for usize {

View file

@ -154,7 +154,7 @@ impl Parse for PacketEntitiesMessage {
for _ in 0..updated_entries {
let diff: u32 = read_bit_var(&mut data)?;
last_index += diff as i32 + 1;
last_index = last_index.saturating_add(diff as i32).saturating_add(1);
let entity_index = EntityId::from(last_index as u32);
let pvs = data.read()?;

View file

@ -1,4 +1,5 @@
use crate::demo::gamevent::GameEventValueType;
use crate::demo::message::gameevent::GameEventTypeId;
use crate::demo::message::packetentities::EntityId;
use crate::demo::packet::datatable::{ClassId, SendTableName};
use bitstream_reader::{FromUtf8Error, ReadError};
@ -46,7 +47,7 @@ pub enum ParseError {
DataRemaining(usize),
#[error(display = "String table with index {} not found", _0)]
StringTableNotFound(u8),
#[error(display = "A malformed game event was read")]
#[error(display = "A malformed game event was read: {}", _0)]
MalformedGameEvent(#[error(source)] GameEventError),
#[error(
display = "A read game event doesn't contain the expected values, expected type {} for {} event, got type {}",
@ -95,8 +96,8 @@ pub enum GameEventError {
IncorrectValueCount,
#[error(display = "Event with 'none' value")]
NoneValue,
#[error(display = "Unknown type")]
UnknownType,
#[error(display = "Unknown type: {}", _0)]
UnknownType(GameEventTypeId),
}
impl From<ReadError> for ParseError {