mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-04 02:24:12 +02:00
update to new bitreader
This commit is contained in:
parent
f5e236c58b
commit
e7b9f5ecbb
25 changed files with 378 additions and 590 deletions
|
|
@ -1,4 +1,6 @@
|
|||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConsoleCmdPacket {
|
||||
|
|
@ -6,21 +8,12 @@ pub struct ConsoleCmdPacket {
|
|||
command: String,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for ConsoleCmdPacket {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read(32)?;
|
||||
let len = stream.read::<usize>(32)?;
|
||||
impl BitRead<LittleEndian> for ConsoleCmdPacket {
|
||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let len = stream.read_int::<usize>(32)?;
|
||||
let mut packet_data = stream.read_bits(len * 8)?;
|
||||
let command = packet_data.read_string(None)?;
|
||||
Ok(ConsoleCmdPacket {
|
||||
tick,
|
||||
command,
|
||||
})
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
let _ = stream.skip(32)?;
|
||||
let len = stream.read::<usize>(32)?;
|
||||
stream.skip(len * 8).map_err(ParseError::from)
|
||||
Ok(ConsoleCmdPacket { tick, command })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
|
||||
use crate::demo::sendprop::{SendPropDefinition, SendPropFlag, SendPropType};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -23,32 +25,39 @@ pub struct DataTablePacket {
|
|||
server_classes: Vec<ServerClass>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for DataTablePacket {
|
||||
fn parse(stream: &mut Stream<'a>, state: &ParserState<'a>) -> Result<Self> {
|
||||
let tick = stream.read(32)?;
|
||||
impl Parse for DataTablePacket {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read()?;
|
||||
let start = stream.pos();
|
||||
let len = stream.read::<usize>(32)?;
|
||||
let len = stream.read_int::<usize>(32)?;
|
||||
let mut packet_data = stream.read_bits(len * 8)?;
|
||||
|
||||
let mut tables = vec![];
|
||||
while packet_data.read_bool()? {
|
||||
let needs_decoder = packet_data.read_bool()?;
|
||||
let name = packet_data.read_string(None)?;
|
||||
let prop_count = packet_data.read(10)?;
|
||||
let prop_count = packet_data.read_int(10)?;
|
||||
|
||||
let mut array_element_prop = None;
|
||||
let mut props = Vec::with_capacity(prop_count);
|
||||
|
||||
for i in 0..prop_count {
|
||||
let prop: SendPropDefinition = SendPropDefinition::parse(&mut packet_data, state, name.clone())?;
|
||||
let prop: SendPropDefinition =
|
||||
SendPropDefinition::read(&mut packet_data, name.clone())?;
|
||||
if prop.flags.contains(SendPropFlag::InsideArray) {
|
||||
if array_element_prop.is_some() || prop.flags.contains(SendPropFlag::ChangesOften) {
|
||||
return Err(ParseError::InvalidSendPropArray("Array contents can't have the 'ChangesOften' flag".to_owned()));
|
||||
if array_element_prop.is_some()
|
||||
|| prop.flags.contains(SendPropFlag::ChangesOften)
|
||||
{
|
||||
return Err(ParseError::InvalidSendPropArray(
|
||||
"Array contents can't have the 'ChangesOften' flag".to_owned(),
|
||||
));
|
||||
}
|
||||
array_element_prop = Some(prop);
|
||||
} else if let Some(array_element) = array_element_prop {
|
||||
if prop.prop_type != SendPropType::Array {
|
||||
return Err(ParseError::InvalidSendPropArray("Array contents can without array".to_owned()));
|
||||
return Err(ParseError::InvalidSendPropArray(
|
||||
"Array contents can without array".to_owned(),
|
||||
));
|
||||
}
|
||||
array_element_prop = None;
|
||||
props.push(prop.with_array_property(array_element));
|
||||
|
|
@ -68,10 +77,10 @@ impl<'a> Parse<'a> for DataTablePacket {
|
|||
|
||||
// TODO linked tables?
|
||||
|
||||
let server_class_count = packet_data.read(16)?;
|
||||
let server_class_count = packet_data.read_int(16)?;
|
||||
let mut server_classes = Vec::with_capacity(server_class_count);
|
||||
for i in 0..server_class_count {
|
||||
let id = packet_data.read(16)?;
|
||||
let id = packet_data.read_int(16)?;
|
||||
let name = packet_data.read_string(None)?;
|
||||
let data_table = packet_data.read_string(None)?;
|
||||
server_classes.push(ServerClass {
|
||||
|
|
@ -91,10 +100,4 @@ impl<'a> Parse<'a> for DataTablePacket {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
let _ = stream.skip(32)?;
|
||||
let len = stream.read::<usize>(32)?;
|
||||
stream.skip(len * 8).map_err(ParseError::from)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use crate::demo::vector::Vector;
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Message;
|
||||
|
|
@ -16,10 +16,10 @@ pub struct MessagePacket {
|
|||
flags: u32, // TODO
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for MessagePacket {
|
||||
fn parse(stream: &mut Stream<'a>, state: &ParserState<'a>) -> Result<Self> {
|
||||
let tick = stream.read(32)?;
|
||||
let flags = stream.read(32)?;
|
||||
impl Parse for MessagePacket {
|
||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let flags = stream.read_int(32)?;
|
||||
|
||||
let view_origin_1 = Vector::parse(stream, state)?;
|
||||
let view_angle_1 = Vector::parse(stream, state)?;
|
||||
|
|
@ -28,9 +28,9 @@ impl<'a> Parse<'a> for MessagePacket {
|
|||
let view_angles = (Vector::parse(stream, state)?, view_angle_1);
|
||||
let local_view_angles = (Vector::parse(stream, state)?, local_view_angle_1);
|
||||
|
||||
let sequence_in = stream.read(32)?;
|
||||
let sequence_out = stream.read(32)?;
|
||||
let length: usize = stream.read(32)?;
|
||||
let sequence_in = stream.read_int(32)?;
|
||||
let sequence_out = stream.read_int(32)?;
|
||||
let length: usize = stream.read_int(32)?;
|
||||
let mut packet_data = stream.read_bits(length * 8)?;
|
||||
|
||||
let messages = vec![];
|
||||
|
|
@ -56,7 +56,7 @@ impl<'a> Parse<'a> for MessagePacket {
|
|||
}
|
||||
|
||||
let _ = stream.skip(32 * 2)?;
|
||||
let length: usize = stream.read::<usize>(32)?;
|
||||
let length: usize = stream.read_int::<usize>(32)?;
|
||||
stream.skip(length * 8).map_err(ParseError::from)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
use enum_primitive_derive::Primitive;
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
|
|
@ -12,15 +13,15 @@ use self::synctick::SyncTickPacket;
|
|||
use self::usercmd::UserCmdPacket;
|
||||
|
||||
pub mod consolecmd;
|
||||
pub mod datatable;
|
||||
pub mod message;
|
||||
pub mod stop;
|
||||
pub mod stringtable;
|
||||
pub mod synctick;
|
||||
pub mod usercmd;
|
||||
pub mod datatable;
|
||||
pub mod message;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Packet<'a> {
|
||||
pub enum Packet {
|
||||
Sigon(MessagePacket),
|
||||
Message(MessagePacket),
|
||||
SyncTick(SyncTickPacket),
|
||||
|
|
@ -28,10 +29,11 @@ pub enum Packet<'a> {
|
|||
UserCmd(UserCmdPacket),
|
||||
DataTables(DataTablePacket),
|
||||
Stop(StopPacket),
|
||||
StringTables(StringTablePacket<'a>),
|
||||
StringTables(StringTablePacket),
|
||||
}
|
||||
|
||||
#[derive(Primitive, Debug)]
|
||||
#[derive(BitRead, Primitive, Debug)]
|
||||
#[discriminant_bits = 8]
|
||||
pub enum PacketType {
|
||||
Sigon = 1,
|
||||
Message = 2,
|
||||
|
|
@ -43,21 +45,9 @@ pub enum PacketType {
|
|||
StringTables = 8,
|
||||
}
|
||||
|
||||
impl Parse<'_> for PacketType {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
let raw = stream.read(8)?;
|
||||
let prop_type: Option<PacketType> = PacketType::from_u8(raw);
|
||||
prop_type.ok_or(ParseError::InvalidPacketType(raw))
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
stream.skip(8).map_err(ParseError::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for Packet<'a> {
|
||||
fn parse(stream: &mut Stream<'a>, state: &ParserState<'a>) -> Result<Self> {
|
||||
let packet_type = PacketType::parse(stream, state)?;
|
||||
impl Parse for Packet {
|
||||
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
|
||||
let packet_type = PacketType::read(stream)?;
|
||||
Ok(match packet_type {
|
||||
PacketType::Sigon => Packet::Sigon(MessagePacket::parse(stream, state)?),
|
||||
PacketType::Message => Packet::Message(MessagePacket::parse(stream, state)?),
|
||||
|
|
@ -66,22 +56,9 @@ impl<'a> Parse<'a> for Packet<'a> {
|
|||
PacketType::UserCmd => Packet::UserCmd(UserCmdPacket::parse(stream, state)?),
|
||||
PacketType::DataTables => Packet::DataTables(DataTablePacket::parse(stream, state)?),
|
||||
PacketType::Stop => Packet::Stop(StopPacket::parse(stream, state)?),
|
||||
PacketType::StringTables => Packet::StringTables(StringTablePacket::parse(stream, state)?),
|
||||
PacketType::StringTables => {
|
||||
Packet::StringTables(StringTablePacket::parse(stream, state)?)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
let packet_type = PacketType::parse(stream, &ParserState::new(&stream))?;
|
||||
dbg!(&packet_type);
|
||||
match packet_type {
|
||||
PacketType::Sigon => MessagePacket::skip(stream),
|
||||
PacketType::Message => MessagePacket::skip(stream),
|
||||
PacketType::SyncTick => SyncTickPacket::skip(stream),
|
||||
PacketType::ConsoleCmd => ConsoleCmdPacket::skip(stream),
|
||||
PacketType::UserCmd => UserCmdPacket::skip(stream),
|
||||
PacketType::DataTables => DataTablePacket::skip(stream),
|
||||
PacketType::Stop => StopPacket::skip(stream),
|
||||
PacketType::StringTables => StringTablePacket::skip(stream),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
use crate::{Parse, ParserState, Result, Stream};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{Parse, ParserState, Result, Stream, ReadResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StopPacket;
|
||||
|
||||
impl<'a> Parse<'a> for StopPacket {
|
||||
fn parse(_stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
impl BitRead<LittleEndian> for StopPacket {
|
||||
fn read(_stream: &mut Stream) -> ReadResult<Self> {
|
||||
Ok(StopPacket)
|
||||
}
|
||||
|
||||
fn skip(_stream: &mut Stream) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,33 @@
|
|||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StringTable<'a> {
|
||||
pub struct StringTable {
|
||||
name: String,
|
||||
entries: Vec<StringTableEntry<'a>>,
|
||||
entries: Vec<StringTableEntry>,
|
||||
max_entries: u32,
|
||||
fixed_userdata_size: Option<u32>,
|
||||
fixed_userdata_size_bits: Option<u32>,
|
||||
client_entries: Option<Vec<StringTableEntry<'a>>>,
|
||||
client_entries: Option<Vec<StringTableEntry>>,
|
||||
compressed: bool,
|
||||
}
|
||||
|
||||
impl<'a> StringTable<'a> {
|
||||
fn parse(stream: &mut Stream<'a>) -> Result<Self> {
|
||||
impl BitRead<LittleEndian> for StringTable {
|
||||
fn read(stream: &mut Stream) -> ReadResult <Self> {
|
||||
let name = stream.read_string(None)?;
|
||||
let entry_count: u32 = stream.read(16)?;
|
||||
let entry_count: u32 = stream.read_int(16)?;
|
||||
let mut entries = Vec::with_capacity(entry_count as usize);
|
||||
for _ in 0..entry_count {
|
||||
entries.push(StringTableEntry::parse(stream)?);
|
||||
entries.push(StringTableEntry::read(stream)?);
|
||||
}
|
||||
|
||||
let client_entries = if stream.read_bool()? {
|
||||
let count = stream.read(16)?;
|
||||
let count = stream.read_int(16)?;
|
||||
let mut vec = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
vec.push(StringTableEntry::parse(stream)?);
|
||||
vec.push(StringTableEntry::read(stream)?);
|
||||
}
|
||||
Some(vec)
|
||||
} else {
|
||||
|
|
@ -44,16 +46,16 @@ impl<'a> StringTable<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct StringTableEntry<'a> {
|
||||
pub struct StringTableEntry {
|
||||
text: String,
|
||||
extra_data: Option<Stream<'a>>,
|
||||
extra_data: Option<Stream>,
|
||||
}
|
||||
|
||||
impl<'a> StringTableEntry<'a> {
|
||||
fn parse(stream: &mut Stream<'a>) -> Result<Self> {
|
||||
impl BitRead<LittleEndian> for StringTableEntry {
|
||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||
let text = stream.read_string(None)?;
|
||||
let extra_data = if stream.read_bool()? {
|
||||
let byte_len: usize = stream.read(16)?;
|
||||
let byte_len: usize = stream.read_int(16)?;
|
||||
Some(stream.read_bits(byte_len * 8)?)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -62,31 +64,36 @@ impl<'a> StringTableEntry<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for StringTableEntry<'a> {
|
||||
impl fmt::Debug for StringTableEntry {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match &self.extra_data {
|
||||
None => write!(f, "Table Entry: '{}'", self.text),
|
||||
Some(extra_data) => write!(f, "Table Entry: '{}' with {} bits of extra data", self.text, extra_data.bit_len())
|
||||
Some(extra_data) => write!(
|
||||
f,
|
||||
"Table Entry: '{}' with {} bits of extra data",
|
||||
self.text,
|
||||
extra_data.bit_len()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StringTablePacket<'a> {
|
||||
pub struct StringTablePacket {
|
||||
tick: u32,
|
||||
tables: Vec<StringTable<'a>>,
|
||||
tables: Vec<StringTable>,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for StringTablePacket<'a> {
|
||||
fn parse(stream: &mut Stream<'a>, _state: &ParserState<'a>) -> Result<Self> {
|
||||
let tick = stream.read(32)?;
|
||||
impl Parse for StringTablePacket {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let start = stream.pos();
|
||||
let length: usize = stream.read(32)?;
|
||||
let length: usize = stream.read_int(32)?;
|
||||
let mut packet_data = stream.read_bits(length * 8)?;
|
||||
let count: u32 = packet_data.read(8)?;
|
||||
let count: u32 = packet_data.read_int(8)?;
|
||||
let mut tables = Vec::with_capacity(count as usize);
|
||||
for _ in 0..count {
|
||||
tables.push(StringTable::parse(&mut packet_data)?);
|
||||
tables.push(StringTable::read(&mut packet_data)?);
|
||||
}
|
||||
if packet_data.bits_left() > 7 {
|
||||
Err(ParseError::DataRemaining(packet_data.bits_left()))
|
||||
|
|
@ -94,10 +101,4 @@ impl<'a> Parse<'a> for StringTablePacket<'a> {
|
|||
Ok(StringTablePacket { tick, tables })
|
||||
}
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
let _ = stream.skip(32)?;
|
||||
let length = stream.read::<usize>(32)?;
|
||||
stream.skip(length).map_err(ParseError::from)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,8 @@
|
|||
use bitstream_reader::{BitRead};
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(BitRead, Debug)]
|
||||
pub struct SyncTickPacket {
|
||||
tick: u32,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for SyncTickPacket {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
Ok(SyncTickPacket {
|
||||
tick: stream.read(32)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
stream.skip(32).map_err(ParseError::from)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
use crate::{Parse, ParseError, ParserState, Result, Stream};
|
||||
use bitstream_reader::{BitRead, LittleEndian};
|
||||
|
||||
use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UserCmdPacket {
|
||||
|
|
@ -6,22 +8,13 @@ pub struct UserCmdPacket {
|
|||
sequence_out: u32,
|
||||
}
|
||||
|
||||
impl<'a> Parse<'a> for UserCmdPacket {
|
||||
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
|
||||
let tick = stream.read(32)?;
|
||||
let sequence_out = stream.read(32)?;
|
||||
let len = stream.read::<usize>(32)?;
|
||||
impl BitRead<LittleEndian> for UserCmdPacket {
|
||||
fn read(stream: &mut Stream) -> ReadResult<Self> {
|
||||
let tick = stream.read_int(32)?;
|
||||
let sequence_out = stream.read_int(32)?;
|
||||
let len = stream.read_int::<usize>(32)?;
|
||||
let mut _packet_data = stream.read_bits(len * 8)?;
|
||||
// TODO parse the packet data
|
||||
Ok(UserCmdPacket {
|
||||
tick,
|
||||
sequence_out
|
||||
})
|
||||
}
|
||||
|
||||
fn skip(stream: &mut Stream) -> Result<()> {
|
||||
let _ = stream.skip(64)?;
|
||||
let len = stream.read::<usize>(32)?;
|
||||
stream.skip(len * 8).map_err(ParseError::from)
|
||||
Ok(UserCmdPacket { tick, sequence_out })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue