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

keep baselineprops seperate and add some tracing

This commit is contained in:
Robin Appelman 2021-07-29 19:16:24 +02:00
commit 24e83957d5
8 changed files with 213 additions and 40 deletions

146
Cargo.lock generated
View file

@ -115,6 +115,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits 0.2.14",
"winapi",
]
[[package]]
name = "clicolors-control"
version = "1.0.1"
@ -297,12 +309,30 @@ version = "0.2.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "main_error"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb63bb1e282e0b6aba0addb1f0e87cb5181ea68142b2dfd21ba108f8e8088a64"
[[package]]
name = "matchers"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
dependencies = [
"regex-automata",
]
[[package]]
name = "memchr"
version = "2.4.0"
@ -487,6 +517,12 @@ dependencies = [
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
[[package]]
name = "pretty_assertions"
version = "0.7.2"
@ -562,6 +598,15 @@ dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
@ -663,6 +708,21 @@ dependencies = [
"syn",
]
[[package]]
name = "sharded-slab"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3"
dependencies = [
"lazy_static",
]
[[package]]
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "snap"
version = "1.0.5"
@ -787,6 +847,8 @@ dependencies = [
"snap",
"steamid-ng",
"test-case",
"tracing",
"tracing-subscriber",
]
[[package]]
@ -809,6 +871,15 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "toml"
version = "0.5.8"
@ -818,6 +889,81 @@ dependencies = [
"serde",
]
[[package]]
name = "tracing"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tracing-core"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052"
dependencies = [
"lazy_static",
]
[[package]]
name = "tracing-log"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
dependencies = [
"lazy_static",
"log",
"tracing-core",
]
[[package]]
name = "tracing-serde"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
dependencies = [
"serde",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48"
dependencies = [
"ansi_term",
"chrono",
"lazy_static",
"matchers",
"regex",
"serde",
"serde_json",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
"tracing-serde",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"

View file

@ -43,6 +43,8 @@ no-panic = { version = "0.1", optional = true }
fnv = "1"
steamid-ng = "1"
schemars = { version = "0.8", optional = true }
tracing = "0.1"
tracing-subscriber = "0.2"
[features]
schema = ["schemars", "bitbuffer/schemars"]

View file

@ -12,6 +12,8 @@ fn main() -> Result<(), MainError> {
#[cfg(feature = "better_panic")]
better_panic::install();
tracing_subscriber::fmt::init();
let args: Vec<_> = env::args().collect();
if args.len() < 2 {
println!("1 argument required");

View file

@ -56,6 +56,7 @@ pub enum PVS {
pub struct PacketEntity {
pub server_class: ClassId,
pub entity_index: EntityId,
pub baseline_props: Vec<SendProp>,
pub props: Vec<SendProp>,
pub in_pvs: bool,
pub pvs: PVS,
@ -75,11 +76,11 @@ impl fmt::Display for PacketEntity {
impl PacketEntity {
pub fn mut_prop_by_identifier(&mut self, index: &SendPropIdentifier) -> Option<&mut SendProp> {
self.props.iter_mut().find(|prop| prop.identifier == *index)
self.props_mut().find(|prop| prop.identifier == *index)
}
pub fn get_prop_by_identifier(&self, index: &SendPropIdentifier) -> Option<&SendProp> {
self.props.iter().find(|prop| prop.identifier == *index)
self.props().find(|prop| prop.identifier == *index)
}
pub fn apply_update(&mut self, props: Vec<SendProp>) {
@ -96,22 +97,18 @@ impl PacketEntity {
self.get_prop_by_identifier(&identifier)
}
pub fn diff_from_baseline<'a>(
&'a self,
baseline: &'a [SendProp],
) -> impl Iterator<Item = &'a SendProp> + 'a {
// self.props.iter().filter(move |prop| {
// !baseline
// .iter()
// .any(|base_prop| base_prop.index == prop.index && base_prop.value == prop.value)
// })
self.props.iter().filter(move |prop| {
baseline
.iter()
.find(|base_prop| base_prop.identifier == prop.identifier)
.map(|base_prop| base_prop.value != prop.value)
.unwrap_or(true)
})
pub fn props(&self) -> impl Iterator<Item = &SendProp> {
self.baseline_props.iter().chain(self.props.iter())
}
pub fn props_mut(&mut self) -> impl Iterator<Item = &mut SendProp> {
self.baseline_props.iter_mut().chain(self.props.iter_mut())
}
pub fn into_props(self) -> impl Iterator<Item = SendProp> {
self.baseline_props
.into_iter()
.chain(self.props.into_iter())
}
}
@ -208,6 +205,7 @@ fn get_entity_for_update(
Ok(PacketEntity {
server_class: class_id,
entity_index,
baseline_props: vec![],
props: Vec::with_capacity(8),
in_pvs: false,
pvs,
@ -259,6 +257,7 @@ impl Parse<'_> for PacketEntitiesMessage {
entities.push(PacketEntity {
server_class: 0.into(),
entity_index,
baseline_props: vec![],
props: vec![],
in_pvs: false,
pvs,
@ -313,17 +312,7 @@ impl Encode for PacketEntitiesMessage {
match entity.pvs {
PVS::Enter => {
Self::write_enter(entity, stream, state)?;
let baseline = state.get_baseline(
self.base_line as usize,
entity.entity_index,
entity.server_class,
send_table,
)?;
Self::write_update(
entity.props.iter().skip(baseline.len()),
stream,
send_table,
)?;
Self::write_update(&entity.props, stream, send_table)?;
}
PVS::Preserve => {
Self::write_update(&entity.props, stream, send_table)?;
@ -363,12 +352,14 @@ impl PacketEntitiesMessage {
.get(usize::from(class_index))
.ok_or(ParseError::UnknownServerClass(class_index))?;
let props = state.get_baseline(baseline_index, entity_index, class_index, send_table)?;
let baseline_props =
state.get_baseline(baseline_index, entity_index, class_index, send_table)?;
Ok(PacketEntity {
server_class: class_index,
entity_index,
props,
baseline_props,
props: vec![],
in_pvs: true,
pvs: PVS::Enter,
serial_number: serial,
@ -431,10 +422,17 @@ impl PacketEntitiesMessage {
true.write(stream)?;
let index = prop.index as usize;
let definition = send_table
.flattened_props
.get(index)
.ok_or(ParseError::UnknownDefinition(prop.identifier))?;
if index >= send_table.flattened_props.len() {
dbg!(&send_table.name);
}
let definition =
send_table
.flattened_props
.get(index)
.ok_or(ParseError::PropIndexOutOfBounds {
index: index as i32,
prop_count: send_table.flattened_props.len(),
})?;
write_bit_var((index as i32 - last_index - 1) as u32, stream)?;
last_index = index as i32;
prop.value.encode(stream, &definition.parse_definition)?;
@ -530,6 +528,7 @@ fn test_packet_entitier_message_roundtrip() {
entities: vec![PacketEntity {
server_class: ClassId::from(0),
entity_index: Default::default(),
baseline_props: vec![],
props: vec![],
in_pvs: true,
pvs: PVS::Enter,
@ -550,6 +549,7 @@ fn test_packet_entitier_message_roundtrip() {
PacketEntity {
server_class: ClassId::from(0),
entity_index: EntityId::from(0),
baseline_props: vec![],
props: vec![],
in_pvs: true,
pvs: PVS::Enter,
@ -559,6 +559,7 @@ fn test_packet_entitier_message_roundtrip() {
PacketEntity {
server_class: ClassId::from(1),
entity_index: EntityId::from(4),
baseline_props: vec![],
props: vec![
SendProp {
index: 0,
@ -579,6 +580,7 @@ fn test_packet_entitier_message_roundtrip() {
PacketEntity {
server_class: ClassId::from(1),
entity_index: EntityId::from(5),
baseline_props: vec![],
props: vec![
SendProp {
index: 0,

View file

@ -5,6 +5,7 @@ use crate::demo::message::{Message, MessageType};
use crate::demo::parser::Encode;
use crate::demo::vector::Vector;
use crate::{Parse, ParserState, ReadResult, Result, Stream};
use tracing::{event, span, Level};
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Debug, BitRead, BitWrite, PartialEq, Serialize, Deserialize, Clone)]
@ -118,15 +119,20 @@ impl<'a> Parse<'a> for MessagePacket<'a> {
let meta = stream.read()?;
let length: u32 = stream.read()?;
event!(Level::DEBUG, length, "reading packet data");
let mut packet_data = stream.read_bits(length as usize * 8)?;
let mut messages = Vec::with_capacity(8);
while packet_data.bits_left() > 6 {
let message_type = MessageType::read(&mut packet_data)?;
let _span =
span!(Level::INFO, "reading packet", message_type = ?message_type).entered();
if state.should_parse_message(message_type) && message_type != MessageType::Empty {
event!(Level::INFO, "parsing message");
messages.push(Message::from_type(message_type, &mut packet_data, state)?);
} else {
event!(Level::INFO, "skipping message");
Message::skip_type(message_type, &mut packet_data, state)?;
}
}

View file

@ -11,6 +11,7 @@ use self::synctick::SyncTickPacket;
use self::usercmd::UserCmdPacket;
use crate::demo::parser::Encode;
use serde::{Deserialize, Serialize};
use tracing::{event, span, Level};
pub mod consolecmd;
pub mod datatable;
@ -48,6 +49,19 @@ impl Packet<'_> {
Packet::StringTables(msg) => msg.tick,
}
}
pub fn set_tick(&mut self, tick: u32) {
match self {
Packet::Sigon(msg) => msg.tick = tick,
Packet::Message(msg) => msg.tick = tick,
Packet::SyncTick(msg) => msg.tick = tick,
Packet::ConsoleCmd(msg) => msg.tick = tick,
Packet::UserCmd(msg) => msg.tick = tick,
Packet::DataTables(msg) => msg.tick = tick,
Packet::Stop(msg) => msg.tick = tick,
Packet::StringTables(msg) => msg.tick = tick,
}
}
}
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
@ -83,6 +97,8 @@ impl Packet<'_> {
impl<'a> Parse<'a> for Packet<'a> {
fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> {
let packet_type = PacketType::read(stream)?;
let _span = span!(Level::INFO, "reading packet", packet_type = ?packet_type).entered();
event!(Level::INFO, "parsing packet");
Ok(match packet_type {
PacketType::Sigon => Packet::Sigon(MessagePacket::parse(stream, state)?),
PacketType::Message => Packet::Message(MessagePacket::parse(stream, state)?),

View file

@ -214,7 +214,7 @@ impl GameStateAnalyser {
}
pub fn handle_player_resource(&mut self, entity: &PacketEntity) {
for prop in &entity.props {
for prop in entity.props() {
if let Some((table_name, prop_name)) = self.prop_names.get(&prop.identifier) {
if let Ok(player_id) = u32::from_str(prop_name.as_str()) {
let entity_id = EntityId::from(player_id);
@ -248,7 +248,7 @@ impl GameStateAnalyser {
pub fn handle_player_entity(&mut self, entity: &PacketEntity) {
let player = self.state.get_or_create_player(entity.entity_index);
for prop in &entity.props {
for prop in entity.props() {
if let Some((table_name, prop_name)) = self.prop_names.get(&prop.identifier) {
match table_name.as_str() {
"DT_BasePlayer" => match prop_name.as_str() {

View file

@ -57,15 +57,14 @@ impl EntityDump {
tick,
server_class: classes[usize::from(entity.server_class)].name.clone(),
id: entity.entity_index,
pvs: entity.pvs.into(),
props: entity
.props
.into_iter()
.into_props()
.map(|prop| {
let (table_name, prop_name) = &prop_names[&prop.identifier];
(format!("{}.{}", table_name, prop_name), prop.value)
})
.collect(),
pvs: entity.pvs.into(),
}
}
}