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

skip messages we dont care about

This commit is contained in:
Robin Appelman 2019-03-17 18:44:33 +01:00
commit 128bf1ceb2
17 changed files with 237 additions and 71 deletions

View file

@ -1,4 +1,4 @@
use bitstream_reader::{BitRead, LittleEndian}; use bitstream_reader::{BitRead, LittleEndian, BitSkip};
use crate::demo::sendprop::read_bit_coord; use crate::demo::sendprop::read_bit_coord;
use crate::demo::vector::Vector; use crate::demo::vector::Vector;
@ -44,3 +44,5 @@ impl BitRead<LittleEndian> for BSPDecalMessage {
}) })
} }
} }
impl BitSkip<LittleEndian> for BSPDecalMessage{}

View file

@ -1,4 +1,4 @@
use bitstream_reader::{BitRead, BitReadSized, LittleEndian}; use bitstream_reader::{BitRead, BitReadSized, LittleEndian, BitSkip};
use crate::demo::message::stringtable::log_base2; use crate::demo::message::stringtable::log_base2;
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};
@ -40,3 +40,5 @@ impl BitRead<LittleEndian> for ClassInfoMessage {
}) })
} }
} }
impl BitSkip<LittleEndian> for ClassInfoMessage{}

View file

@ -1,14 +1,15 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::iter::FromIterator; use std::iter::FromIterator;
use bitstream_reader::{BitRead, LittleEndian}; use bitstream_reader::{BitRead, LittleEndian, BitSkip};
use crate::demo::gameevent_gen::GameEventType; use crate::demo::gameevent_gen::GameEventType;
use crate::demo::gamevent::{ use crate::demo::gamevent::{
GameEvent, GameEventDefinition, GameEventEntry, GameEventValue, GameEventValueType, GameEvent, GameEventDefinition, GameEventEntry, GameEventValue, GameEventValueType,
RawGameEvent, RawGameEvent,
}; };
use crate::{Parse, ParserState, ReadResult, Result, Stream}; use crate::{Parse, ParserState, ReadResult, Result, Stream, ParseError};
use crate::demo::parser::ParseBitSkip;
fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<GameEventValue> { fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<GameEventValue> {
Ok(match definition.kind { Ok(match definition.kind {
@ -52,6 +53,13 @@ impl Parse for GameEventMessage {
} }
} }
impl ParseBitSkip for GameEventMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let length: u16 = stream.read_sized(11)?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GameEventTypeId(u16); pub struct GameEventTypeId(u16);
@ -102,3 +110,5 @@ impl BitRead<LittleEndian> for GameEventListMessage {
Ok(GameEventListMessage { event_list }) Ok(GameEventListMessage { event_list })
} }
} }
impl BitSkip<LittleEndian> for GameEventListMessage{}

View file

@ -1,6 +1,6 @@
use crate::Stream; use crate::Stream;
/// Messages that consists only of primitives and string and can be derived /// Messages that consists only of primitives and string and can be derived
use bitstream_reader::{BitRead, LittleEndian}; use bitstream_reader::{BitRead, LittleEndian, BitSize, BitSkip};
use std::collections::HashMap; use std::collections::HashMap;
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
@ -10,7 +10,9 @@ pub struct FileMessage {
pub requested: bool, pub requested: bool,
} }
#[derive(BitRead, Debug)] impl BitSkip<LittleEndian> for FileMessage{}
#[derive(BitRead, BitSize, Debug)]
pub struct NetTickMessage { pub struct NetTickMessage {
pub tick: u32, pub tick: u32,
pub frame_time: u16, pub frame_time: u16,
@ -22,7 +24,9 @@ pub struct StringCmdMessage {
pub command: String, pub command: String,
} }
#[derive(BitRead, Debug)] impl BitSkip<LittleEndian> for StringCmdMessage{}
#[derive(BitRead, BitSize, Debug)]
pub struct SigOnStateMessage { pub struct SigOnStateMessage {
pub state: u8, pub state: u8,
pub count: u32, pub count: u32,
@ -33,6 +37,8 @@ pub struct PrintMessage {
pub value: String, pub value: String,
} }
impl BitSkip<LittleEndian> for PrintMessage{}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct ServerInfoMessage { pub struct ServerInfoMessage {
pub version: u16, pub version: u16,
@ -54,18 +60,20 @@ pub struct ServerInfoMessage {
pub replay: bool, pub replay: bool,
} }
#[derive(BitRead, Debug)] impl BitSkip<LittleEndian> for ServerInfoMessage{}
#[derive(BitRead, BitSize, Debug)]
pub struct SetPauseMessage { pub struct SetPauseMessage {
pub pause: bool, pub pause: bool,
} }
#[derive(BitRead, Debug)] #[derive(BitRead, BitSize, Debug)]
pub struct SetViewMessage { pub struct SetViewMessage {
#[size = 11] #[size = 11]
pub index: u16, pub index: u16,
} }
#[derive(BitRead, Debug)] #[derive(BitRead, BitSize, Debug)]
pub struct FixAngleMessage { pub struct FixAngleMessage {
pub relative: bool, pub relative: bool,
pub x: u16, pub x: u16,
@ -86,7 +94,9 @@ pub struct EntityMessage {
pub data: Stream, pub data: Stream,
} }
#[derive(BitRead, Debug)] impl BitSkip<LittleEndian> for EntityMessage{}
#[derive(BitRead, BitSize, Debug)]
pub struct PreFetchMessage { pub struct PreFetchMessage {
#[size = 14] #[size = 14]
pub index: u16, pub index: u16,
@ -101,12 +111,16 @@ pub struct MenuMessage {
pub index: Stream, pub index: Stream,
} }
impl BitSkip<LittleEndian> for MenuMessage{}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct GetCvarValueMessage { pub struct GetCvarValueMessage {
pub cookie: u32, pub cookie: u32,
pub value: String, pub value: String,
} }
impl BitSkip<LittleEndian> for GetCvarValueMessage{}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
#[endianness = "LittleEndian"] #[endianness = "LittleEndian"]
pub struct CmdKeyValuesMessage { pub struct CmdKeyValuesMessage {
@ -115,8 +129,12 @@ pub struct CmdKeyValuesMessage {
pub data: Stream, pub data: Stream,
} }
impl BitSkip<LittleEndian> for CmdKeyValuesMessage{}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct SetConVarMessage { pub struct SetConVarMessage {
#[size_bits = 8] #[size_bits = 8]
vars: HashMap<String, String>, vars: HashMap<String, String>,
} }
impl BitSkip<LittleEndian> for SetConVarMessage{}

View file

@ -3,6 +3,7 @@ use num_traits::FromPrimitive;
pub use generated::*; pub use generated::*;
use crate::{Parse, ParseError, ParserState, Result, Stream};
use crate::demo::message::bspdecal::*; use crate::demo::message::bspdecal::*;
use crate::demo::message::classinfo::*; use crate::demo::message::classinfo::*;
use crate::demo::message::gameevent::*; use crate::demo::message::gameevent::*;
@ -11,7 +12,7 @@ use crate::demo::message::stringtable::*;
use crate::demo::message::tempentities::*; use crate::demo::message::tempentities::*;
use crate::demo::message::usermessage::*; use crate::demo::message::usermessage::*;
use crate::demo::message::voice::*; use crate::demo::message::voice::*;
use crate::{Parse, ParseError, ParserState, Result, Stream}; use crate::demo::parser::ParseBitSkip;
pub mod bspdecal; pub mod bspdecal;
pub mod classinfo; pub mod classinfo;
@ -23,7 +24,7 @@ pub mod tempentities;
pub mod usermessage; pub mod usermessage;
pub mod voice; pub mod voice;
#[derive(Primitive, Debug, Clone, Copy)] #[derive(Primitive, Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageType { pub enum MessageType {
Empty = 0, Empty = 0,
File = 2, File = 2,
@ -98,6 +99,45 @@ pub enum Message {
impl Parse for Message { impl Parse for Message {
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> { fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
let message_type = MessageType::parse(stream, state)?; let message_type = MessageType::parse(stream, state)?;
Self::from_type(message_type, stream, state)
}
}
impl Message {
pub fn get_message_type(&self) -> MessageType {
match self {
Message::Empty => MessageType::Empty,
Message::File(_) => MessageType::File,
Message::NetTick(_) => MessageType::NetTick,
Message::StringCmd(_) => MessageType::StringCmd,
Message::SetConVar(_) => MessageType::SetConVar,
Message::SigOnState(_) => MessageType::SigOnState,
Message::Print(_) => MessageType::Print,
Message::ServerInfo(_) => MessageType::ServerInfo,
Message::ClassInfo(_) => MessageType::ClassInfo,
Message::SetPause(_) => MessageType::SetPause,
Message::CreateStringTable(_) => MessageType::CreateStringTable,
Message::UpdateStringTable(_) => MessageType::UpdateStringTable,
Message::VoiceInit(_) => MessageType::VoiceInit,
Message::VoiceData(_) => MessageType::VoiceData,
Message::ParseSounds(_) => MessageType::ParseSounds,
Message::SetView(_) => MessageType::SetView,
Message::FixAngle(_) => MessageType::FixAngle,
Message::BspDecal(_) => MessageType::BspDecal,
Message::UserMessage(_) => MessageType::UserMessage,
Message::EntityMessage(_) => MessageType::EntityMessage,
Message::GameEvent(_) => MessageType::GameEvent,
Message::PacketEntities(_) => MessageType::PacketEntities,
Message::TempEntities(_) => MessageType::TempEntities,
Message::PreFetch(_) => MessageType::PreFetch,
Message::Menu(_) => MessageType::Menu,
Message::GameEventList(_) => MessageType::GameEventList,
Message::GetCvarValue(_) => MessageType::GetCvarValue,
Message::CmdKeyValues(_) => MessageType::CmdKeyValues,
}
}
pub fn from_type(message_type: MessageType, stream: &mut Stream, state: &ParserState) -> Result<Self> {
Ok(match message_type { Ok(match message_type {
MessageType::Empty => Message::Empty, MessageType::Empty => Message::Empty,
MessageType::File => Message::File(FileMessage::parse(stream, state)?), MessageType::File => Message::File(FileMessage::parse(stream, state)?),
@ -151,39 +191,37 @@ impl Parse for Message {
} }
}) })
} }
}
impl Message { pub fn skip_type(message_type: MessageType, stream: &mut Stream) -> Result<()> {
pub fn get_message_type(&self) -> MessageType { match message_type {
match self { MessageType::Empty => Ok(()),
Message::Empty => MessageType::Empty, MessageType::File => FileMessage::parse_skip(stream),
Message::File(_) => MessageType::File, MessageType::NetTick => NetTickMessage::parse_skip(stream),
Message::NetTick(_) => MessageType::NetTick, MessageType::StringCmd => StringCmdMessage::parse_skip(stream),
Message::StringCmd(_) => MessageType::StringCmd, MessageType::SetConVar => SetConVarMessage::parse_skip(stream),
Message::SetConVar(_) => MessageType::SetConVar, MessageType::SigOnState => SigOnStateMessage::parse_skip(stream),
Message::SigOnState(_) => MessageType::SigOnState, MessageType::Print => PrintMessage::parse_skip(stream),
Message::Print(_) => MessageType::Print, MessageType::ServerInfo => ServerInfoMessage::parse_skip(stream),
Message::ServerInfo(_) => MessageType::ServerInfo, MessageType::ClassInfo => ClassInfoMessage::parse_skip(stream),
Message::ClassInfo(_) => MessageType::ClassInfo, MessageType::SetPause => SetPauseMessage::parse_skip(stream),
Message::SetPause(_) => MessageType::SetPause, MessageType::CreateStringTable => CreateStringTableMessage::parse_skip(stream),
Message::CreateStringTable(_) => MessageType::CreateStringTable, MessageType::UpdateStringTable => UpdateStringTableMessage::parse_skip(stream),
Message::UpdateStringTable(_) => MessageType::UpdateStringTable, MessageType::VoiceInit => VoiceInitMessage::parse_skip(stream),
Message::VoiceInit(_) => MessageType::VoiceInit, MessageType::VoiceData => VoiceDataMessage::parse_skip(stream),
Message::VoiceData(_) => MessageType::VoiceData, MessageType::ParseSounds => ParseSoundsMessage::parse_skip(stream),
Message::ParseSounds(_) => MessageType::ParseSounds, MessageType::SetView => SetViewMessage::parse_skip(stream),
Message::SetView(_) => MessageType::SetView, MessageType::FixAngle => FixAngleMessage::parse_skip(stream),
Message::FixAngle(_) => MessageType::FixAngle, MessageType::BspDecal => BSPDecalMessage::parse_skip(stream),
Message::BspDecal(_) => MessageType::BspDecal, MessageType::UserMessage => UserMessage::parse_skip(stream),
Message::UserMessage(_) => MessageType::UserMessage, MessageType::EntityMessage => EntityMessage::parse_skip(stream),
Message::EntityMessage(_) => MessageType::EntityMessage, MessageType::GameEvent => GameEventMessage::parse_skip(stream),
Message::GameEvent(_) => MessageType::GameEvent, MessageType::PacketEntities => PacketEntitiesMessage::parse_skip(stream),
Message::PacketEntities(_) => MessageType::PacketEntities, MessageType::TempEntities => TempEntitiesMessage::parse_skip(stream),
Message::TempEntities(_) => MessageType::TempEntities, MessageType::PreFetch => PreFetchMessage::parse_skip(stream),
Message::PreFetch(_) => MessageType::PreFetch, MessageType::Menu => MenuMessage::parse_skip(stream),
Message::Menu(_) => MessageType::Menu, MessageType::GameEventList => GameEventListMessage::parse_skip(stream),
Message::GameEventList(_) => MessageType::GameEventList, MessageType::GetCvarValue => GetCvarValueMessage::parse_skip(stream),
Message::GetCvarValue(_) => MessageType::GetCvarValue, MessageType::CmdKeyValues => CmdKeyValuesMessage::parse_skip(stream),
Message::CmdKeyValues(_) => MessageType::CmdKeyValues,
} }
} }
} }

View file

@ -1,9 +1,10 @@
use bitstream_reader::BitRead; use bitstream_reader::BitRead;
use serde::Serialize; use serde::Serialize;
use crate::{Parse, ParserState, Result, Stream, ParseError};
use crate::demo::packet::datatable::ServerClass; use crate::demo::packet::datatable::ServerClass;
use crate::demo::sendprop::SendProp; use crate::demo::sendprop::SendProp;
use crate::{Parse, ParserState, Result, Stream}; use crate::demo::parser::ParseBitSkip;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize)]
pub struct EntityId(u32); pub struct EntityId(u32);
@ -66,3 +67,15 @@ impl Parse for PacketEntitiesMessage {
}) })
} }
} }
impl ParseBitSkip for PacketEntitiesMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _: u16 = stream.read_sized(11)?;
let _: Option<u32> = stream.read()?;
let _: u8 = stream.read_sized(1)?;
let _: u16 = stream.read_sized(11)?;
let length: u32 = stream.read_sized(20)?;
let _: bool = stream.read()?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}

View file

@ -2,10 +2,11 @@ use bitstream_reader::{BitBuffer, BitStream, LittleEndian};
use num_traits::{PrimInt, Unsigned}; use num_traits::{PrimInt, Unsigned};
use snap::Decoder; use snap::Decoder;
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
use crate::demo::packet::stringtable::{ use crate::demo::packet::stringtable::{
ExtraData, FixedUserdataSize, StringTable, StringTableEntry, ExtraData, FixedUserdataSize, StringTable, StringTableEntry,
}; };
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream}; use crate::demo::parser::ParseBitSkip;
#[derive(Debug)] #[derive(Debug)]
pub struct CreateStringTableMessage { pub struct CreateStringTableMessage {
@ -33,13 +34,13 @@ impl Parse for CreateStringTableMessage {
let max_entries: u16 = stream.read()?; let max_entries: u16 = stream.read()?;
let encode_bits = log_base2(max_entries); let encode_bits = log_base2(max_entries);
let entity_count: u16 = stream.read_sized(encode_bits as usize + 1)?; let entity_count: u16 = stream.read_sized(encode_bits as usize + 1)?;
let bit_count = read_var_int(stream)?; let length = read_var_int(stream)?;
let fixed_userdata_size = stream.read()?; let fixed_userdata_size = stream.read()?;
let compressed = stream.read()?; let compressed = stream.read()?;
let mut table_data = stream.read_bits(bit_count as usize)?; let mut table_data = stream.read_bits(length as usize)?;
if compressed { if compressed {
let decompressed_size: u32 = table_data.read()?; let decompressed_size: u32 = table_data.read()?;
@ -88,6 +89,23 @@ impl Parse for CreateStringTableMessage {
} }
} }
impl ParseBitSkip for CreateStringTableMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _: String = stream.read()?;
let max_entries: u16 = stream.read()?;
let encode_bits = log_base2(max_entries);
let _: u16 = stream.read_sized(encode_bits as usize + 1)?;
let length = read_var_int(stream)?;
let _: Option<FixedUserdataSize> = stream.read()?;
let _: bool = stream.read()?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct UpdateStringTableMessage { pub struct UpdateStringTableMessage {
pub entries: Vec<(u16, StringTableEntry)>, pub entries: Vec<(u16, StringTableEntry)>,
@ -99,9 +117,9 @@ impl Parse for UpdateStringTableMessage {
let table_id = stream.read_sized(5)?; let table_id = stream.read_sized(5)?;
let changed: u16 = if stream.read()? { stream.read()? } else { 1 }; let changed: u16 = if stream.read()? { stream.read()? } else { 1 };
let len = stream.read_int(20)?; let length: u32 = stream.read_int(20)?;
let mut data = stream.read_bits(len)?; let mut data = stream.read_bits(length as usize)?;
let entries = match state.string_tables.get(table_id as usize) { let entries = match state.string_tables.get(table_id as usize) {
Some(table) => parse_string_table_update(&mut data, table, changed), Some(table) => parse_string_table_update(&mut data, table, changed),
@ -112,6 +130,16 @@ impl Parse for UpdateStringTableMessage {
} }
} }
impl ParseBitSkip for UpdateStringTableMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _: u8 = stream.read_sized(5)?;
let _: u16 = if stream.read()? { stream.read()? } else { 1 };
let length: u32 = stream.read_int(20)?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}
fn parse_string_table_update( fn parse_string_table_update(
stream: &mut Stream, stream: &mut Stream,
table_meta: &StringTableMeta, table_meta: &StringTableMeta,
@ -218,7 +246,7 @@ fn read_table_entry(
} else { } else {
None None
} }
.map(ExtraData::new); .map(ExtraData::new);
Ok(StringTableEntry { text, extra_data }) Ok(StringTableEntry { text, extra_data })
} }

View file

@ -1,7 +1,8 @@
use crate::{Parse, ParserState, Result, Stream}; use crate::{Parse, ParserState, Result, Stream, ParseError};
use super::packetentities::PacketEntity; use super::packetentities::PacketEntity;
use super::stringtable::read_var_int; use super::stringtable::read_var_int;
use crate::demo::parser::ParseBitSkip;
#[derive(Debug)] #[derive(Debug)]
pub struct TempEntitiesMessage { pub struct TempEntitiesMessage {
@ -19,3 +20,11 @@ impl Parse for TempEntitiesMessage {
}) })
} }
} }
impl ParseBitSkip for TempEntitiesMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _: u8 = stream.read()?;
let length = read_var_int(stream)?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}

View file

@ -1,9 +1,10 @@
use bitstream_reader::{BitRead, LittleEndian}; use bitstream_reader::{BitRead, BitSkip, LittleEndian};
use enum_primitive_derive::Primitive; use enum_primitive_derive::Primitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use serde::Serialize; use serde::Serialize;
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream, Result, ParseError};
use crate::demo::parser::ParseBitSkip;
#[derive(Primitive, Clone, Copy, Debug)] #[derive(Primitive, Clone, Copy, Debug)]
pub enum UserMessageType { pub enum UserMessageType {
@ -98,6 +99,15 @@ impl BitRead<LittleEndian> for UserMessage {
} }
} }
impl ParseBitSkip for UserMessage {
fn parse_skip(stream: &mut Stream) -> Result<()> {
let _ = stream.skip_bits(8)?;
let length:u32 = stream.read_int(11)?;
stream.skip_bits(length as usize).map_err(ParseError::from)
}
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum ChatMessageKind { pub enum ChatMessageKind {
#[serde(rename = "TF_Chat_All")] #[serde(rename = "TF_Chat_All")]
@ -146,7 +156,7 @@ impl BitRead<LittleEndian> for SayText2Message {
if first == 7 { if first == 7 {
let _color = stream.read_string(Some(6))?; let _color = stream.read_string(Some(6))?;
} else { } else {
let _ = stream.skip(8)?; let _ = stream.skip_bits(8)?;
} }
let text: String = stream.read()?; let text: String = stream.read()?;
@ -169,7 +179,7 @@ impl BitRead<LittleEndian> for SayText2Message {
let kind = stream.read()?; let kind = stream.read()?;
let from = stream.read()?; let from = stream.read()?;
let text = stream.read()?; let text = stream.read()?;
let _ = stream.skip(16)?; let _ = stream.skip_bits(16)?;
(kind, from, text) (kind, from, text)
}; };

View file

@ -1,4 +1,4 @@
use bitstream_reader::{BitRead, LittleEndian}; use bitstream_reader::{BitRead, LittleEndian, BitSkip};
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};
@ -30,6 +30,8 @@ impl BitRead<LittleEndian> for VoiceInitMessage {
} }
} }
impl BitSkip<LittleEndian> for VoiceInitMessage{}
#[derive(BitRead, Debug, Clone)] #[derive(BitRead, Debug, Clone)]
#[endianness = "LittleEndian"] #[endianness = "LittleEndian"]
pub struct VoiceDataMessage { pub struct VoiceDataMessage {
@ -40,6 +42,8 @@ pub struct VoiceDataMessage {
data: Stream, data: Stream,
} }
impl BitSkip<LittleEndian> for VoiceDataMessage{}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ParseSoundsMessage { pub struct ParseSoundsMessage {
pub reliable: bool, pub reliable: bool,
@ -67,3 +71,5 @@ impl BitRead<LittleEndian> for ParseSoundsMessage {
}) })
} }
} }
impl BitSkip<LittleEndian> for ParseSoundsMessage{}

