mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
fix parsing demos that have game events before the definitions
This commit is contained in:
parent
3caadadb3b
commit
d952c5c4bc
4 changed files with 24 additions and 6 deletions
0
src/bin/all_test.rs
Normal file
0
src/bin/all_test.rs
Normal file
|
|
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
use bitstream_reader::{BitRead, LittleEndian};
|
use bitstream_reader::{BitRead, LittleEndian};
|
||||||
|
use parse_display::Display;
|
||||||
|
|
||||||
use crate::demo::gameevent_gen::GameEventType;
|
use crate::demo::gameevent_gen::GameEventType;
|
||||||
use crate::demo::gamevent::{
|
use crate::demo::gamevent::{
|
||||||
|
|
@ -34,6 +35,17 @@ impl Parse for GameEventMessage {
|
||||||
let length: u16 = stream.read_sized(11)?;
|
let length: u16 = stream.read_sized(11)?;
|
||||||
let mut data = stream.read_bits(length as usize)?;
|
let mut data = stream.read_bits(length as usize)?;
|
||||||
let event_type: GameEventTypeId = data.read()?;
|
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)) {
|
let raw_event = match state.event_definitions.get(usize::from(event_type)) {
|
||||||
Some(definition) => {
|
Some(definition) => {
|
||||||
let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
|
let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
|
||||||
|
|
@ -46,7 +58,12 @@ impl Parse for GameEventMessage {
|
||||||
values,
|
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)?;
|
let event = GameEvent::from_raw_event(raw_event)?;
|
||||||
Ok(GameEventMessage {
|
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);
|
pub struct GameEventTypeId(#[size = 9] u16);
|
||||||
|
|
||||||
impl From<GameEventTypeId> for usize {
|
impl From<GameEventTypeId> for usize {
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ impl Parse for PacketEntitiesMessage {
|
||||||
|
|
||||||
for _ in 0..updated_entries {
|
for _ in 0..updated_entries {
|
||||||
let diff: u32 = read_bit_var(&mut data)?;
|
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 entity_index = EntityId::from(last_index as u32);
|
||||||
|
|
||||||
let pvs = data.read()?;
|
let pvs = data.read()?;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::demo::gamevent::GameEventValueType;
|
use crate::demo::gamevent::GameEventValueType;
|
||||||
|
use crate::demo::message::gameevent::GameEventTypeId;
|
||||||
use crate::demo::message::packetentities::EntityId;
|
use crate::demo::message::packetentities::EntityId;
|
||||||
use crate::demo::packet::datatable::{ClassId, SendTableName};
|
use crate::demo::packet::datatable::{ClassId, SendTableName};
|
||||||
use bitstream_reader::{FromUtf8Error, ReadError};
|
use bitstream_reader::{FromUtf8Error, ReadError};
|
||||||
|
|
@ -46,7 +47,7 @@ pub enum ParseError {
|
||||||
DataRemaining(usize),
|
DataRemaining(usize),
|
||||||
#[error(display = "String table with index {} not found", _0)]
|
#[error(display = "String table with index {} not found", _0)]
|
||||||
StringTableNotFound(u8),
|
StringTableNotFound(u8),
|
||||||
#[error(display = "A malformed game event was read")]
|
#[error(display = "A malformed game event was read: {}", _0)]
|
||||||
MalformedGameEvent(#[error(source)] GameEventError),
|
MalformedGameEvent(#[error(source)] GameEventError),
|
||||||
#[error(
|
#[error(
|
||||||
display = "A read game event doesn't contain the expected values, expected type {} for {} event, got type {}",
|
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,
|
IncorrectValueCount,
|
||||||
#[error(display = "Event with 'none' value")]
|
#[error(display = "Event with 'none' value")]
|
||||||
NoneValue,
|
NoneValue,
|
||||||
#[error(display = "Unknown type")]
|
#[error(display = "Unknown type: {}", _0)]
|
||||||
UnknownType,
|
UnknownType(GameEventTypeId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ReadError> for ParseError {
|
impl From<ReadError> for ParseError {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue