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

message work

This commit is contained in:
Robin Appelman 2019-03-02 16:42:04 +01:00
commit 8d053296ca
12 changed files with 534 additions and 10 deletions

View file

@ -1,3 +1,5 @@
#[allow(unused_variables)]
use std::error::Error; use std::error::Error;
use std::fs; use std::fs;

File diff suppressed because it is too large Load diff

View file

@ -130,6 +130,7 @@ impl FromGameEventValue for () {
} }
} }
#[derive(Debug)]
pub struct RawGameEvent { pub struct RawGameEvent {
pub event_type: GameEventType, pub event_type: GameEventType,
pub values: Vec<GameEventValue>, pub values: Vec<GameEventValue>,

View file

@ -2,7 +2,7 @@ use bitstream_reader::{BitRead, BitReadSized, LittleEndian};
use crate::{ReadResult, Stream}; use crate::{ReadResult, Stream};
#[derive(BitReadSized)] #[derive(BitReadSized, Debug)]
pub struct ClassInfoEntry { pub struct ClassInfoEntry {
#[size = "input_size"] #[size = "input_size"]
class_id: u16, class_id: u16,
@ -10,6 +10,7 @@ pub struct ClassInfoEntry {
table_name: String, table_name: String,
} }
#[derive(Debug)]
pub struct ClassInfoMessage { pub struct ClassInfoMessage {
count: u16, count: u16,
create: bool, create: bool,

View file

@ -20,6 +20,7 @@ fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<
}) })
} }
#[derive(Debug)]
pub struct GameEventMessage { pub struct GameEventMessage {
pub event: GameEvent pub event: GameEvent
} }
@ -50,6 +51,7 @@ impl Parse for GameEventMessage {
} }
} }
#[derive(Debug)]
pub struct GameEventListMessage { pub struct GameEventListMessage {
event_list: HashMap<GameEventType, GameEventDefinition>, event_list: HashMap<GameEventType, GameEventDefinition>,
} }

View file

@ -1,6 +1,7 @@
/// Messages that consists only of primitives and string and can be derived /// Messages that consists only of primitives and string and can be derived
use bitstream_reader::BitRead; use bitstream_reader::{BitRead, BitStream, LittleEndian};
use std::collections::HashMap; use std::collections::HashMap;
use crate::Stream;
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct FileMessage { pub struct FileMessage {
@ -72,6 +73,19 @@ pub struct FixAngleMessage {
pub z: u16, pub z: u16,
} }
#[derive(BitRead, Debug)]
#[endianness = "LittleEndian"]
pub struct EntityMessage {
#[size = 11]
pub index: u16,
#[size = 9]
pub class_id: u16,
#[size = 11]
pub length: u16,
#[size = "length * 8"]
pub data: Stream,
}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct PreFetchMessage { pub struct PreFetchMessage {
#[size = 14] #[size = 14]
@ -79,11 +93,28 @@ pub struct PreFetchMessage {
} }
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct GetCvarMessage { #[endianness = "LittleEndian"]
pub struct MenuMessage {
pub kind: u16,
pub length: u16,
#[size = "length * 8"]
pub index: Stream,
}
#[derive(BitRead, Debug)]
pub struct GetCvarValueMessage {
pub cookie: u32, pub cookie: u32,
pub value: String, pub value: String,
} }
#[derive(BitRead, Debug)]
#[endianness = "LittleEndian"]
pub struct CmdKeyValuesMessage {
pub length: u32,
#[size = "length * 8"]
pub data: Stream,
}
#[derive(BitRead, Debug)] #[derive(BitRead, Debug)]
pub struct SetConVarMessage { pub struct SetConVarMessage {
#[size_bits = 8] #[size_bits = 8]

View file

@ -3,7 +3,17 @@ use num_traits::FromPrimitive;
pub use generated::*; pub use generated::*;
use crate::{Parse, ParseError, ParserState, Result, Stream}; use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
use crate::demo::message::bspdecal::*;
use crate::demo::message::classinfo::*;
use crate::demo::message::gameevent::*;
use crate::demo::message::generated::*;
use crate::demo::message::packetentities::*;
use crate::demo::message::stringtable::*;
use crate::demo::message::tempentities::*;
use crate::demo::message::usermessage::*;
use crate::demo::message::voice::*;
use bitstream_reader::{BitRead, LittleEndian};
pub mod classinfo; pub mod classinfo;
pub mod generated; pub mod generated;
@ -12,6 +22,8 @@ pub mod voice;
pub mod bspdecal; pub mod bspdecal;
pub mod usermessage; pub mod usermessage;
pub mod gameevent; pub mod gameevent;
pub mod packetentities;
pub mod tempentities;
#[derive(Primitive, Debug)] #[derive(Primitive, Debug)]
pub enum MessageType { pub enum MessageType {
@ -51,3 +63,69 @@ impl Parse for MessageType {
prop_type.ok_or(ParseError::InvalidMessageType(raw)) prop_type.ok_or(ParseError::InvalidMessageType(raw))
} }
} }
#[derive(Debug)]
pub enum Message {
File(FileMessage),
NetTick(NetTickMessage),
StringCmd(StringCmdMessage),
SetConVar(SetConVarMessage),
SigOnState(SigOnStateMessage),
Print(PrintMessage),
ServerInfo(ServerInfoMessage),
ClassInfo(ClassInfoMessage),
SetPause(SetPauseMessage),
CreateStringTable(CreateStringTableMessage),
UpdateStringTable(UpdateStringTableMessage),
VoiceInit(VoiceInitMessage),
VoiceData(VoiceDataMessage),
ParseSounds(ParseSoundsMessage),
SetView(SetViewMessage),
FixAngle(FixAngleMessage),
BspDecal(BSPDecalMessage),
UserMessage(UserMessage),
EntityMessage(EntityMessage),
GameEvent(GameEventMessage),
PacketEntities(PacketEntitiesMessage),
TempEntities(TempEntitiesMessage),
PreFetch(PreFetchMessage),
Menu(MenuMessage),
GameEventList(GameEventListMessage),
GetCvarValue(GetCvarValueMessage),
CmdKeyValues(CmdKeyValuesMessage),
}
impl Parse for Message {
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
let message_type = MessageType::parse(stream, state)?;
Ok(match message_type {
MessageType::File => Message::File(FileMessage::parse(stream, state)?),
MessageType::NetTick => Message::NetTick(NetTickMessage::parse(stream, state)?),
MessageType::StringCmd => Message::StringCmd(StringCmdMessage::parse(stream, state)?),
MessageType::SetConVar => Message::SetConVar(SetConVarMessage::parse(stream, state)?),
MessageType::SigOnState => Message::SigOnState(SigOnStateMessage::parse(stream, state)?),
MessageType::Print => Message::Print(PrintMessage::parse(stream, state)?),
MessageType::ServerInfo => Message::ServerInfo(ServerInfoMessage::parse(stream, state)?),
MessageType::ClassInfo => Message::ClassInfo(ClassInfoMessage::parse(stream, state)?),
MessageType::SetPause => Message::SetPause(SetPauseMessage::parse(stream, state)?),
MessageType::CreateStringTable => Message::CreateStringTable(CreateStringTableMessage::parse(stream, state)?),
MessageType::UpdateStringTable => Message::UpdateStringTable(UpdateStringTableMessage::parse(stream, state)?),
MessageType::VoiceInit => Message::VoiceInit(VoiceInitMessage::parse(stream, state)?),
MessageType::VoiceData => Message::VoiceData(VoiceDataMessage::parse(stream, state)?),
MessageType::ParseSounds => Message::ParseSounds(ParseSoundsMessage::parse(stream, state)?),
MessageType::SetView => Message::SetView(SetViewMessage::parse(stream, state)?),
MessageType::FixAngle => Message::FixAngle(FixAngleMessage::parse(stream, state)?),
MessageType::BspDecal => Message::BspDecal(BSPDecalMessage::parse(stream, state)?),
MessageType::UserMessage => Message::UserMessage(UserMessage::parse(stream, state)?),
MessageType::EntityMessage => Message::EntityMessage(EntityMessage::parse(stream, state)?),
MessageType::GameEvent => Message::GameEvent(GameEventMessage::parse(stream, state)?),
MessageType::PacketEntities => Message::PacketEntities(PacketEntitiesMessage::parse(stream, state)?),
MessageType::TempEntities => Message::TempEntities(TempEntitiesMessage::parse(stream, state)?),
MessageType::PreFetch => Message::PreFetch(PreFetchMessage::parse(stream, state)?),
MessageType::Menu => Message::Menu(MenuMessage::parse(stream, state)?),
MessageType::GameEventList => Message::GameEventList(GameEventListMessage::parse(stream, state)?),
MessageType::GetCvarValue => Message::GetCvarValue(GetCvarValueMessage::parse(stream, state)?),
MessageType::CmdKeyValues => Message::CmdKeyValues(CmdKeyValuesMessage::parse(stream, state)?),
})
}
}

View file

@ -0,0 +1,61 @@
use bitstream_reader::{BitRead, BitReadSized, LittleEndian};
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
use crate::demo::packet::datatable::ServerClass;
use crate::demo::sendprop::SendProp;
#[derive(Debug)]
pub struct EntityId(u32);
#[derive(BitRead, Clone, Copy, Debug)]
#[discriminant_bits = 3]
pub enum PVS {
PRESERVE = 0,
ENTER = 1,
LEAVE = 2,
DELETE = 4,
}
#[derive(Debug)]
pub struct PacketEntity {
server_class: ServerClass,
entity_index: EntityId,
props: Vec<SendProp>,
in_pvs: bool,
pvs: PVS,
serial_number: u32,
delay: Option<u32>,
}
#[derive(Debug)]
pub struct PacketEntitiesMessage {
entities: Vec<PacketEntity>,
removed_entities: Vec<EntityId>,
max_entries: u16,
delta: Option<u32>,
base_line: u8,
updated_base_line: bool,
}
impl Parse for PacketEntitiesMessage {
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
let max_entries = stream.read_sized(11)?;
let delta = stream.read()?;
let base_line = stream.read_sized(1)?;
let updated_entries: u16 = stream.read_sized(11)?;
let length: u32 = stream.read_sized(20)?;
let updated_base_line = stream.read()?;
let data = stream.read_bits(length as usize)?;
// TODO
Ok(PacketEntitiesMessage {
entities: Vec::new(),
removed_entities: Vec::new(),
max_entries,
delta,
base_line,
updated_base_line,
})
}
}

View file

@ -6,10 +6,12 @@ use bitstream_reader::{BitRead, BitReadSized, BitStream, LittleEndian};
use crate::{Parse, ParseError, ParserState, ReadResult, Stream, Result}; use crate::{Parse, ParseError, ParserState, ReadResult, Stream, Result};
use crate::demo::packet::stringtable::{ExtraData, FixedUserdataSize, StringTable, StringTableEntry}; use crate::demo::packet::stringtable::{ExtraData, FixedUserdataSize, StringTable, StringTableEntry};
#[derive(Debug)]
pub struct CreateStringTableMessage { pub struct CreateStringTableMessage {
pub table: StringTable, pub table: StringTable,
} }
#[derive(Debug)]
pub struct StringTableMeta { pub struct StringTableMeta {
pub max_entries: u16, pub max_entries: u16,
pub fixed_userdata_size: Option<FixedUserdataSize>, pub fixed_userdata_size: Option<FixedUserdataSize>,
@ -71,6 +73,7 @@ impl BitRead<LittleEndian> for CreateStringTableMessage {
} }
} }
#[derive(Debug)]
pub struct UpdateStringTableMessage { pub struct UpdateStringTableMessage {
pub entries: HashMap<u16, StringTableEntry>, pub entries: HashMap<u16, StringTableEntry>,
pub table_id: u8, pub table_id: u8,
@ -177,7 +180,7 @@ fn parse_string_table_entries(
Ok(entries) Ok(entries)
} }
fn read_var_int(stream: &mut Stream) -> ReadResult<u32> { pub fn read_var_int(stream: &mut Stream) -> ReadResult<u32> {
let mut result: u32 = 0; let mut result: u32 = 0;
for i in (0..35u32).step_by(7) { for i in (0..35u32).step_by(7) {
let byte: u8 = stream.read()?; let byte: u8 = stream.read()?;

View file

@ -0,0 +1,23 @@
use bitstream_reader::{BitRead, BitReadSized, LittleEndian};
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
use super::packetentities::PacketEntity;
use super::stringtable::read_var_int;
#[derive(Debug)]
pub struct TempEntitiesMessage {
pub entities: Vec<PacketEntity>
}
impl Parse for TempEntitiesMessage {
fn parse(stream: &mut Stream, state: &ParserState) -> Result<Self> {
let count: u8 = stream.read()?;
let length = read_var_int(stream)?;
let data = stream.read_bits(length as usize)?;
Ok(TempEntitiesMessage {
entities: Vec::new()
})
}
}

View file

@ -68,6 +68,7 @@ pub enum UserMessageType {
Unknown = 255, Unknown = 255,
} }
#[derive(Debug)]
pub enum UserMessage { pub enum UserMessage {
SayText2(SayText2Message), SayText2(SayText2Message),
Text(TextMessage), Text(TextMessage),

View file

@ -1,8 +1,6 @@
use crate::demo::vector::Vector;
use crate::{Parse, ParseError, ParserState, Result, Stream}; use crate::{Parse, ParseError, ParserState, Result, Stream};
use crate::demo::message::Message;
#[derive(Debug)] use crate::demo::vector::Vector;
pub struct Message;
#[derive(Debug)] #[derive(Debug)]
pub struct MessagePacket { pub struct MessagePacket {
@ -33,7 +31,13 @@ impl Parse for MessagePacket {
let length: usize = stream.read_int(32)?; let length: usize = stream.read_int(32)?;
let mut packet_data = stream.read_bits(length * 8)?; let mut packet_data = stream.read_bits(length * 8)?;
let messages = vec![]; let mut messages = Vec::new();
dbg!(&packet_data);
while packet_data.bits_left() > 6 {
let message = Message::parse(stream, state)?;
dbg!(&message);
messages.push(message);
}
let packet = MessagePacket { let packet = MessagePacket {
tick, tick,