View file

@ -1,4 +1,4 @@
use bitstream_reader::{BitRead, LazyBitReadSized, LittleEndian}; use bitstream_reader::{BitRead, LittleEndian};
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};

View file

@ -1,8 +1,8 @@
use bitstream_reader::{BitRead, BitSize, LazyBitRead, LittleEndian}; use bitstream_reader::{BitRead, BitSize, LazyBitRead, LittleEndian};
use crate::demo::message::Message;
use crate::demo::vector::Vector;
use crate::{Parse, ParserState, ReadResult, Result, Stream}; use crate::{Parse, ParserState, ReadResult, Result, Stream};
use crate::demo::message::{Message, MessageType};
use crate::demo::vector::Vector;
#[derive(Debug)] #[derive(Debug)]
pub struct MessagePacket { pub struct MessagePacket {
@ -57,10 +57,13 @@ impl Parse for MessagePacket {
let mut messages: Vec<Message> = Vec::with_capacity(25); let mut messages: Vec<Message> = Vec::with_capacity(25);
while packet_data.bits_left() > 6 { while packet_data.bits_left() > 6 {
let message = Message::parse(&mut packet_data, state)?; let message_type = MessageType::parse(&mut packet_data, state)?;
match message {
Message::Empty => {} if state.parse_message_types.contains(&message_type) {
_ => messages.push(message), let message = Message::from_type(message_type, &mut packet_data, state)?;
messages.push(message);
} else {
let _ = Message::skip_type(message_type, &mut packet_data)?;
} }
} }

View file

@ -13,7 +13,7 @@ impl BitRead<LittleEndian> for UserCmdPacket {
let tick = stream.read()?; let tick = stream.read()?;
let sequence_out = stream.read()?; let sequence_out = stream.read()?;
let len: u32 = stream.read()?; let len: u32 = stream.read()?;
let _ = stream.skip(len as usize * 8)?; let _ = stream.skip_bits(len as usize * 8)?;
// TODO parse the packet data // TODO parse the packet data
Ok(UserCmdPacket { tick, sequence_out }) Ok(UserCmdPacket { tick, sequence_out })
} }

View file

@ -218,6 +218,10 @@ impl Analyser {
Self::default() Self::default()
} }
pub fn get_message_types(&self) -> Vec<MessageType> {
vec![MessageType::GameEvent, MessageType::UserMessage]
}
fn handle_user_message(&mut self, message: UserMessage, tick: u32) { fn handle_user_message(&mut self, message: UserMessage, tick: u32) {
match message { match message {
UserMessage::SayText2(message) => match message.kind { UserMessage::SayText2(message) => match message.kind {

View file

@ -25,11 +25,15 @@ pub struct DemoHandler {
impl DemoHandler { impl DemoHandler {
pub fn new() -> Self { pub fn new() -> Self {
let mut state = ParserState::new();
let analyser = Analyser::new();
state.parse_message_types.extend(analyser.get_message_types());
DemoHandler { DemoHandler {
tick: 0, tick: 0,
string_table_names: Vec::new(), string_table_names: Vec::new(),
analyser: Analyser::new(), analyser,
state_handler: ParserState::new(), state_handler: state,
} }
} }

View file

@ -1,4 +1,4 @@
use bitstream_reader::{BitRead, LittleEndian, ReadError}; use bitstream_reader::{BitRead, BitSkip, LittleEndian, ReadError};
use crate::demo::gamevent::{GameEventValue, GameEventValueType}; use crate::demo::gamevent::{GameEventValue, GameEventValueType};
use crate::demo::header::Header; use crate::demo::header::Header;
@ -74,6 +74,17 @@ impl<T: BitRead<LittleEndian>> Parse for T {
} }
} }
pub trait ParseBitSkip {
fn parse_skip(stream: &mut Stream) -> Result<()>;
}
impl<T: BitSkip<LittleEndian>> ParseBitSkip for T {
#[inline(always)]
fn parse_skip(stream: &mut Stream) -> Result<()> {
Self::skip(stream).map_err(ParseError::from)
}
}
pub struct DemoParser { pub struct DemoParser {
stream: Stream, stream: Stream,
handler: DemoHandler, handler: DemoHandler,

View file

@ -1,10 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::demo::gamevent::GameEventDefinition; use crate::demo::gamevent::GameEventDefinition;
use crate::demo::message::{Message, MessageType};
use crate::demo::message::gameevent::GameEventTypeId; use crate::demo::message::gameevent::GameEventTypeId;
use crate::demo::message::packetentities::EntityId; use crate::demo::message::packetentities::EntityId;
use crate::demo::message::stringtable::StringTableMeta; use crate::demo::message::stringtable::StringTableMeta;
use crate::demo::message::{Message, MessageType};
use crate::demo::packet::datatable::{SendTable, ServerClass}; use crate::demo::packet::datatable::{SendTable, ServerClass};
use crate::demo::packet::stringtable::StringTableEntry; use crate::demo::packet::stringtable::StringTableEntry;
use crate::demo::parser::handler::{MessageHandler, StringTableEntryHandler}; use crate::demo::parser::handler::{MessageHandler, StringTableEntryHandler};
@ -28,6 +28,7 @@ pub struct ParserState {
pub server_classes: Vec<ServerClass>, pub server_classes: Vec<ServerClass>,
pub instance_baselines: [HashMap<EntityId, Vec<SendProp>>; 2], pub instance_baselines: [HashMap<EntityId, Vec<SendProp>>; 2],
pub demo_meta: DemoMeta, pub demo_meta: DemoMeta,
pub parse_message_types: Vec<MessageType>,
} }
pub struct StaticBaseline { pub struct StaticBaseline {
@ -48,7 +49,14 @@ impl StaticBaseline {
impl ParserState { impl ParserState {
pub fn new() -> Self { pub fn new() -> Self {
ParserState::default() let mut state = ParserState::default();
state.parse_message_types.extend_from_slice(&[
MessageType::ServerInfo,
MessageType::GameEventList,
MessageType::CreateStringTable,
MessageType::UpdateStringTable
]);
state
} }
pub fn handle_data_table( pub fn handle_data_table(