Expand description
§source2-demo
source2-demo is a Rust library for parsing Source 2 engine demo files.
§Supported Games
- Dota 2
- Deadlock
- Counter-Strike 2
§Installation
Add the following to your Cargo.toml and enable the feature for the game you want to parse:
[dependencies]
# For Dota 2
source2-demo = { version = "0.5", features = ["dota"] }
# For Deadlock
# source2-demo = { version = "0.5", features = ["deadlock"] }
# For Counter-Strike 2
# source2-demo = { version = "0.5", features = ["cs2"] }§Quick Start: Parsing Chat Messages
Here’s a simple program that prints chat messages from a Dota 2 replay. It handles the CDotaUserMsgChatMessage protobuf message and prints the player’s name and their message.
More examples can be found in the d2-examples and dl-examples directories.
use source2_demo::prelude::*;
use source2_demo::proto::*;
// Create a struct that implements the Default trait
#[derive(Default)]
struct Chat;
// Mark the impl block with the observer attribute
#[observer]
#[uses_all]
impl Chat {
// Use the on_message attribute to mark the protobuf message handler
#[on_message]
fn handle_chat_msg(
&mut self,
ctx: &Context,
chat_msg: CDotaUserMsgChatMessage, // Use any protobuf message as an argument
) -> ObserverResult {
if let Ok(pr) = ctx.entities().get_by_class_name("CDOTA_PlayerResource") {
let name: String = property!(
pr,
"m_vecPlayerData.{:04}.m_iszPlayerName",
chat_msg.source_player_id()
);
println!("{}: {}", name, chat_msg.message_text());
}
Ok(())
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a parser
let mut parser = Parser::from_reader(std::fs::File::open("replay.dem")?)?;
// Register observers
parser.register_observer::<Chat>();
// Run the parser
parser.run_to_end()?;
Ok(())
}§Quick Start: Rewriting Protobuf Messages
Use source2_demo::writer when you want to write a modified demo. The writer
parses the input replay, applies registered rewriters, and writes a new replay
stream to the output.
This example removes Dota 2 chat messages by rewriting a protobuf packet message:
use source2_demo::prelude::*;
use source2_demo::proto::CDotaUserMsgChatMessage;
use source2_demo::writer::*;
use std::fs::File;
#[derive(Default)]
struct RemoveChat;
#[rewriter]
impl RemoveChat {
#[rewrite_packet_message]
fn remove_chat(
&mut self,
_message: CDotaUserMsgChatMessage,
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Drop)
}
}
fn main() -> anyhow::Result<()> {
let input = File::open("input.dem")?;
let output = File::create("output.dem")?;
let mut writer = DemoWriter::from_reader(input, output)?;
writer.register_rewriter::<RemoveChat>();
writer.run()?;
Ok(())
}§Quick Start: Rewriting Fields and String Tables
This Deadlock example anonymizes a replay by rewriting entity fields, a packet message,
and userinfo entries in string tables. The full example is in dl-examples/anonymize-replay.
use source2_demo::prelude::*;
use source2_demo::proto::{
CCitadelUserMsgPostMatchDetails, CMsgMatchMetaDataContents, CMsgPlayerInfo,
};
use source2_demo::writer::*;
#[derive(Default)]
struct ReplayAnonymizer;
#[rewriter]
impl ReplayAnonymizer {
#[rewrite_field(class = "CCitadelPlayerController", field = "m_steamID")]
fn remove_steam_id(&mut self, _value: u64) -> u64 {
0
}
#[rewrite_packet_message]
fn remove_post_match_details(
&mut self,
message: &mut CCitadelUserMsgPostMatchDetails,
) -> Result<MessageRewrite, ParserError> {
if let Some(match_details) = message.match_details.as_mut() {
let mut metadata = CMsgMatchMetaDataContents::decode(match_details.as_slice())?;
if let Some(match_info) = metadata.match_info.as_mut() {
match_info.match_id = Some(0);
for player in &mut match_info.players {
player.account_id = Some(0);
}
}
*match_details = metadata.encode_to_vec();
}
Ok(MessageRewrite::Rewrite)
}
#[rewrite_string_table_entry]
fn remove_userinfo(
&mut self,
table_name: &str,
entry: &mut StringTableEntryUpdate,
) -> Result<(), ParserError> {
if table_name == "userinfo" {
if let Some(value) = entry.value_mut() {
let mut player = CMsgPlayerInfo::decode(value.as_slice())?;
player.name = Some("Anonymous".to_string());
player.xuid = Some(0);
player.steamid = Some(0);
*value = player.encode_to_vec();
}
}
Ok(())
}
}§Building Examples
To build the examples, clone the repository and use Cargo:
git clone https://github.com/Rupas1k/source2-demo
cd source2-demo
# Build examples for a specific game
cd dl-examples # d2-examples
cargo build --release§Run a Specific Example
cargo run --release -p example input.dem
cargo run --release -p example input.dem output.dem§Features
The crate supports the following cargo features:
dota- Enable Dota 2 replay parsing (includes Dota 2 protobufs)deadlock- Enable Deadlock replay parsing (includes Citadel protobufs)cs2- Enable Counter-Strike 2 replay parsing (includes CS2 protobufs)unsafe- Disable bounds checking in the reader for improved performance.mimalloc(default) - Use mimalloc as the global allocator for improved performance
You can enable multiple game features if needed:
source2-demo = { version = "*", features = ["dota", "cs2"] }You can disable mimalloc if it causes issues on your platform (e.g., WebAssembly):
source2-demo = { version = "*", default-features = false }§Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
§Credits
This project was inspired by and builds upon the work of other Source 2 demo parsers:
§License
This project is dual-licensed under either:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
§Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Re-exports§
pub use prost;
Modules§
- c_
bidir_ msg_ prediction_ event - c_
demo_ class_ info - c_
demo_ recovery - c_
demo_ string_ tables - c_
game_ info - c_
msg_ add_ item_ to_ socket_ response - c_
msg_ add_ socket_ response - c_
msg_ apply_ remote_ con_ vars - c_
msg_ c_ vars - c_
msg_ client_ to_ gc_ aggregate_ metrics - c_
msg_ client_ to_ gc_ integrity_ status - c_
msg_ client_ welcome - c_
msg_ extract_ gems_ response - c_
msg_ gc_ to_ gcso_ cache_ subscribe - c_
msg_ gc_ update_ sub_ gc_ session_ info - c_
msg_ inference_ iterate_ beam_ search - c_
msg_ reset_ strange_ gem_ count_ response - c_
msg_ sdo_ assert - c_
msg_ serialized_ so_ cache - c_
msg_ server_ network_ stats - c_
msg_ set_ item_ positions - c_
msg_ so_ cache_ subscribed - c_
msg_ so_ multiple_ objects - c_
msg_ source1_ legacy_ game_ event - c_
msg_ source1_ legacy_ game_ event_ list - c_
msg_ source2_ perf_ interval_ sample - c_
msg_ source2_ play_ stats_ packed_ record_ list - c_
msg_ steam_ learn_ access_ tokens - c_
msg_ steam_ learn_ inference_ backend_ response - c_
msg_ steam_ learn_ inference_ metadata_ response - c_
msg_ steam_ learn_ server_ info - c_
source2_ metrics_ fetch_ map_ data_ response - c_
source2_ metrics_ match_ perf_ summary_ notification - c_
user_ message_ camera_ transition - c_
user_ message_ diagnostic_ response - c_
user_ message_ dll_ status - c_
user_ message_ inventory_ response - c_
user_ message_ notify_ response_ found - c_
user_ message_ request_ diagnostic - c_
user_ message_ util_ msg_ response - c_
user_ msg_ particle_ manager - c_
workshop_ populate_ item_ descriptions_ request - c_
workshop_ set_ item_ payment_ rules_ request - cgc_
to_ gc_ msg_ master_ ack - cgc_
to_ gc_ msg_ master_ startup_ complete - csvc_
msg_ class_ info - csvc_
msg_ game_ event - csvc_
msg_ game_ event_ list - csvc_
msg_ list_ game_ events - csvc_
msg_ packet_ entities - csvc_
msg_ send_ table - csvc_
msg_ sounds - proto_
flattened_ serializer_ field_ t
Structs§
- CBidir
MsgPrediction Event - CBidir
MsgRebroadcast Game Event - CBidir
MsgRebroadcast Source - CBroadcast
Post Game Data Frame Request - CCommunity
Clan Announcement Info - CCommunity
GetClan Announcements Request - CCommunity
GetClan Announcements Response - CDemo
Animation Data - CDemo
Animation Header - CDemo
Class Info - CDemo
Console Cmd - CDemo
Custom Data - CDemo
Custom Data Callbacks - CDemo
File Header - CDemo
File Info - CDemo
Full Packet - CDemo
Packet - CDemo
Recovery - CDemo
Save Game - CDemo
Send Tables - CDemo
Spawn Groups - CDemo
Spawn Groups Hltv Broadcast - CDemo
Stop - CDemo
String Tables - CDemo
Sync Tick - CDemo
User Cmd - CEntity
Message DoSpark - CEntity
Message FixAngle - CEntity
Message Play Jingle - CEntity
Message Propagate Force - CEntity
Message Remove AllDecals - CEntity
Message Screen Overlay - CEntity
Msg - CExtra
MsgBlock - CGame
Info - CGcMsg
Compressed MsgTo Client - CGcMsg
GetIp Location Response - CGcStore
Purchase Init Line Item - CGcSystem
MsgGet Account Details - CGcSystem
MsgGet Account Details Response - CGcTo
GcMsg Master Ack - CGcTo
GcMsg Master AckResponse - CGcTo
GcMsg Master Startup Complete - CGcTo
GcMsg Routed - CGcTo
GcMsg Routed Reply - CIpLocation
Info - CMsg
AddItem ToSocket - CMsg
AddItem ToSocket Data - CMsg
AddItem ToSocket Response - CMsg
AddSocket - CMsg
AddSocket Response - CMsg
Apply EggEssence - CMsg
Apply Pennant Upgrade - CMsg
Apply Remote ConVars - CMsg
Apply Strange Part - CMsgC
Vars - CMsg
Clear Decals ForEntity Event - CMsg
Clear Entity Decals Event - CMsg
Clear World Decals Event - CMsg
Client Hello - CMsg
Client Ping Data - CMsg
Client ToGc Aggregate Metrics - CMsg
Client ToGc Integrity Status - CMsg
Client Welcome - CMsg
Cloth Effect Anim Event - CMsg
Cloth Stiffen Anim Event - CMsg
Connection Status - CMsg
Custom Game Install Status - CMsg
Extract Gems - CMsg
Extract Gems Response - CMsg
GcAdditional Welcome MsgList - CMsg
GcAssert JobData - CMsg
GcClient Ping - CMsg
GcClient Version Updated - CMsg
GcCon Command - CMsg
GcMultiplex Message - CMsg
GcRequest SubGc Session Info - CMsg
GcRequest SubGc Session Info Response - CMsg
GcServer Version Updated - CMsg
GcStore Purchase Cancel - CMsg
GcStore Purchase Cancel Response - CMsg
GcStore Purchase Finalize - CMsg
GcStore Purchase Finalize Response - CMsg
GcStore Purchase Init - CMsg
GcStore Purchase Init Response - CMsg
GcTo Client Aggregate Metrics Backoff - CMsg
GcTo Client Apply Remote ConVars - CMsg
GcTo Client Poll Convar Request - CMsg
GcTo Client Poll Convar Response - CMsg
GcTo Client Poll File Request - CMsg
GcTo Client Poll File Response - CMsg
GcTo Client Request Dropped - CMsg
GcTo GcBanned Word List Updated - CMsg
GcTo GcDirty SdoCache - CMsg
GcTo GcForward Account Details - CMsg
GcTo GcLoad Session SoCache - CMsg
GcTo GcLoad Session SoCache Response - CMsg
GcTo GcMaster Broadcast Message - CMsg
GcTo GcMaster Destroy Cache - CMsg
GcTo GcMaster Subscribe ToCache - CMsg
GcTo GcMaster Subscribe ToCache Async - CMsg
GcTo GcMaster Subscribe ToCache Response - CMsg
GcTo GcMaster Unsubscribe From Cache - CMsg
GcTo GcPerform Manual Op - CMsg
GcTo GcPerform Manual OpCompleted - CMsg
GcTo GcReload Server Region Settings - CMsg
GcTo GcSub GcStarting - CMsg
GcTo GcUniverse Startup - CMsg
GcTo GcUniverse Startup Response - CMsg
GcTo GcUpdate Session Stats - CMsg
GcTo GcUpdate SqlKey Value - CMsg
GcTo GcWeb ApiAccount Changed - CMsg
GcTo Gcso Cache Subscribe - CMsg
GcTo Gcso Cache Unsubscribe - CMsg
GcTo Server Apply Remote ConVars - CMsg
GcTo Server Steam Learn Access Tokens Changed - CMsg
GcTo Server Steam Learn UseHttp - CMsg
GcUpdate SubGc Session Info - CMsg
Inference Iterate Beam Search - CMsg
Invitation Created - CMsg
Invite ToLobby - CMsg
Invite ToParty - CMsg
IpcAddress - CMsg
Item Acknowledged - CMsg
Kick From Party - CMsg
LanServer Available - CMsg
Leave Party - CMsg
Lobby Invite Response - CMsg
Party Invite Response - CMsg
Place Decal Event - CMsg
Player Info - CMsg
Proto BufHeader - CMsgQ
Angle - CMsg
Quaternion - CMsg
Reset Strange GemCount - CMsg
Reset Strange GemCount Response - CMsg
Rgba - CMsg
SdoAssert - CMsg
SdoNo Memcached - CMsg
Serialized SoCache - CMsg
Server Available - CMsg
Server Network Stats - CMsg
Server Peer - CMsg
Server User Cmd - CMsg
SetItem Positions - CMsg
SoCache Have Version - CMsg
SoCache Subscribed - CMsg
SoCache Subscribed UpTo Date - CMsg
SoCache Subscription Check - CMsg
SoCache Subscription Refresh - CMsg
SoCache Unsubscribed - CMsg
SoCache Version - CMsg
SoMultiple Objects - CMsg
SoSingle Object - CMsg
Soid Owner - CMsg
Sort Items - CMsg
SosSet Library Stack Fields - CMsg
SosSet Sound Event Params - CMsg
SosStart Sound Event - CMsg
SosStop Sound Event - CMsg
SosStop Sound Event Hash - CMsg
Source1 Legacy Game Event - CMsg
Source1 Legacy Game Event List - CMsg
Source1 Legacy Listen Events - CMsg
Source2 Network Flow Quality - CMsg
Source2 Perf Interval Sample - CMsg
Source2 Play Stats Packed Record List - CMsg
Source2 System Specs - CMsg
Source2V Prof Lite Report - CMsg
Source2V Prof Lite Report Item - CMsg
Steam Learn Access Tokens - CMsg
Steam Learn Batch Operation Request - CMsg
Steam Learn Batch Operation Response - CMsg
Steam Learn Cache Data Request - CMsg
Steam Learn Cache Data Response - CMsg
Steam Learn Data - CMsg
Steam Learn Data Element - CMsg
Steam Learn Data List - CMsg
Steam Learn Data Object - CMsg
Steam Learn Data Source - CMsg
Steam Learn Data Source Desc Element - CMsg
Steam Learn Data Source Desc Object - CMsg
Steam Learn GetAccess Tokens Request - CMsg
Steam Learn GetAccess Tokens Response - CMsg
Steam Learn Inference Backend Response - CMsg
Steam Learn Inference Metadata Backend Request - CMsg
Steam Learn Inference Metadata Request - CMsg
Steam Learn Inference Metadata Response - CMsg
Steam Learn Inference Request - CMsg
Steam Learn Inference Response - CMsg
Steam Learn Register Data Source Request - CMsg
Steam Learn Register Data Source Response - CMsg
Steam Learn Server Info - CMsg
Steam Learn Snapshot Project Request - CMsg
Steam Learn Snapshot Project Response - CMsg
Transform - CMsgV
Debug Game Session IdEvent - CMsg
Vector - CMsg
Vector2D - CMsg
Voice Audio - CNet
MsgDebug Overlay - CNet
MsgNop - CNet
MsgSet ConVar - CNet
MsgSignon State - CNet
MsgSpawn Group Load - CNet
MsgSpawn Group Load Completed - CNet
MsgSpawn Group Manifest Update - CNet
MsgSpawn Group SetCreation Tick - CNet
MsgSpawn Group Unload - CNet
MsgSplit Screen User - CNet
MsgString Cmd - CNet
MsgTick - CSoEcon
Game Account Client - CSoEcon
Item - CSoEcon
Item Attribute - CSoEcon
Item Equipped - CSource2
Metrics Fetch MapData Request - CSource2
Metrics Fetch MapData Response - CSource2
Metrics Match Perf Summary Notification - CSource2
Metrics Record Play Stats Notification - CSvc
MsgBroadcast Command - CSvc
MsgBsp Decal - CSvc
MsgClass Info - CSvc
MsgClear AllString Tables - CSvc
MsgCmd KeyValues - CSvc
MsgCreate String Table - CSvc
MsgCrosshair Angle - CSvc
MsgFix Angle - CSvc
MsgFlattened Serializer - CSvc
MsgFull Frame Split - CSvc
MsgGame Event - CSvc
MsgGame Event List - CSvc
MsgGame Session Configuration - CSvc
MsgGet Cvar Value - CSvc
MsgHltv Fixup Operator Status - CSvc
MsgHltv Replay - CSvc
MsgHltv Status - CSvc
MsgList Game Events - CSvc
MsgMenu - CSvc
MsgNext MsgPredicted - CSvc
MsgPacket Entities - CSvc
MsgPacket Reliable - CSvc
MsgPeer List - CSvc
MsgPrefetch - CSvc
MsgPrint - CSvc
MsgRcon Server Details - CSvc
MsgSend Table - CSvc
MsgServer Info - CSvc
MsgServer Steam Id - CSvc
MsgSet Pause - CSvc
MsgSet View - CSvc
MsgSounds - CSvc
MsgSplit Screen - CSvc
MsgStop Sound - CSvc
MsgTemp Entities - CSvc
MsgUpdate String Table - CSvc
MsgUser Commands - CSvc
MsgUser Message - CSvc
MsgVoice Data - CSvc
MsgVoice Init - CUser
Message Achievement Event - CUser
Message Ammo Denied - CUser
Message Anim State Graph State - CUser
Message Audio Parameter - CUser
Message Camera Transition - CUser
Message Close Caption - CUser
Message Close Caption Direct - CUser
Message Close Caption Placeholder - CUser
Message Colored Text - CUser
Message Credits Msg - CUser
Message Current Timescale - CUser
Message Desired Timescale - CUser
Message Diagnostic Response - CUser
Message DllStatus - CUser
Message Extra User Data - CUser
Message Fade - CUser
Message Game Title - CUser
Message Haptics Manager Effect - CUser
Message Haptics Manager Pulse - CUser
Message HudMsg - CUser
Message HudText - CUser
Message Inventory Response - CUser
Message Item Pickup - CUser
Message LagCompensation Error - CUser
Message Notify Response Found - CUser
Message Play Response Conditional - CUser
Message Request Diagnostic - CUser
Message Request DllStatus - CUser
Message Request Inventory - CUser
Message Request State - CUser
Message Request Util Action - CUser
Message Reset Hud - CUser
Message Rumble - CUser
Message SayText - CUser
Message SayText2 - CUser
Message SayText Channel - CUser
Message Screen Tilt - CUser
Message Send Audio - CUser
Message Server Frame Time - CUser
Message Shake - CUser
Message Shake Dir - CUser
Message Show Menu - CUser
Message Text Msg - CUser
Message Update CssClasses - CUser
Message Util MsgResponse - CUser
Message Voice Mask - CUser
Message Water Shake - CUser
MsgCustom Game Event - CUser
MsgHud Error - CUser
MsgParticle Manager - CWorkshop
GetContributors Request - CWorkshop
GetContributors Response - CWorkshop
Populate Item Descriptions Request - CWorkshop
SetItem Payment Rules Request - CWorkshop
SetItem Payment Rules Response - Cclc
MsgBaseline Ack - Cclc
MsgClient Info - Cclc
MsgCmd KeyValues - Cclc
MsgDiagnostic - Cclc
MsgHltv Fixup Operator Tick - Cclc
MsgHltv Replay - Cclc
MsgListen Events - Cclc
MsgLoading Progress - Cclc
MsgMove - Cclc
MsgRcon Server Details - Cclc
MsgRequest Pause - Cclc
MsgRespond Cvar Value - Cclc
MsgServer Status - Cclc
MsgSplit Player Connect - Cclc
MsgSplit Player Disconnect - Cclc
MsgVoice Data - Proto
Flattened Serializer FieldT - Proto
Flattened SerializerT
Enums§
- Bidirectional
Messages - ClcMessages
- Dialog
Type - EBase
Entity Messages - EBase
Game Events - EBase
User Messages - ECustom
Game Install Status - EDemo
Commands - EHaptic
Pulse Type - ENetwork
Disconnection Reason - EProto
Debug Visiblity - EProto
Execution Site - EQuery
Cvar Value Status - ERoll
Type - ESource2
Play Stats Field Type - ESource
Engine - ESplit
Screen Message Type - ESteam
Learn Cache Data Result - ESteam
Learn Data Type - ESteam
Learn GetAccess Tokens Result - ESteam
Learn Inference Metadata Result - ESteam
Learn Inference Result - ESteam
Learn Snapshot Project Result - ESteamm
Learn Register Data Source Result - EgcBase
Msg - EgcPlatform
- GcConnection
Status - GcProto
BufMsg Src - NetMessages
- Particle
Message - Partner
Account Type - Prefetch
Type - Replay
Event TypeT - Request
PauseT - Signon
StateT - Spawn
Group FlagsT - SvcMessages
- SvcMessages
LowFrequency - Voice
Data FormatT