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:
parent
b9a92be010
commit
128bf1ceb2
17 changed files with 237 additions and 71 deletions
|
|
@ -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::vector::Vector;
|
||||
|
|
@ -44,3 +44,5 @@ impl BitRead<LittleEndian> for BSPDecalMessage {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for BSPDecalMessage{}
|
||||
|
|
@ -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::{ReadResult, Stream};
|
||||
|
|
@ -40,3 +40,5 @@ impl BitRead<LittleEndian> for ClassInfoMessage {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for ClassInfoMessage{}
|
||||
|
|
@ -1,14 +1,15 @@
|
|||
use std::collections::HashMap;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
use bitstream_reader::{BitRead, LittleEndian, BitSkip};
|
||||
|
||||
use crate::demo::gameevent_gen::GameEventType;
|
||||
use crate::demo::gamevent::{
|
||||
GameEvent, GameEventDefinition, GameEventEntry, GameEventValue, GameEventValueType,
|
||||
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> {
|
||||
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)]
|
||||
pub struct GameEventTypeId(u16);
|
||||
|
||||
|
|
@ -102,3 +110,5 @@ impl BitRead<LittleEndian> for GameEventListMessage {
|
|||
Ok(GameEventListMessage { event_list })
|
||||
}
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for GameEventListMessage{}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::Stream;
|
||||
/// 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;
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
|
|
@ -10,7 +10,9 @@ pub struct FileMessage {
|
|||
pub requested: bool,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
impl BitSkip<LittleEndian> for FileMessage{}
|
||||
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct NetTickMessage {
|
||||
pub tick: u32,
|
||||
pub frame_time: u16,
|
||||
|
|
@ -22,7 +24,9 @@ pub struct StringCmdMessage {
|
|||
pub command: String,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
impl BitSkip<LittleEndian> for StringCmdMessage{}
|
||||
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct SigOnStateMessage {
|
||||
pub state: u8,
|
||||
pub count: u32,
|
||||
|
|
@ -33,6 +37,8 @@ pub struct PrintMessage {
|
|||
pub value: String,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for PrintMessage{}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
pub struct ServerInfoMessage {
|
||||
pub version: u16,
|
||||
|
|
@ -54,18 +60,20 @@ pub struct ServerInfoMessage {
|
|||
pub replay: bool,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
impl BitSkip<LittleEndian> for ServerInfoMessage{}
|
||||
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct SetPauseMessage {
|
||||
pub pause: bool,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct SetViewMessage {
|
||||
#[size = 11]
|
||||
pub index: u16,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct FixAngleMessage {
|
||||
pub relative: bool,
|
||||
pub x: u16,
|
||||
|
|
@ -86,7 +94,9 @@ pub struct EntityMessage {
|
|||
pub data: Stream,
|
||||
}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
impl BitSkip<LittleEndian> for EntityMessage{}
|
||||
|
||||
#[derive(BitRead, BitSize, Debug)]
|
||||
pub struct PreFetchMessage {
|
||||
#[size = 14]
|
||||
pub index: u16,
|
||||
|
|
@ -101,12 +111,16 @@ pub struct MenuMessage {
|
|||
pub index: Stream,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for MenuMessage{}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
pub struct GetCvarValueMessage {
|
||||
pub cookie: u32,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for GetCvarValueMessage{}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
#[endianness = "LittleEndian"]
|
||||
pub struct CmdKeyValuesMessage {
|
||||
|
|
@ -115,8 +129,12 @@ pub struct CmdKeyValuesMessage {
|
|||
pub data: Stream,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for CmdKeyValuesMessage{}
|
||||
|
||||
#[derive(BitRead, Debug)]
|
||||
pub struct SetConVarMessage {
|
||||
#[size_bits = 8]
|
||||
vars: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for SetConVarMessage{}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use num_traits::FromPrimitive;
|
|||
|
||||
pub use generated::*;
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use crate::demo::message::bspdecal::*;
|
||||
use crate::demo::message::classinfo::*;
|
||||
use crate::demo::message::gameevent::*;
|
||||
|
|
@ -11,7 +12,7 @@ use crate::demo::message::stringtable::*;
|
|||
use crate::demo::message::tempentities::*;
|
||||
use crate::demo::message::usermessage::*;
|
||||
use crate::demo::message::voice::*;
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use crate::demo::parser::ParseBitSkip;
|
||||
|
||||
pub mod bspdecal;
|
||||
pub mod classinfo;
|
||||
|
|
@ -23,7 +24,7 @@ pub mod tempentities;
|
|||
pub mod usermessage;
|
||||
pub mod voice;
|
||||
|
||||
#[derive(Primitive, Debug, Clone, Copy)]
|
||||
#[derive(Primitive, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum MessageType {
|
||||
Empty = 0,
|
||||
File = 2,
|
||||
|
|
@ -98,6 +99,45 @@ pub enum Message {
|
|||
impl Parse for Message {
|
||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||
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 {
|
||||
MessageType::Empty => Message::Empty,
|
||||
MessageType::File => Message::File(FileMessage::parse(stream, state)?),
|
||||
|
|
@ -151,39 +191,37 @@ impl Parse for Message {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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 skip_type(message_type: MessageType, stream: &mut Stream) -> Result<()> {
|
||||
match message_type {
|
||||
MessageType::Empty => Ok(()),
|
||||
MessageType::File => FileMessage::parse_skip(stream),
|
||||
MessageType::NetTick => NetTickMessage::parse_skip(stream),
|
||||
MessageType::StringCmd => StringCmdMessage::parse_skip(stream),
|
||||
MessageType::SetConVar => SetConVarMessage::parse_skip(stream),
|
||||
MessageType::SigOnState => SigOnStateMessage::parse_skip(stream),
|
||||
MessageType::Print => PrintMessage::parse_skip(stream),
|
||||
MessageType::ServerInfo => ServerInfoMessage::parse_skip(stream),
|
||||
MessageType::ClassInfo => ClassInfoMessage::parse_skip(stream),
|
||||
MessageType::SetPause => SetPauseMessage::parse_skip(stream),
|
||||
MessageType::CreateStringTable => CreateStringTableMessage::parse_skip(stream),
|
||||
MessageType::UpdateStringTable => UpdateStringTableMessage::parse_skip(stream),
|
||||
MessageType::VoiceInit => VoiceInitMessage::parse_skip(stream),
|
||||
MessageType::VoiceData => VoiceDataMessage::parse_skip(stream),
|
||||
MessageType::ParseSounds => ParseSoundsMessage::parse_skip(stream),
|
||||
MessageType::SetView => SetViewMessage::parse_skip(stream),
|
||||
MessageType::FixAngle => FixAngleMessage::parse_skip(stream),
|
||||
MessageType::BspDecal => BSPDecalMessage::parse_skip(stream),
|
||||
MessageType::UserMessage => UserMessage::parse_skip(stream),
|
||||
MessageType::EntityMessage => EntityMessage::parse_skip(stream),
|
||||
MessageType::GameEvent => GameEventMessage::parse_skip(stream),
|
||||
MessageType::PacketEntities => PacketEntitiesMessage::parse_skip(stream),
|
||||
MessageType::TempEntities => TempEntitiesMessage::parse_skip(stream),
|
||||
MessageType::PreFetch => PreFetchMessage::parse_skip(stream),
|
||||
MessageType::Menu => MenuMessage::parse_skip(stream),
|
||||
MessageType::GameEventList => GameEventListMessage::parse_skip(stream),
|
||||
MessageType::GetCvarValue => GetCvarValueMessage::parse_skip(stream),
|
||||
MessageType::CmdKeyValues => CmdKeyValuesMessage::parse_skip(stream),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use bitstream_reader::BitRead;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{Parse, ParserState, Result, Stream, ParseError};
|
||||
use crate::demo::packet::datatable::ServerClass;
|
||||
use crate::demo::sendprop::SendProp;
|
||||
use crate::{Parse, ParserState, Result, Stream};
|
||||
use crate::demo::parser::ParseBitSkip;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ use bitstream_reader::{BitBuffer, BitStream, LittleEndian};
|
|||
use num_traits::{PrimInt, Unsigned};
|
||||
use snap::Decoder;
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||
use crate::demo::packet::stringtable::{
|
||||
ExtraData, FixedUserdataSize, StringTable, StringTableEntry,
|
||||
};
|
||||
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||
use crate::demo::parser::ParseBitSkip;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CreateStringTableMessage {
|
||||
|
|
@ -33,13 +34,13 @@ impl Parse for CreateStringTableMessage {
|
|||
let max_entries: u16 = stream.read()?;
|
||||
let encode_bits = log_base2(max_entries);
|
||||
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 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 {
|
||||
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)]
|
||||
pub struct UpdateStringTableMessage {
|
||||
pub entries: Vec<(u16, StringTableEntry)>,
|
||||
|
|
@ -99,9 +117,9 @@ impl Parse for UpdateStringTableMessage {
|
|||
let table_id = stream.read_sized(5)?;
|
||||
|
||||
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) {
|
||||
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(
|
||||
stream: &mut Stream,
|
||||
table_meta: &StringTableMeta,
|
||||
|
|
@ -218,7 +246,7 @@ fn read_table_entry(
|
|||
} else {
|
||||
None
|
||||
}
|
||||
.map(ExtraData::new);
|
||||
.map(ExtraData::new);
|
||||
|
||||
Ok(StringTableEntry { text, extra_data })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use crate::{Parse, ParserState, Result, Stream};
|
||||
use crate::{Parse, ParserState, Result, Stream, ParseError};
|
||||
|
||||
use super::packetentities::PacketEntity;
|
||||
use super::stringtable::read_var_int;
|
||||
use crate::demo::parser::ParseBitSkip;
|
||||
|
||||
#[derive(Debug)]
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
use bitstream_reader::{BitRead, BitSkip, LittleEndian};
|
||||
use enum_primitive_derive::Primitive;
|
||||
use num_traits::FromPrimitive;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{ReadResult, Stream};
|
||||
use crate::{ReadResult, Stream, Result, ParseError};
|
||||
use crate::demo::parser::ParseBitSkip;
|
||||
|
||||
#[derive(Primitive, Clone, Copy, Debug)]
|
||||
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)]
|
||||
pub enum ChatMessageKind {
|
||||
#[serde(rename = "TF_Chat_All")]
|
||||
|
|
@ -146,7 +156,7 @@ impl BitRead<LittleEndian> for SayText2Message {
|
|||
if first == 7 {
|
||||
let _color = stream.read_string(Some(6))?;
|
||||
} else {
|
||||
let _ = stream.skip(8)?;
|
||||
let _ = stream.skip_bits(8)?;
|
||||
}
|
||||
|
||||
let text: String = stream.read()?;
|
||||
|
|
@ -169,7 +179,7 @@ impl BitRead<LittleEndian> for SayText2Message {
|
|||
let kind = stream.read()?;
|
||||
let from = stream.read()?;
|
||||
let text = stream.read()?;
|
||||
let _ = stream.skip(16)?;
|
||||
let _ = stream.skip_bits(16)?;
|
||||
(kind, from, text)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
use bitstream_reader::{BitRead, LittleEndian, BitSkip};
|
||||
|
||||
use crate::{ReadResult, Stream};
|
||||
|
||||
|
|
@ -30,6 +30,8 @@ impl BitRead<LittleEndian> for VoiceInitMessage {
|
|||
}
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for VoiceInitMessage{}
|
||||
|
||||
#[derive(BitRead, Debug, Clone)]
|
||||
#[endianness = "LittleEndian"]
|
||||
pub struct VoiceDataMessage {
|
||||
|
|
@ -40,6 +42,8 @@ pub struct VoiceDataMessage {
|
|||
data: Stream,
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for VoiceDataMessage{}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParseSoundsMessage {
|
||||
pub reliable: bool,
|
||||
|
|
@ -67,3 +71,5 @@ impl BitRead<LittleEndian> for ParseSoundsMessage {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl BitSkip<LittleEndian> for ParseSoundsMessage{}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use bitstream_reader::{BitRead, LazyBitReadSized, LittleEndian};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{ReadResult, Stream};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
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::demo::message::{Message, MessageType};
|
||||
use crate::demo::vector::Vector;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MessagePacket {
|
||||
|
|
@ -57,10 +57,13 @@ impl Parse for MessagePacket {
|
|||
|
||||
let mut messages: Vec<Message> = Vec::with_capacity(25);
|
||||
while packet_data.bits_left() > 6 {
|
||||
let message = Message::parse(&mut packet_data, state)?;
|
||||
match message {
|
||||
Message::Empty => {}
|
||||
_ => messages.push(message),
|
||||
let message_type = MessageType::parse(&mut packet_data, state)?;
|
||||
|
||||
if state.parse_message_types.contains(&message_type) {
|
||||
let message = Message::from_type(message_type, &mut packet_data, state)?;
|
||||
messages.push(message);
|
||||
} else {
|
||||
let _ = Message::skip_type(message_type, &mut packet_data)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ impl BitRead<LittleEndian> for UserCmdPacket {
|
|||
let tick = stream.read()?;
|
||||
let sequence_out = 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
|
||||
Ok(UserCmdPacket { tick, sequence_out })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ impl Analyser {
|
|||
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) {
|
||||
match message {
|
||||
UserMessage::SayText2(message) => match message.kind {
|
||||
|
|
|
|||
|
|
@ -25,11 +25,15 @@ pub struct DemoHandler {
|
|||
|
||||
impl DemoHandler {
|
||||
pub fn new() -> Self {
|
||||
let mut state = ParserState::new();
|
||||
let analyser = Analyser::new();
|
||||
state.parse_message_types.extend(analyser.get_message_types());
|
||||
|
||||
DemoHandler {
|
||||
tick: 0,
|
||||
string_table_names: Vec::new(),
|
||||
analyser: Analyser::new(),
|
||||
state_handler: ParserState::new(),
|
||||
analyser,
|
||||
state_handler: state,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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::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 {
|
||||
stream: Stream,
|
||||
handler: DemoHandler,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::demo::gamevent::GameEventDefinition;
|
||||
use crate::demo::message::{Message, MessageType};
|
||||
use crate::demo::message::gameevent::GameEventTypeId;
|
||||
use crate::demo::message::packetentities::EntityId;
|
||||
use crate::demo::message::stringtable::StringTableMeta;
|
||||
use crate::demo::message::{Message, MessageType};
|
||||
use crate::demo::packet::datatable::{SendTable, ServerClass};
|
||||
use crate::demo::packet::stringtable::StringTableEntry;
|
||||
use crate::demo::parser::handler::{MessageHandler, StringTableEntryHandler};
|
||||
|
|
@ -28,6 +28,7 @@ pub struct ParserState {
|
|||
pub server_classes: Vec<ServerClass>,
|
||||
pub instance_baselines: [HashMap<EntityId, Vec<SendProp>>; 2],
|
||||
pub demo_meta: DemoMeta,
|
||||
pub parse_message_types: Vec<MessageType>,
|
||||
}
|
||||
|
||||
pub struct StaticBaseline {
|
||||
|
|
@ -48,7 +49,14 @@ impl StaticBaseline {
|
|||
|
||||
impl ParserState {
|
||||
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(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue