From fa5b04f70b2ccf653210f019796e557c2d4acd5a Mon Sep 17 00:00:00 2001 From: Andrei Benea Date: Mon, 1 Jan 2024 05:52:05 +0200 Subject: [PATCH] SendTable parsing wip. --- Cargo.lock | 72 ++++++++++++++++++++ cs2-demo/proto/netmessages.proto | 31 +++++++++ cs2-demo/src/demo_command.rs | 9 ++- cs2-demo/src/lib.rs | 3 + cs2-demo/src/send_tables.rs | 35 ++++++++++ cs2-demo/src/testdata/cdemosendtables.binpb | Bin 0 -> 97282 bytes csdemoparser/Cargo.toml | 4 +- csdemoparser/src/cs2.rs | 1 + 8 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 cs2-demo/src/send_tables.rs create mode 100644 cs2-demo/src/testdata/cdemosendtables.binpb diff --git a/Cargo.lock b/Cargo.lock index 5cb27c9..5fa6abe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "1.1.2" @@ -64,6 +79,9 @@ name = "anyhow" version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca87830a3e3fb156dc96cfbd31cb620265dd053be734723f22b760d6cc3c3051" +dependencies = [ + "backtrace", +] [[package]] name = "assert-json-diff" @@ -81,6 +99,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -111,6 +144,15 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -302,6 +344,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "glob" version = "0.3.1" @@ -407,6 +455,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -423,6 +480,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -635,6 +701,12 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" version = "0.38.28" diff --git a/cs2-demo/proto/netmessages.proto b/cs2-demo/proto/netmessages.proto index c129c05..6e76158 100644 --- a/cs2-demo/proto/netmessages.proto +++ b/cs2-demo/proto/netmessages.proto @@ -51,3 +51,34 @@ message CSVCMsg_ServerInfo { optional .CSVCMsg_GameSessionConfiguration game_session_config = 19; optional bytes game_session_manifest = 20; } + +message ProtoFlattenedSerializerField_t { + message polymorphic_field_t { + optional int32 polymorphic_field_serializer_name_sym = 1; + optional int32 polymorphic_field_serializer_version = 2; + } + + optional int32 var_type_sym = 1; + optional int32 var_name_sym = 2; + optional int32 bit_count = 3; + optional float low_value = 4; + optional float high_value = 5; + optional int32 encode_flags = 6; + optional int32 field_serializer_name_sym = 7; + optional int32 field_serializer_version = 8; + optional int32 send_node_sym = 9; + optional int32 var_encoder_sym = 10; + repeated .ProtoFlattenedSerializerField_t.polymorphic_field_t polymorphic_types = 11; +} + +message ProtoFlattenedSerializer_t { + optional int32 serializer_name_sym = 1; + optional int32 serializer_version = 2; + repeated int32 fields_index = 3; +} + +message CSVCMsg_FlattenedSerializer { + repeated .ProtoFlattenedSerializer_t serializers = 1; + repeated string symbols = 2; + repeated .ProtoFlattenedSerializerField_t fields = 3; +} diff --git a/cs2-demo/src/demo_command.rs b/cs2-demo/src/demo_command.rs index fcead26..8fdd033 100644 --- a/cs2-demo/src/demo_command.rs +++ b/cs2-demo/src/demo_command.rs @@ -1,5 +1,6 @@ use super::packet::Packet; use super::proto::demo::{CDemoFileHeader, CDemoPacket, CDemoSendTables}; +use super::send_tables::SendTables; use super::{Error, Result}; use crate::proto::demo::{CDemoFullPacket, CDemoStringTables}; use crate::string_table::{parse_string_tables, StringTable}; @@ -16,7 +17,7 @@ pub enum DemoCommand { FileInfo, /// A sync tick. It contains no data. SyncTick, - SendTables(CDemoSendTables), + SendTables(SendTables), ClassInfo, StringTables(Vec), Packet(Packet), @@ -37,7 +38,9 @@ impl DemoCommand { 1 => DemoCommand::FileHeader(CDemoFileHeader::parse_from_bytes(data)?), 2 => DemoCommand::FileInfo, 3 => DemoCommand::SyncTick, - 4 => DemoCommand::SendTables(CDemoSendTables::parse_from_bytes(data)?), + 4 => DemoCommand::SendTables(SendTables::try_new(CDemoSendTables::parse_from_bytes( + data, + )?)?), 5 => DemoCommand::ClassInfo, 6 => DemoCommand::StringTables(parse_string_tables( CDemoStringTables::parse_from_bytes(data)?, @@ -68,7 +71,7 @@ impl fmt::Display for DemoCommand { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { DemoCommand::FileHeader(m) => write!(f, "FileHeader {}", m), - DemoCommand::SendTables(m) => write!(f, "SendTables {} bytes", m.data().len()), + DemoCommand::SendTables(_) => write!(f, "SendTables"), _ => write!(f, "{:?}", self), } } diff --git a/cs2-demo/src/lib.rs b/cs2-demo/src/lib.rs index 88dd5f8..161a3fd 100644 --- a/cs2-demo/src/lib.rs +++ b/cs2-demo/src/lib.rs @@ -2,6 +2,7 @@ mod demo_command; mod message; mod packet; pub mod proto; +mod send_tables; mod string_table; use crate::proto::demo::EDemoCommands; @@ -32,6 +33,8 @@ pub enum Error { MissingPacket, #[error("cannot parse string table player index")] InvalidPlayerIndex, + #[error("cannot parse sendtables")] + InvalidSendTables, } pub type Result = std::result::Result; diff --git a/cs2-demo/src/send_tables.rs b/cs2-demo/src/send_tables.rs new file mode 100644 index 0000000..6ac9393 --- /dev/null +++ b/cs2-demo/src/send_tables.rs @@ -0,0 +1,35 @@ +use crate::proto::demo::CDemoSendTables; +use crate::proto::netmessages::CSVCMsg_FlattenedSerializer; +use crate::{Error, Result}; +use protobuf::CodedInputStream; + +#[derive(Debug)] +pub struct SendTables { + _flattened_serializer: CSVCMsg_FlattenedSerializer, +} + +impl SendTables { + pub(crate) fn try_new(msg: CDemoSendTables) -> Result { + let mut data = msg.data(); + let _flattened_serializer: CSVCMsg_FlattenedSerializer = CodedInputStream::new(&mut data) + .read_message() + .or(Err(Error::InvalidSendTables))?; + Ok(Self { + _flattened_serializer, + }) + } +} + +#[cfg(test)] +mod tests { + use protobuf::Message; + + use super::*; + + #[test] + fn test() { + let binpb = include_bytes!("testdata/cdemosendtables.binpb"); + let dst = CDemoSendTables::parse_from_bytes(binpb).unwrap(); + SendTables::try_new(dst).unwrap(); + } +} diff --git a/cs2-demo/src/testdata/cdemosendtables.binpb b/cs2-demo/src/testdata/cdemosendtables.binpb new file mode 100644 index 0000000000000000000000000000000000000000..302f346b9e36634479632a37dcc26b4309760041 GIT binary patch literal 97282 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 anyhow::Result { } } DemoCommand::StringTables(st) => state.handle_string_tables(st)?, + // DemoCommand::SendTables(send) => state.handle_send_tables(send)?, _ => {} } }