mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 10:14:06 +02:00
borrowed data
This commit is contained in:
parent
fed1da5cb0
commit
a4ddd586dd
27 changed files with 181 additions and 176 deletions
|
|
@ -23,7 +23,7 @@ fn main() -> Result<(), MainError> {
|
||||||
.map(|arg| arg.as_str() == "all")
|
.map(|arg| arg.as_str() == "all")
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let file = fs::read(path)?;
|
let file = fs::read(path)?;
|
||||||
let demo = Demo::new(file);
|
let demo = Demo::new(&file);
|
||||||
let parser = if all {
|
let parser = if all {
|
||||||
DemoParser::new_all(demo.get_stream())
|
DemoParser::new_all(demo.get_stream())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub struct BSPDecalMessage {
|
||||||
pub low_priority: bool,
|
pub low_priority: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for BSPDecalMessage {
|
impl BitRead<'_, LittleEndian> for BSPDecalMessage {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let position = {
|
let position = {
|
||||||
let has_x = stream.read()?;
|
let has_x = stream.read()?;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ pub struct ClassInfoMessage {
|
||||||
entries: Vec<ClassInfoEntry>,
|
entries: Vec<ClassInfoEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for ClassInfoMessage {
|
impl BitRead<'_, LittleEndian> for ClassInfoMessage {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let count: u16 = stream.read()?;
|
let count: u16 = stream.read()?;
|
||||||
let create: bool = stream.read()?;
|
let create: bool = stream.read()?;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ pub struct GameEventMessage {
|
||||||
pub event: Box<GameEvent>,
|
pub event: Box<GameEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for GameEventMessage {
|
impl Parse<'_> for GameEventMessage {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||||
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)?;
|
||||||
|
|
@ -71,7 +71,7 @@ impl Parse for GameEventMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseBitSkip for GameEventMessage {
|
impl ParseBitSkip<'_> for GameEventMessage {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
||||||
let length: u16 = stream.read_sized(11)?;
|
let length: u16 = stream.read_sized(11)?;
|
||||||
stream.skip_bits(length as usize).map_err(ParseError::from)
|
stream.skip_bits(length as usize).map_err(ParseError::from)
|
||||||
|
|
@ -98,7 +98,7 @@ pub struct GameEventListMessage {
|
||||||
pub event_list: Vec<GameEventDefinition>,
|
pub event_list: Vec<GameEventDefinition>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for GameEventDefinition {
|
impl BitRead<'_, LittleEndian> for GameEventDefinition {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let event_type: GameEventTypeId = stream.read()?;
|
let event_type: GameEventTypeId = stream.read()?;
|
||||||
let name: String = stream.read()?;
|
let name: String = stream.read()?;
|
||||||
|
|
@ -123,7 +123,7 @@ impl BitRead<LittleEndian> for GameEventDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for GameEventListMessage {
|
impl BitRead<'_, LittleEndian> for GameEventListMessage {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let count: u16 = stream.read_sized(9)?;
|
let count: u16 = stream.read_sized(9)?;
|
||||||
let length: u32 = stream.read_sized(20)?;
|
let length: u32 = stream.read_sized(20)?;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ pub struct FixAngleMessage {
|
||||||
|
|
||||||
#[derive(BitRead, Debug)]
|
#[derive(BitRead, Debug)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct EntityMessage {
|
pub struct EntityMessage<'a> {
|
||||||
#[size = 11]
|
#[size = 11]
|
||||||
pub index: u16,
|
pub index: u16,
|
||||||
#[size = 9]
|
#[size = 9]
|
||||||
|
|
@ -82,7 +82,7 @@ pub struct EntityMessage {
|
||||||
#[size = 11]
|
#[size = 11]
|
||||||
pub length: u16,
|
pub length: u16,
|
||||||
#[size = "length"]
|
#[size = "length"]
|
||||||
pub data: Stream,
|
pub data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BitRead, Debug)]
|
#[derive(BitRead, Debug)]
|
||||||
|
|
@ -93,11 +93,11 @@ pub struct PreFetchMessage {
|
||||||
|
|
||||||
#[derive(BitRead, Debug)]
|
#[derive(BitRead, Debug)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct MenuMessage {
|
pub struct MenuMessage<'a> {
|
||||||
pub kind: u16,
|
pub kind: u16,
|
||||||
pub length: u16,
|
pub length: u16,
|
||||||
#[size = "length.saturating_mul(8)"]
|
#[size = "length.saturating_mul(8)"]
|
||||||
pub index: Stream,
|
pub index: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BitRead, Debug)]
|
#[derive(BitRead, Debug)]
|
||||||
|
|
@ -108,8 +108,8 @@ pub struct GetCvarValueMessage {
|
||||||
|
|
||||||
#[derive(BitRead, Debug)]
|
#[derive(BitRead, Debug)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct CmdKeyValuesMessage {
|
pub struct CmdKeyValuesMessage<'a> {
|
||||||
pub length: u32,
|
pub length: u32,
|
||||||
#[size = "length.saturating_mul(8)"]
|
#[size = "length.saturating_mul(8)"]
|
||||||
pub data: Stream,
|
pub data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ pub enum MessageType {
|
||||||
CmdKeyValues = 32,
|
CmdKeyValues = 32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for MessageType {
|
impl Parse<'_> for MessageType {
|
||||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||||
let raw = stream.read_int(6)?;
|
let raw = stream.read_int(6)?;
|
||||||
MessageType::try_from(raw).map_err(|_| ParseError::InvalidMessageType(raw))
|
MessageType::try_from(raw).map_err(|_| ParseError::InvalidMessageType(raw))
|
||||||
|
|
@ -69,7 +69,7 @@ impl Parse for MessageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Message {
|
pub enum Message<'a> {
|
||||||
Empty,
|
Empty,
|
||||||
File(FileMessage),
|
File(FileMessage),
|
||||||
NetTick(NetTickMessage),
|
NetTick(NetTickMessage),
|
||||||
|
|
@ -80,34 +80,34 @@ pub enum Message {
|
||||||
ServerInfo(Box<ServerInfoMessage>),
|
ServerInfo(Box<ServerInfoMessage>),
|
||||||
ClassInfo(ClassInfoMessage),
|
ClassInfo(ClassInfoMessage),
|
||||||
SetPause(SetPauseMessage),
|
SetPause(SetPauseMessage),
|
||||||
CreateStringTable(CreateStringTableMessage),
|
CreateStringTable(CreateStringTableMessage<'a>),
|
||||||
UpdateStringTable(UpdateStringTableMessage),
|
UpdateStringTable(UpdateStringTableMessage<'a>),
|
||||||
VoiceInit(VoiceInitMessage),
|
VoiceInit(VoiceInitMessage),
|
||||||
VoiceData(VoiceDataMessage),
|
VoiceData(VoiceDataMessage<'a>),
|
||||||
ParseSounds(ParseSoundsMessage),
|
ParseSounds(ParseSoundsMessage<'a>),
|
||||||
SetView(SetViewMessage),
|
SetView(SetViewMessage),
|
||||||
FixAngle(FixAngleMessage),
|
FixAngle(FixAngleMessage),
|
||||||
BspDecal(BSPDecalMessage),
|
BspDecal(BSPDecalMessage),
|
||||||
UserMessage(UserMessage),
|
UserMessage(UserMessage<'a>),
|
||||||
EntityMessage(EntityMessage),
|
EntityMessage(EntityMessage<'a>),
|
||||||
GameEvent(GameEventMessage),
|
GameEvent(GameEventMessage),
|
||||||
PacketEntities(PacketEntitiesMessage),
|
PacketEntities(PacketEntitiesMessage),
|
||||||
TempEntities(TempEntitiesMessage),
|
TempEntities(TempEntitiesMessage),
|
||||||
PreFetch(PreFetchMessage),
|
PreFetch(PreFetchMessage),
|
||||||
Menu(MenuMessage),
|
Menu(MenuMessage<'a>),
|
||||||
GameEventList(GameEventListMessage),
|
GameEventList(GameEventListMessage),
|
||||||
GetCvarValue(GetCvarValueMessage),
|
GetCvarValue(GetCvarValueMessage),
|
||||||
CmdKeyValues(CmdKeyValuesMessage),
|
CmdKeyValues(CmdKeyValuesMessage<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Message {
|
impl<'a> Parse<'a> for Message<'a> {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, 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)
|
Self::from_type(message_type, stream, state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl<'a> Message<'a> {
|
||||||
pub fn get_message_type(&self) -> MessageType {
|
pub fn get_message_type(&self) -> MessageType {
|
||||||
match self {
|
match self {
|
||||||
Message::Empty => MessageType::Empty,
|
Message::Empty => MessageType::Empty,
|
||||||
|
|
@ -143,7 +143,7 @@ impl Message {
|
||||||
|
|
||||||
pub fn from_type(
|
pub fn from_type(
|
||||||
message_type: MessageType,
|
message_type: MessageType,
|
||||||
stream: &mut Stream,
|
stream: &mut Stream<'a>,
|
||||||
state: &ParserState,
|
state: &ParserState,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
Ok(match message_type {
|
Ok(match message_type {
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ impl PacketEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_bit_var<T: BitReadSized<LittleEndian>>(stream: &mut Stream) -> ReadResult<T> {
|
fn read_bit_var<'a, T: BitReadSized<'a, LittleEndian>>(stream: &mut Stream<'a>) -> ReadResult<T> {
|
||||||
let ty: u8 = stream.read_sized(2)?;
|
let ty: u8 = stream.read_sized(2)?;
|
||||||
|
|
||||||
let bits = match ty {
|
let bits = match ty {
|
||||||
|
|
@ -116,7 +116,7 @@ pub struct PacketEntitiesMessage {
|
||||||
pub updated_base_line: bool,
|
pub updated_base_line: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_send_table(state: &ParserState, class: ClassId) -> Result<&SendTable> {
|
fn get_send_table<'a, 'b>(state: &'b ParserState<'a>, class: ClassId) -> Result<&'b SendTable> {
|
||||||
state
|
state
|
||||||
.send_tables
|
.send_tables
|
||||||
.get(usize::from(class))
|
.get(usize::from(class))
|
||||||
|
|
@ -144,7 +144,7 @@ fn get_entity_for_update(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for PacketEntitiesMessage {
|
impl Parse<'_> for PacketEntitiesMessage {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||||
let max_entries = stream.read_sized(11)?;
|
let max_entries = stream.read_sized(11)?;
|
||||||
let delta: Option<u32> = stream.read()?;
|
let delta: Option<u32> = stream.read()?;
|
||||||
|
|
@ -269,7 +269,7 @@ impl PacketEntitiesMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseBitSkip for PacketEntitiesMessage {
|
impl ParseBitSkip<'_> for PacketEntitiesMessage {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
||||||
stream.skip_bits(11)?;
|
stream.skip_bits(11)?;
|
||||||
if stream.read()? {
|
if stream.read()? {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub struct SetConVarMessage {
|
||||||
vars: Vec<(String, String)>,
|
vars: Vec<(String, String)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for SetConVarMessage {
|
impl BitRead<'_, LittleEndian> for SetConVarMessage {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let count: u8 = stream.read()?;
|
let count: u8 = stream.read()?;
|
||||||
let mut vars: Vec<(String, String)> = Vec::with_capacity(min(count, 128) as usize);
|
let mut vars: Vec<(String, String)> = Vec::with_capacity(min(count, 128) as usize);
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CreateStringTableMessage {
|
pub struct CreateStringTableMessage<'a> {
|
||||||
pub table: Box<StringTable>,
|
pub table: Box<StringTable<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -20,7 +20,7 @@ pub struct StringTableMeta {
|
||||||
pub fixed_userdata_size: Option<FixedUserDataSize>,
|
pub fixed_userdata_size: Option<FixedUserDataSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&StringTable> for StringTableMeta {
|
impl From<&StringTable<'_>> for StringTableMeta {
|
||||||
fn from(table: &StringTable) -> Self {
|
fn from(table: &StringTable) -> Self {
|
||||||
StringTableMeta {
|
StringTableMeta {
|
||||||
max_entries: table.max_entries,
|
max_entries: table.max_entries,
|
||||||
|
|
@ -29,8 +29,8 @@ impl From<&StringTable> for StringTableMeta {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for CreateStringTableMessage {
|
impl<'a> Parse<'a> for CreateStringTableMessage<'a> {
|
||||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
|
||||||
let name = stream.read()?;
|
let name = stream.read()?;
|
||||||
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);
|
||||||
|
|
@ -67,7 +67,7 @@ impl Parse for CreateStringTableMessage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer = BitReadBuffer::new(decompressed_data, LittleEndian);
|
let buffer = BitReadBuffer::new_owned(decompressed_data, LittleEndian);
|
||||||
table_data = BitReadStream::new(buffer);
|
table_data = BitReadStream::new(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,8 +92,8 @@ impl Parse for CreateStringTableMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseBitSkip for CreateStringTableMessage {
|
impl<'a> ParseBitSkip<'a> for CreateStringTableMessage<'a> {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream<'a>) -> Result<()> {
|
||||||
let _: String = stream.read()?;
|
let _: String = stream.read()?;
|
||||||
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);
|
||||||
|
|
@ -109,13 +109,13 @@ impl ParseBitSkip for CreateStringTableMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UpdateStringTableMessage {
|
pub struct UpdateStringTableMessage<'a> {
|
||||||
pub entries: Vec<(u16, StringTableEntry)>,
|
pub entries: Vec<(u16, StringTableEntry<'a>)>,
|
||||||
pub table_id: u8,
|
pub table_id: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for UpdateStringTableMessage {
|
impl<'a> Parse<'a> for UpdateStringTableMessage<'a> {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
|
||||||
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 };
|
||||||
|
|
@ -132,8 +132,8 @@ impl Parse for UpdateStringTableMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseBitSkip for UpdateStringTableMessage {
|
impl<'a> ParseBitSkip<'a> for UpdateStringTableMessage<'a> {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream<'a>) -> Result<()> {
|
||||||
let _: u8 = stream.read_sized(5)?;
|
let _: u8 = stream.read_sized(5)?;
|
||||||
|
|
||||||
let _: u16 = if stream.read()? { stream.read()? } else { 1 };
|
let _: u16 = if stream.read()? { stream.read()? } else { 1 };
|
||||||
|
|
@ -142,12 +142,12 @@ impl ParseBitSkip for UpdateStringTableMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TableEntries {
|
struct TableEntries<'a> {
|
||||||
entries: Vec<(u16, StringTableEntry)>,
|
entries: Vec<(u16, StringTableEntry<'a>)>,
|
||||||
history: Vec<u16>,
|
history: Vec<u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableEntries {
|
impl<'a> TableEntries<'a> {
|
||||||
pub fn new(count: usize) -> Self {
|
pub fn new(count: usize) -> Self {
|
||||||
TableEntries {
|
TableEntries {
|
||||||
entries: Vec::with_capacity(min(count, 128)),
|
entries: Vec::with_capacity(min(count, 128)),
|
||||||
|
|
@ -155,7 +155,7 @@ impl TableEntries {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, entry: (u16, StringTableEntry)) {
|
pub fn push(&mut self, entry: (u16, StringTableEntry<'a>)) {
|
||||||
if self.history.len() > 31 {
|
if self.history.len() > 31 {
|
||||||
self.history.remove(0);
|
self.history.remove(0);
|
||||||
}
|
}
|
||||||
|
|
@ -164,23 +164,23 @@ impl TableEntries {
|
||||||
self.history.push(entry_index as u16);
|
self.history.push(entry_index as u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_history(&self, index: usize) -> Option<&StringTableEntry> {
|
pub fn get_history(&self, index: usize) -> Option<&StringTableEntry<'a>> {
|
||||||
self.history
|
self.history
|
||||||
.get(index)
|
.get(index)
|
||||||
.and_then(|entry_index| self.entries.get(*entry_index as usize))
|
.and_then(|entry_index| self.entries.get(*entry_index as usize))
|
||||||
.map(|entry| &entry.1)
|
.map(|entry| &entry.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_entries(self) -> Vec<(u16, StringTableEntry)> {
|
pub fn into_entries(self) -> Vec<(u16, StringTableEntry<'a>)> {
|
||||||
self.entries
|
self.entries
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_table_update(
|
fn parse_string_table_update<'a>(
|
||||||
stream: &mut Stream,
|
stream: &mut Stream<'a>,
|
||||||
table_meta: &StringTableMeta,
|
table_meta: &StringTableMeta,
|
||||||
entry_count: u16,
|
entry_count: u16,
|
||||||
) -> ReadResult<Vec<(u16, StringTableEntry)>> {
|
) -> ReadResult<Vec<(u16, StringTableEntry<'a>)>> {
|
||||||
let entry_bits = log_base2(table_meta.max_entries);
|
let entry_bits = log_base2(table_meta.max_entries);
|
||||||
let mut entries = TableEntries::new(entry_count as usize);
|
let mut entries = TableEntries::new(entry_count as usize);
|
||||||
|
|
||||||
|
|
@ -202,11 +202,11 @@ fn parse_string_table_update(
|
||||||
Ok(entries.into_entries())
|
Ok(entries.into_entries())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string_table_list(
|
fn parse_string_table_list<'a>(
|
||||||
stream: &mut Stream,
|
stream: &mut Stream<'a>,
|
||||||
table_meta: &StringTableMeta,
|
table_meta: &StringTableMeta,
|
||||||
entry_count: u16,
|
entry_count: u16,
|
||||||
) -> Result<Vec<(u16, StringTableEntry)>> {
|
) -> Result<Vec<(u16, StringTableEntry<'a>)>> {
|
||||||
let mut entries = TableEntries::new(entry_count as usize);
|
let mut entries = TableEntries::new(entry_count as usize);
|
||||||
|
|
||||||
for index in 0..entry_count {
|
for index in 0..entry_count {
|
||||||
|
|
@ -223,11 +223,11 @@ fn parse_string_table_list(
|
||||||
Ok(entries.into_entries())
|
Ok(entries.into_entries())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_table_entry(
|
fn read_table_entry<'a>(
|
||||||
stream: &mut Stream,
|
stream: &mut Stream<'a>,
|
||||||
table_meta: &StringTableMeta,
|
table_meta: &StringTableMeta,
|
||||||
history: &TableEntries,
|
history: &TableEntries,
|
||||||
) -> ReadResult<StringTableEntry> {
|
) -> ReadResult<StringTableEntry<'a>> {
|
||||||
let text = if stream.read()? {
|
let text = if stream.read()? {
|
||||||
// set value
|
// set value
|
||||||
if stream.read()? {
|
if stream.read()? {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub struct TempEntitiesMessage {
|
||||||
pub entities: Vec<PacketEntity>,
|
pub entities: Vec<PacketEntity>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for TempEntitiesMessage {
|
impl Parse<'_> for TempEntitiesMessage {
|
||||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||||
let _count: u8 = stream.read()?;
|
let _count: u8 = stream.read()?;
|
||||||
let length = read_var_int(stream)?;
|
let length = read_var_int(stream)?;
|
||||||
|
|
@ -21,7 +21,7 @@ impl Parse for TempEntitiesMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseBitSkip for TempEntitiesMessage {
|
impl ParseBitSkip<'_> for TempEntitiesMessage {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
||||||
let _: u8 = stream.read()?;
|
let _: u8 = stream.read()?;
|
||||||
let length = read_var_int(stream)?;
|
let length = read_var_int(stream)?;
|
||||||
|
|
|
||||||
|
|
@ -72,18 +72,18 @@ pub enum UserMessageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum UserMessage {
|
pub enum UserMessage<'a> {
|
||||||
SayText2(Box<SayText2Message>),
|
SayText2(Box<SayText2Message>),
|
||||||
Text(Box<TextMessage>),
|
Text(Box<TextMessage>),
|
||||||
ResetHUD(ResetHudMessage),
|
ResetHUD(ResetHudMessage),
|
||||||
Train(TrainMessage),
|
Train(TrainMessage),
|
||||||
VoiceSubtitle(VoiceSubtitleMessage),
|
VoiceSubtitle(VoiceSubtitleMessage),
|
||||||
Shake(ShakeMessage),
|
Shake(ShakeMessage),
|
||||||
Unknown(UnknownUserMessage),
|
Unknown(UnknownUserMessage<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for UserMessage {
|
impl<'a> BitRead<'a, LittleEndian> for UserMessage<'a> {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
|
||||||
let message_type =
|
let message_type =
|
||||||
UserMessageType::try_from(stream.read::<u8>()?).unwrap_or(UserMessageType::Unknown);
|
UserMessageType::try_from(stream.read::<u8>()?).unwrap_or(UserMessageType::Unknown);
|
||||||
let length = stream.read_int(11)?;
|
let length = stream.read_int(11)?;
|
||||||
|
|
@ -122,7 +122,7 @@ pub enum ChatMessageKind {
|
||||||
NameChange,
|
NameChange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for ChatMessageKind {
|
impl BitRead<'_, LittleEndian> for ChatMessageKind {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let raw: String = stream.read()?;
|
let raw: String = stream.read()?;
|
||||||
Ok(match raw.as_str() {
|
Ok(match raw.as_str() {
|
||||||
|
|
@ -146,7 +146,7 @@ pub struct SayText2Message {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for SayText2Message {
|
impl BitRead<'_, LittleEndian> for SayText2Message {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let client = stream.read()?;
|
let client = stream.read()?;
|
||||||
let raw = stream.read()?;
|
let raw = stream.read()?;
|
||||||
|
|
@ -250,12 +250,12 @@ pub struct ShakeMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UnknownUserMessage {
|
pub struct UnknownUserMessage<'a> {
|
||||||
data: Stream,
|
data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for UnknownUserMessage {
|
impl<'a> BitRead<'a, LittleEndian> for UnknownUserMessage<'a> {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
|
||||||
Ok(UnknownUserMessage {
|
Ok(UnknownUserMessage {
|
||||||
data: stream.read_bits(stream.bits_left())?,
|
data: stream.read_bits(stream.bits_left())?,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ pub struct VoiceInitMessage {
|
||||||
sampling_rate: u16,
|
sampling_rate: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for VoiceInitMessage {
|
impl BitRead<'_, LittleEndian> for VoiceInitMessage {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let codec = stream.read()?;
|
let codec = stream.read()?;
|
||||||
let quality = stream.read()?;
|
let quality = stream.read()?;
|
||||||
|
|
@ -32,24 +32,24 @@ impl BitRead<LittleEndian> for VoiceInitMessage {
|
||||||
|
|
||||||
#[derive(BitRead, Debug, Clone)]
|
#[derive(BitRead, Debug, Clone)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct VoiceDataMessage {
|
pub struct VoiceDataMessage<'a> {
|
||||||
client: u8,
|
client: u8,
|
||||||
proximity: u8,
|
proximity: u8,
|
||||||
length: u16,
|
length: u16,
|
||||||
#[size = "length"]
|
#[size = "length"]
|
||||||
data: Stream,
|
data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ParseSoundsMessage {
|
pub struct ParseSoundsMessage<'a> {
|
||||||
pub reliable: bool,
|
pub reliable: bool,
|
||||||
pub num: u8,
|
pub num: u8,
|
||||||
pub length: u16,
|
pub length: u16,
|
||||||
pub data: Stream,
|
pub data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for ParseSoundsMessage {
|
impl<'a> BitRead<'a, LittleEndian> for ParseSoundsMessage<'a> {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
|
||||||
let reliable = stream.read()?;
|
let reliable = stream.read()?;
|
||||||
let num = if reliable { 1u8 } else { stream.read()? };
|
let num = if reliable { 1u8 } else { stream.read()? };
|
||||||
let length = if reliable {
|
let length = if reliable {
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,22 @@ pub mod parser;
|
||||||
pub mod sendprop;
|
pub mod sendprop;
|
||||||
pub mod vector;
|
pub mod vector;
|
||||||
|
|
||||||
pub type Buffer = BitReadBuffer<LittleEndian>;
|
pub type Buffer<'a> = BitReadBuffer<'a, LittleEndian>;
|
||||||
pub type Stream = BitReadStream<LittleEndian>;
|
pub type Stream<'a> = BitReadStream<'a, LittleEndian>;
|
||||||
|
|
||||||
pub struct Demo {
|
pub struct Demo<'a> {
|
||||||
stream: Stream,
|
stream: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Demo {
|
impl<'a> Demo<'a> {
|
||||||
pub fn new(vec: Vec<u8>) -> Self {
|
pub fn new(byes: &'a [u8]) -> Self {
|
||||||
let data = Buffer::new(vec, LittleEndian);
|
let data = Buffer::new(byes, LittleEndian);
|
||||||
let stream = Stream::new(data);
|
let stream = Stream::new(data);
|
||||||
Demo { stream }
|
Demo { stream }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a new stream with the data of the demo
|
/// Get a new stream with the data of the demo
|
||||||
pub fn get_stream(&self) -> Stream {
|
pub fn get_stream(&self) -> Stream<'a> {
|
||||||
self.stream.clone()
|
self.stream.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub struct ConsoleCmdPacket {
|
||||||
command: String,
|
command: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for ConsoleCmdPacket {
|
impl BitRead<'_, LittleEndian> for ConsoleCmdPacket {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let tick = stream.read_int(32)?;
|
let tick = stream.read_int(32)?;
|
||||||
let len = stream.read_int::<usize>(32)?;
|
let len = stream.read_int::<usize>(32)?;
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ pub struct DataTablePacket {
|
||||||
pub server_classes: Vec<ServerClass>,
|
pub server_classes: Vec<ServerClass>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for DataTablePacket {
|
impl Parse<'_> for DataTablePacket {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||||
let tick = stream.read()?;
|
let tick = stream.read()?;
|
||||||
let len = stream.read_int::<usize>(32)?;
|
let len = stream.read_int::<usize>(32)?;
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ pub struct MessagePacketMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MessagePacket {
|
pub struct MessagePacket<'a> {
|
||||||
pub tick: u32,
|
pub tick: u32,
|
||||||
pub messages: Vec<Message>,
|
pub messages: Vec<Message<'a>>,
|
||||||
pub meta: LazyBitRead<MessagePacketMeta, LittleEndian>,
|
pub meta: LazyBitRead<'a, MessagePacketMeta, LittleEndian>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
@ -26,7 +26,7 @@ pub struct ViewAngles {
|
||||||
pub local_angles: (Vector, Vector),
|
pub local_angles: (Vector, Vector),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Endianness> BitRead<E> for ViewAngles {
|
impl<E: Endianness> BitRead<'_, E> for ViewAngles {
|
||||||
fn read(stream: &mut bitbuffer::BitReadStream<E>) -> ReadResult<Self> {
|
fn read(stream: &mut bitbuffer::BitReadStream<E>) -> ReadResult<Self> {
|
||||||
let view_origin_1 = Vector::read(stream)?;
|
let view_origin_1 = Vector::read(stream)?;
|
||||||
let view_angle_1 = Vector::read(stream)?;
|
let view_angle_1 = Vector::read(stream)?;
|
||||||
|
|
@ -46,8 +46,8 @@ impl<E: Endianness> BitRead<E> for ViewAngles {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for MessagePacket {
|
impl<'a> Parse<'a> for MessagePacket<'a> {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
|
||||||
let tick = stream.read()?;
|
let tick = stream.read()?;
|
||||||
|
|
||||||
let meta = stream.read()?;
|
let meta = stream.read()?;
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,15 @@ pub mod synctick;
|
||||||
pub mod usercmd;
|
pub mod usercmd;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Packet {
|
pub enum Packet<'a> {
|
||||||
Sigon(MessagePacket),
|
Sigon(MessagePacket<'a>),
|
||||||
Message(MessagePacket),
|
Message(MessagePacket<'a>),
|
||||||
SyncTick(SyncTickPacket),
|
SyncTick(SyncTickPacket),
|
||||||
ConsoleCmd(ConsoleCmdPacket),
|
ConsoleCmd(ConsoleCmdPacket),
|
||||||
UserCmd(UserCmdPacket),
|
UserCmd(UserCmdPacket),
|
||||||
DataTables(DataTablePacket),
|
DataTables(DataTablePacket),
|
||||||
Stop(StopPacket),
|
Stop(StopPacket),
|
||||||
StringTables(StringTablePacket),
|
StringTables(StringTablePacket<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BitRead, TryFromPrimitive, Debug, Clone, Copy)]
|
#[derive(BitRead, TryFromPrimitive, Debug, Clone, Copy)]
|
||||||
|
|
@ -45,8 +45,8 @@ pub enum PacketType {
|
||||||
StringTables = 8,
|
StringTables = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for Packet {
|
impl<'a> Parse<'a> for Packet<'a> {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
|
||||||
let packet_type = PacketType::read(stream)?;
|
let packet_type = PacketType::read(stream)?;
|
||||||
Ok(match packet_type {
|
Ok(match packet_type {
|
||||||
PacketType::Sigon => Packet::Sigon(MessagePacket::parse(stream, state)?),
|
PacketType::Sigon => Packet::Sigon(MessagePacket::parse(stream, state)?),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::{ReadResult, Stream};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StopPacket;
|
pub struct StopPacket;
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for StopPacket {
|
impl BitRead<'_, LittleEndian> for StopPacket {
|
||||||
fn read(_stream: &mut Stream) -> ReadResult<Self> {
|
fn read(_stream: &mut Stream) -> ReadResult<Self> {
|
||||||
Ok(StopPacket)
|
Ok(StopPacket)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,16 @@ pub struct FixedUserDataSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StringTable {
|
pub struct StringTable<'a> {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub entries: Vec<(u16, StringTableEntry)>,
|
pub entries: Vec<(u16, StringTableEntry<'a>)>,
|
||||||
pub max_entries: u16,
|
pub max_entries: u16,
|
||||||
pub fixed_user_data_size: Option<FixedUserDataSize>,
|
pub fixed_user_data_size: Option<FixedUserDataSize>,
|
||||||
pub client_entries: Option<Vec<StringTableEntry>>,
|
pub client_entries: Option<Vec<StringTableEntry<'a>>>,
|
||||||
pub compressed: bool,
|
pub compressed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StringTable {
|
impl StringTable<'_> {
|
||||||
pub fn get_table_meta(&self) -> StringTableMeta {
|
pub fn get_table_meta(&self) -> StringTableMeta {
|
||||||
StringTableMeta {
|
StringTableMeta {
|
||||||
fixed_userdata_size: self.fixed_user_data_size,
|
fixed_userdata_size: self.fixed_user_data_size,
|
||||||
|
|
@ -33,8 +33,8 @@ impl StringTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for StringTable {
|
impl<'a> BitRead<'a, LittleEndian> for StringTable<'a> {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
|
||||||
let name = stream.read()?;
|
let name = stream.read()?;
|
||||||
let entry_count = stream.read_int(16)?;
|
let entry_count = stream.read_int(16)?;
|
||||||
let mut entries = Vec::with_capacity(min(entry_count, 128) as usize);
|
let mut entries = Vec::with_capacity(min(entry_count, 128) as usize);
|
||||||
|
|
@ -63,33 +63,33 @@ impl BitRead<LittleEndian> for StringTable {
|
||||||
|
|
||||||
#[derive(BitRead, Clone, Debug)]
|
#[derive(BitRead, Clone, Debug)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct ExtraData {
|
pub struct ExtraData<'a> {
|
||||||
pub byte_len: u16,
|
pub byte_len: u16,
|
||||||
#[size = "byte_len.saturating_mul(8)"]
|
#[size = "byte_len.saturating_mul(8)"]
|
||||||
pub data: Stream,
|
pub data: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtraData {
|
impl<'a> ExtraData<'a> {
|
||||||
pub fn new(data: Stream) -> Self {
|
pub fn new(data: Stream<'a>) -> Self {
|
||||||
let byte_len = (data.bit_len() / 8) as u16;
|
let byte_len = (data.bit_len() / 8) as u16;
|
||||||
ExtraData { byte_len, data }
|
ExtraData { byte_len, data }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct StringTableEntry {
|
pub struct StringTableEntry<'a> {
|
||||||
pub text: Option<String>,
|
pub text: Option<String>,
|
||||||
pub extra_data: Option<ExtraData>,
|
pub extra_data: Option<ExtraData<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StringTableEntry {
|
impl StringTableEntry<'_> {
|
||||||
pub fn text(&self) -> &str {
|
pub fn text(&self) -> &str {
|
||||||
self.text.as_ref().map(|s| s.as_str()).unwrap_or("")
|
self.text.as_ref().map(|s| s.as_str()).unwrap_or("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for StringTableEntry {
|
impl<'a> BitRead<'a, LittleEndian> for StringTableEntry<'a> {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream<'a>) -> ReadResult<Self> {
|
||||||
Ok(StringTableEntry {
|
Ok(StringTableEntry {
|
||||||
text: Some(stream.read()?),
|
text: Some(stream.read()?),
|
||||||
extra_data: stream.read()?,
|
extra_data: stream.read()?,
|
||||||
|
|
@ -97,7 +97,7 @@ impl BitRead<LittleEndian> for StringTableEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for StringTableEntry {
|
impl fmt::Debug for StringTableEntry<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match &self.extra_data {
|
match &self.extra_data {
|
||||||
None => write!(f, "StringTableEntry {{ text: \"{}\" }}", self.text()),
|
None => write!(f, "StringTableEntry {{ text: \"{}\" }}", self.text()),
|
||||||
|
|
@ -112,13 +112,13 @@ impl fmt::Debug for StringTableEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StringTablePacket {
|
pub struct StringTablePacket<'a> {
|
||||||
pub tick: u32,
|
pub tick: u32,
|
||||||
pub tables: Vec<StringTable>,
|
pub tables: Vec<StringTable<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for StringTablePacket {
|
impl<'a> Parse<'a> for StringTablePacket<'a> {
|
||||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
|
||||||
let tick = stream.read_int(32)?;
|
let tick = stream.read_int(32)?;
|
||||||
let length: usize = stream.read_int(32)?;
|
let length: usize = stream.read_int(32)?;
|
||||||
let mut packet_data = stream.read_bits(length.saturating_mul(8))?;
|
let mut packet_data = stream.read_bits(length.saturating_mul(8))?;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ pub struct UserCmdPacket {
|
||||||
sequence_out: u32,
|
sequence_out: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for UserCmdPacket {
|
impl BitRead<'_, LittleEndian> for UserCmdPacket {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
let tick = stream.read()?;
|
let tick = stream.read()?;
|
||||||
let sequence_out = stream.read()?;
|
let sequence_out = stream.read()?;
|
||||||
|
|
|
||||||
|
|
@ -24,26 +24,26 @@ pub trait BorrowMessageHandler: MessageHandler {
|
||||||
fn borrow_output(&self, state: &ParserState) -> &Self::Output;
|
fn borrow_output(&self, state: &ParserState) -> &Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DemoHandler<T: MessageHandler> {
|
pub struct DemoHandler<'a, T: MessageHandler> {
|
||||||
pub tick: u32,
|
pub tick: u32,
|
||||||
string_table_names: Vec<String>,
|
string_table_names: Vec<String>,
|
||||||
analyser: T,
|
analyser: T,
|
||||||
state_handler: ParserState,
|
state_handler: ParserState<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DemoHandler<Analyser> {
|
impl<'a> DemoHandler<'a, Analyser> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::with_analyser(Analyser::new())
|
Self::with_analyser(Analyser::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DemoHandler<Analyser> {
|
impl<'a> Default for DemoHandler<'a, Analyser> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
DemoHandler::new()
|
DemoHandler::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: MessageHandler> DemoHandler<T> {
|
impl<'a, T: MessageHandler> DemoHandler<'a, T> {
|
||||||
pub fn with_analyser(analyser: T) -> Self {
|
pub fn with_analyser(analyser: T) -> Self {
|
||||||
let state_handler = ParserState::new(T::does_handle, false);
|
let state_handler = ParserState::new(T::does_handle, false);
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ impl<T: MessageHandler> DemoHandler<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_packet(&mut self, packet: Packet) {
|
pub fn handle_packet(&mut self, packet: Packet<'a>) {
|
||||||
match packet {
|
match packet {
|
||||||
Packet::DataTables(packet) => {
|
Packet::DataTables(packet) => {
|
||||||
self.handle_data_table(packet.tables, packet.server_classes);
|
self.handle_data_table(packet.tables, packet.server_classes);
|
||||||
|
|
@ -94,7 +94,7 @@ impl<T: MessageHandler> DemoHandler<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_string_table(&mut self, table: StringTable) {
|
fn handle_string_table(&mut self, table: StringTable<'a>) {
|
||||||
self.state_handler
|
self.state_handler
|
||||||
.handle_string_table_meta(table.get_table_meta());
|
.handle_string_table_meta(table.get_table_meta());
|
||||||
for (entry_index, entry) in table.entries.into_iter() {
|
for (entry_index, entry) in table.entries.into_iter() {
|
||||||
|
|
@ -108,7 +108,7 @@ impl<T: MessageHandler> DemoHandler<T> {
|
||||||
self.string_table_names.push(table.name);
|
self.string_table_names.push(table.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_table_update(&mut self, table_id: u8, entries: Vec<(u16, StringTableEntry)>) {
|
fn handle_table_update(&mut self, table_id: u8, entries: Vec<(u16, StringTableEntry<'a>)>) {
|
||||||
if let Some(table_name) = self.string_table_names.get(table_id as usize) {
|
if let Some(table_name) = self.string_table_names.get(table_id as usize) {
|
||||||
for (index, entry) in entries {
|
for (index, entry) in entries {
|
||||||
let index = index as usize;
|
let index = index as usize;
|
||||||
|
|
@ -130,7 +130,7 @@ impl<T: MessageHandler> DemoHandler<T> {
|
||||||
.handle_data_table(send_tables, server_classes);
|
.handle_data_table(send_tables, server_classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_message(&mut self, message: Message) {
|
fn handle_message(&mut self, message: Message<'a>) {
|
||||||
let message_type = message.get_message_type();
|
let message_type = message.get_message_type();
|
||||||
if T::does_handle(message_type) {
|
if T::does_handle(message_type) {
|
||||||
self.analyser.handle_message(&message, self.tick);
|
self.analyser.handle_message(&message, self.tick);
|
||||||
|
|
@ -142,12 +142,12 @@ impl<T: MessageHandler> DemoHandler<T> {
|
||||||
self.analyser.into_output(&self.state_handler)
|
self.analyser.into_output(&self.state_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_parser_state(&self) -> &ParserState {
|
pub fn get_parser_state(&self) -> &ParserState<'a> {
|
||||||
&self.state_handler
|
&self.state_handler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: MessageHandler + BorrowMessageHandler> DemoHandler<T> {
|
impl<'a, T: MessageHandler + BorrowMessageHandler> DemoHandler<'a, T> {
|
||||||
pub fn borrow_output(&self) -> &T::Output {
|
pub fn borrow_output(&self) -> &T::Output {
|
||||||
self.analyser.borrow_output(&self.state_handler)
|
self.analyser.borrow_output(&self.state_handler)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,51 +21,51 @@ mod state;
|
||||||
pub use self::error::*;
|
pub use self::error::*;
|
||||||
use crate::demo::parser::handler::BorrowMessageHandler;
|
use crate::demo::parser::handler::BorrowMessageHandler;
|
||||||
|
|
||||||
pub trait Parse: Sized {
|
pub trait Parse<'a>: Sized {
|
||||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self>;
|
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BitRead<LittleEndian>> Parse for T {
|
impl<'a, T: BitRead<'a, LittleEndian>> Parse<'a> for T {
|
||||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
fn parse(stream: &mut Stream<'a>, _state: &ParserState) -> Result<Self> {
|
||||||
Self::read(stream).map_err(ParseError::from)
|
Self::read(stream).map_err(ParseError::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ParseBitSkip {
|
pub trait ParseBitSkip<'a> {
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()>;
|
fn parse_skip(stream: &mut Stream<'a>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BitRead<LittleEndian>> ParseBitSkip for T {
|
impl<'a, T: BitRead<'a, LittleEndian>> ParseBitSkip<'a> for T {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn parse_skip(stream: &mut Stream) -> Result<()> {
|
fn parse_skip(stream: &mut Stream<'a>) -> Result<()> {
|
||||||
Self::skip(stream).map_err(ParseError::from)
|
Self::skip(stream).map_err(ParseError::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DemoParser<A: MessageHandler> {
|
pub struct DemoParser<'a, A: MessageHandler> {
|
||||||
handler: DemoHandler<A>,
|
handler: DemoHandler<'a, A>,
|
||||||
stream: Stream,
|
stream: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DemoParser<Analyser> {
|
impl<'a> DemoParser<'a, Analyser> {
|
||||||
pub fn new(stream: Stream) -> DemoParser<Analyser> {
|
pub fn new(stream: Stream<'a>) -> DemoParser<Analyser> {
|
||||||
DemoParser::new_with_analyser(stream, Analyser::new())
|
DemoParser::new_with_analyser(stream, Analyser::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_all(stream: Stream) -> DemoParser<Analyser> {
|
pub fn new_all(stream: Stream<'a>) -> DemoParser<Analyser> {
|
||||||
DemoParser::new_all_with_analyser(stream, Analyser::new())
|
DemoParser::new_all_with_analyser(stream, Analyser::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: MessageHandler> DemoParser<A> {
|
impl<'a, A: MessageHandler> DemoParser<'a, A> {
|
||||||
pub fn new_with_analyser(stream: Stream, analyser: A) -> DemoParser<A> {
|
pub fn new_with_analyser(stream: Stream<'a>, analyser: A) -> DemoParser<A> {
|
||||||
DemoParser {
|
DemoParser {
|
||||||
handler: DemoHandler::with_analyser(analyser),
|
handler: DemoHandler::with_analyser(analyser),
|
||||||
stream,
|
stream,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_all_with_analyser(stream: Stream, analyser: A) -> DemoParser<A> {
|
pub fn new_all_with_analyser(stream: Stream<'a>, analyser: A) -> DemoParser<A> {
|
||||||
DemoParser {
|
DemoParser {
|
||||||
handler: DemoHandler::parse_all_with_analyser(analyser),
|
handler: DemoHandler::parse_all_with_analyser(analyser),
|
||||||
stream,
|
stream,
|
||||||
|
|
@ -82,7 +82,7 @@ impl<A: MessageHandler> DemoParser<A> {
|
||||||
|
|
||||||
/// A Ticker provides a way to step trough the demo packet by packet
|
/// A Ticker provides a way to step trough the demo packet by packet
|
||||||
/// while allowing to see the intermediate states
|
/// while allowing to see the intermediate states
|
||||||
pub fn ticker(mut self) -> Result<(Header, DemoTicker<A>)> {
|
pub fn ticker(mut self) -> Result<(Header, DemoTicker<'a, A>)> {
|
||||||
let header = Header::read(&mut self.stream)?;
|
let header = Header::read(&mut self.stream)?;
|
||||||
let ticker = DemoTicker {
|
let ticker = DemoTicker {
|
||||||
handler: self.handler,
|
handler: self.handler,
|
||||||
|
|
@ -92,20 +92,20 @@ impl<A: MessageHandler> DemoParser<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RawPacketStream {
|
pub struct RawPacketStream<'a> {
|
||||||
stream: Stream,
|
stream: Stream<'a>,
|
||||||
ended: bool,
|
ended: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawPacketStream {
|
impl<'a> RawPacketStream<'a> {
|
||||||
pub fn new(stream: Stream) -> Self {
|
pub fn new(stream: Stream<'a>) -> Self {
|
||||||
RawPacketStream {
|
RawPacketStream {
|
||||||
stream,
|
stream,
|
||||||
ended: false,
|
ended: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, state: &ParserState) -> Result<Option<Packet>> {
|
pub fn next(&mut self, state: &ParserState) -> Result<Option<Packet<'a>>> {
|
||||||
if self.ended {
|
if self.ended {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -124,12 +124,12 @@ impl RawPacketStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DemoTicker<A: MessageHandler> {
|
pub struct DemoTicker<'a, A: MessageHandler> {
|
||||||
handler: DemoHandler<A>,
|
handler: DemoHandler<'a, A>,
|
||||||
packets: RawPacketStream,
|
packets: RawPacketStream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: MessageHandler> DemoTicker<A> {
|
impl<'a, A: MessageHandler> DemoTicker<'a, A> {
|
||||||
/// Process the next packet
|
/// Process the next packet
|
||||||
///
|
///
|
||||||
/// returns whether or not there are still packets left in the demo
|
/// returns whether or not there are still packets left in the demo
|
||||||
|
|
@ -150,7 +150,7 @@ impl<A: MessageHandler> DemoTicker<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: MessageHandler + BorrowMessageHandler> DemoTicker<A> {
|
impl<A: MessageHandler + BorrowMessageHandler> DemoTicker<'_, A> {
|
||||||
pub fn state(&self) -> &A::Output {
|
pub fn state(&self) -> &A::Output {
|
||||||
self.handler.borrow_output()
|
self.handler.borrow_output()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ pub struct DemoMeta {
|
||||||
pub interval_per_tick: f32,
|
pub interval_per_tick: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParserState {
|
pub struct ParserState<'a> {
|
||||||
pub static_baselines: HashMap<ClassId, StaticBaseline, NullHasherBuilder>,
|
pub static_baselines: HashMap<ClassId, StaticBaseline<'a>, NullHasherBuilder>,
|
||||||
pub parsed_static_baselines: RefCell<HashMap<ClassId, Vec<SendProp>, NullHasherBuilder>>,
|
pub parsed_static_baselines: RefCell<HashMap<ClassId, Vec<SendProp>, NullHasherBuilder>>,
|
||||||
pub event_definitions: Vec<GameEventDefinition>,
|
pub event_definitions: Vec<GameEventDefinition>,
|
||||||
pub string_tables: Vec<StringTableMeta>,
|
pub string_tables: Vec<StringTableMeta>,
|
||||||
|
|
@ -38,13 +38,13 @@ pub struct ParserState {
|
||||||
parse_all: bool,
|
parse_all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StaticBaseline {
|
pub struct StaticBaseline<'a> {
|
||||||
pub class_id: ClassId,
|
pub class_id: ClassId,
|
||||||
pub raw: Stream,
|
pub raw: Stream<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StaticBaseline {
|
impl<'a> StaticBaseline<'a> {
|
||||||
fn new(class_id: ClassId, raw: Stream) -> Self {
|
fn new(class_id: ClassId, raw: Stream<'a>) -> Self {
|
||||||
StaticBaseline { class_id, raw }
|
StaticBaseline { class_id, raw }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ impl StaticBaseline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParserState {
|
impl<'a> ParserState<'a> {
|
||||||
pub fn new(analyser_handles: fn(message_type: MessageType) -> bool, parse_all: bool) -> Self {
|
pub fn new(analyser_handles: fn(message_type: MessageType) -> bool, parse_all: bool) -> Self {
|
||||||
ParserState {
|
ParserState {
|
||||||
static_baselines: HashMap::with_hasher(NullHasherBuilder),
|
static_baselines: HashMap::with_hasher(NullHasherBuilder),
|
||||||
|
|
@ -196,7 +196,12 @@ impl ParserState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_string_entry(&mut self, table: &str, _index: usize, entry: &StringTableEntry) {
|
pub fn handle_string_entry(
|
||||||
|
&mut self,
|
||||||
|
table: &str,
|
||||||
|
_index: usize,
|
||||||
|
entry: &StringTableEntry<'a>,
|
||||||
|
) {
|
||||||
match table {
|
match table {
|
||||||
"instancebaseline" => {
|
"instancebaseline" => {
|
||||||
if let (Some(extra), Ok(class_id)) = (&entry.extra_data, entry.text().parse()) {
|
if let (Some(extra), Ok(class_id)) = (&entry.extra_data, entry.text().parse()) {
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ impl SendPropFlags {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitRead<LittleEndian> for SendPropFlags {
|
impl BitRead<'_, LittleEndian> for SendPropFlags {
|
||||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||||
// since all 16 bits worth of flags are used there are no invalid flags
|
// since all 16 bits worth of flags are used there are no invalid flags
|
||||||
Ok(SendPropFlags(BitFlags::from_bits_truncate(stream.read()?)))
|
Ok(SendPropFlags(BitFlags::from_bits_truncate(stream.read()?)))
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ impl MessageHandler for EntityDumper {
|
||||||
#[test_case("data/small.dem", "data/small_entities.json"; "small.dem")]
|
#[test_case("data/small.dem", "data/small_entities.json"; "small.dem")]
|
||||||
fn entity_test(input_file: &str, snapshot_file: &str) {
|
fn entity_test(input_file: &str, snapshot_file: &str) {
|
||||||
let file = fs::read(input_file).expect("Unable to read file");
|
let file = fs::read(input_file).expect("Unable to read file");
|
||||||
let demo = Demo::new(file);
|
let demo = Demo::new(&file);
|
||||||
let (_, entities) = DemoParser::new_with_analyser(demo.get_stream(), EntityDumper::new())
|
let (_, entities) = DemoParser::new_with_analyser(demo.get_stream(), EntityDumper::new())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl MessageHandler for SendPropAnalyser {
|
||||||
#[test_case("data/gully.dem", "data/gully_props.json"; "gully.dem")]
|
#[test_case("data/gully.dem", "data/gully_props.json"; "gully.dem")]
|
||||||
fn flatten_test(input_file: &str, snapshot_file: &str) {
|
fn flatten_test(input_file: &str, snapshot_file: &str) {
|
||||||
let file = fs::read(input_file).expect("Unable to read file");
|
let file = fs::read(input_file).expect("Unable to read file");
|
||||||
let demo = Demo::new(file);
|
let demo = Demo::new(&file);
|
||||||
let (_, send_tables) =
|
let (_, send_tables) =
|
||||||
DemoParser::new_with_analyser(demo.get_stream(), SendPropAnalyser::new())
|
DemoParser::new_with_analyser(demo.get_stream(), SendPropAnalyser::new())
|
||||||
.parse()
|
.parse()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use tf_demo_parser::{Demo, DemoParser, MatchState};
|
||||||
#[test_case("data/decal.dem", "data/decal.json"; "decal.dem")]
|
#[test_case("data/decal.dem", "data/decal.json"; "decal.dem")]
|
||||||
fn snapshot_test(input_file: &str, snapshot_file: &str) {
|
fn snapshot_test(input_file: &str, snapshot_file: &str) {
|
||||||
let file = fs::read(input_file).expect("Unable to read file");
|
let file = fs::read(input_file).expect("Unable to read file");
|
||||||
let demo = Demo::new(file);
|
let demo = Demo::new(&file);
|
||||||
let (_, state) = DemoParser::new(demo.get_stream()).parse().unwrap();
|
let (_, state) = DemoParser::new(demo.get_stream()).parse().unwrap();
|
||||||
|
|
||||||
let expected: MatchState = serde_json::from_slice(
|
let expected: MatchState = serde_json::from_slice(
|
||||||
|
|
@ -29,7 +29,7 @@ fn snapshot_test(input_file: &str, snapshot_file: &str) {
|
||||||
#[test_case("data/gully.dem", "data/gully_game_state.json"; "gully.dem")]
|
#[test_case("data/gully.dem", "data/gully_game_state.json"; "gully.dem")]
|
||||||
fn game_state_test(input_file: &str, snapshot_file: &str) {
|
fn game_state_test(input_file: &str, snapshot_file: &str) {
|
||||||
let file = fs::read(input_file).expect("Unable to read file");
|
let file = fs::read(input_file).expect("Unable to read file");
|
||||||
let demo = Demo::new(file);
|
let demo = Demo::new(&file);
|
||||||
let (_, state) = DemoParser::new_with_analyser(demo.get_stream(), GameStateAnalyser::new())
|
let (_, state) = DemoParser::new_with_analyser(demo.get_stream(), GameStateAnalyser::new())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue