From 511e29ef922f62fb73959e26950b2f74328c4c5c Mon Sep 17 00:00:00 2001 From: Saul Rennison Date: Thu, 30 Jan 2025 19:39:31 +0000 Subject: [PATCH] Add support for DemRecovery --- src/DemoFile/DemoEvents.cs | 4 + src/DemoFile/Protobufs/demo.proto | 17 ++- src/DemoFile/Protobufs/gameevents.proto | 2 +- src/DemoFile/Protobufs/netmessages.proto | 113 ++++++++++++++++-- .../Protobufs/network_connection.proto | 6 +- src/DemoFile/Protobufs/networkbasetypes.proto | 13 +- src/DemoFile/Protobufs/te.proto | 5 +- src/DemoFile/Protobufs/usermessages.proto | 27 ++++- 8 files changed, 158 insertions(+), 29 deletions(-) diff --git a/src/DemoFile/DemoEvents.cs b/src/DemoFile/DemoEvents.cs index a514f73..e5eb300 100644 --- a/src/DemoFile/DemoEvents.cs +++ b/src/DemoFile/DemoEvents.cs @@ -64,6 +64,9 @@ internal bool ReadDemoCommand(EDemoCommands msgType, ReadOnlySpan buffer, case EDemoCommands.DemAnimationHeader: DemoAnimationHeader?.Invoke(CDemoAnimationHeader.Parser.ParseFrom(buffer)); return true; + case EDemoCommands.DemRecovery: + DemoRecovery?.Invoke(CDemoRecovery.Parser.ParseFrom(buffer)); + return true; default: throw new ArgumentOutOfRangeException(nameof(msgType), msgType, $"Unknown demo command: {msgType}"); } @@ -105,4 +108,5 @@ private static void ReadDemoCommandCore(Action? callback, MessageParser public Action? DemoSpawnGroups; public Action? DemoAnimationData; public Action? DemoAnimationHeader; + public Action? DemoRecovery; } diff --git a/src/DemoFile/Protobufs/demo.proto b/src/DemoFile/Protobufs/demo.proto index f57f7a7..a58617a 100644 --- a/src/DemoFile/Protobufs/demo.proto +++ b/src/DemoFile/Protobufs/demo.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; enum EDemoCommands { DEM_Error = -1; @@ -20,7 +20,8 @@ enum EDemoCommands { DEM_SpawnGroups = 15; DEM_AnimationData = 16; DEM_AnimationHeader = 17; - DEM_Max = 18; + DEM_Recovery = 18; + DEM_Max = 19; DEM_IsCompressed = 64; } @@ -55,7 +56,7 @@ message CGameInfo { message CHeroSelectEvent { optional bool is_pick = 1; optional uint32 team = 2; - optional uint32 hero_id = 3; + optional int32 hero_id = 3; } optional uint64 match_id = 1; @@ -173,3 +174,13 @@ message CDemoUserCmd { message CDemoSpawnGroups { repeated bytes msgs = 3; } + +message CDemoRecovery { + message DemoInitialSpawnGroupEntry { + optional uint32 spawngrouphandle = 1; + optional bool was_created = 2; + } + + optional .CDemoRecovery.DemoInitialSpawnGroupEntry initial_spawn_group = 1; + optional bytes spawn_group_message = 2; +} diff --git a/src/DemoFile/Protobufs/gameevents.proto b/src/DemoFile/Protobufs/gameevents.proto index 9d10f80..125dee1 100644 --- a/src/DemoFile/Protobufs/gameevents.proto +++ b/src/DemoFile/Protobufs/gameevents.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; import "networkbasetypes.proto"; diff --git a/src/DemoFile/Protobufs/netmessages.proto b/src/DemoFile/Protobufs/netmessages.proto index 4cf048a..8a8c7de 100644 --- a/src/DemoFile/Protobufs/netmessages.proto +++ b/src/DemoFile/Protobufs/netmessages.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; import "networkbasetypes.proto"; @@ -7,19 +7,17 @@ enum CLC_Messages { clc_Move = 21; clc_VoiceData = 22; clc_BaselineAck = 23; - clc_ListenEvents = 24; clc_RespondCvarValue = 25; clc_FileCRCCheck = 26; clc_LoadingProgress = 27; clc_SplitPlayerConnect = 28; - clc_ClientMessage = 29; clc_SplitPlayerDisconnect = 30; clc_ServerStatus = 31; - clc_ServerPing = 32; clc_RequestPause = 33; clc_CmdKeyValues = 34; clc_RconServerDetails = 35; clc_HltvReplay = 36; + clc_Diagnostic = 37; } enum SVC_Messages { @@ -50,7 +48,6 @@ enum SVC_Messages { svc_FullFrameSplit = 70; svc_RconServerDetails = 71; svc_UserMessage = 72; - svc_HltvReplay = 73; svc_Broadcast_Command = 74; svc_HltvFixupOperatorStatus = 75; svc_UserCmds = 76; @@ -125,8 +122,7 @@ message CCLCMsg_ClientInfo { message CCLCMsg_Move { optional bytes data = 3; - optional uint32 command_number = 4; - optional uint32 num_commands = 5; + optional uint32 last_command_number = 4; } message CMsgVoiceAudio { @@ -179,11 +175,6 @@ message CCLCMsg_SplitPlayerConnect { optional string playername = 1; } -message CCLCMsg_ClientMessage { - optional int32 msg_type = 1; - optional bytes data = 2; -} - message CCLCMsg_SplitPlayerDisconnect { optional int32 slot = 1; } @@ -205,6 +196,101 @@ message CCLCMsg_RconServerDetails { optional bytes token = 1; } +message CMsgSource2SystemSpecs { + optional string cpu_id = 1; + optional string cpu_brand = 2; + optional uint32 cpu_model = 3; + optional uint32 cpu_num_physical = 4; + optional uint32 ram_physical_total_mb = 21; + optional string gpu_rendersystem_dll_name = 41; + optional uint32 gpu_vendor_id = 42; + optional string gpu_driver_name = 43; + optional uint32 gpu_driver_version_high = 44; + optional uint32 gpu_driver_version_low = 45; + optional uint32 gpu_dx_support_level = 46; + optional uint32 gpu_texture_memory_size_mb = 47; +} + +message CMsgSource2VProfLiteReportItem { + optional string name = 1; + optional uint32 active_samples = 2; + optional uint32 active_samples_1secmax = 4; + optional uint32 usec_max = 3; + optional uint32 usec_avg_active = 11; + optional uint32 usec_p50_active = 12; + optional uint32 usec_p99_active = 13; + optional uint32 usec_avg_all = 21; + optional uint32 usec_p50_all = 22; + optional uint32 usec_p99_all = 23; + optional uint32 usec_1secmax_avg_active = 31; + optional uint32 usec_1secmax_p50_active = 32; + optional uint32 usec_1secmax_p95_active = 33; + optional uint32 usec_1secmax_p99_active = 34; + optional uint32 usec_1secmax_avg_all = 41; + optional uint32 usec_1secmax_p50_all = 42; + optional uint32 usec_1secmax_p95_all = 43; + optional uint32 usec_1secmax_p99_all = 44; +} + +message CMsgSource2VProfLiteReport { + optional .CMsgSource2VProfLiteReportItem total = 1; + repeated .CMsgSource2VProfLiteReportItem items = 2; + optional uint32 discarded_frames = 3; +} + +message CMsgSource2NetworkFlowQuality { + optional uint32 duration = 1; + optional uint64 bytes_total = 5; + optional uint64 bytes_total_reliable = 6; + optional uint64 bytes_total_voice = 7; + optional uint32 bytes_sec_p95 = 10; + optional uint32 bytes_sec_p99 = 11; + optional uint32 enginemsgs_total = 20; + optional uint32 enginemsgs_sec_p95 = 21; + optional uint32 enginemsgs_sec_p99 = 22; + optional uint32 ticks_total = 40; + optional uint32 ticks_good = 41; + optional uint32 ticks_good_almost_late = 42; + optional uint32 ticks_fixed_dropped = 43; + optional uint32 ticks_fixed_late = 44; + optional uint32 ticks_bad_dropped = 45; + optional uint32 ticks_bad_late = 46; + optional uint32 ticks_bad_other = 47; + optional uint32 tick_missrate_samples_total = 50; + optional uint32 tick_missrate_samples_perfect = 51; + optional uint32 tick_missrate_samples_perfectnet = 52; + optional uint32 tick_missratenet_p75_x10 = 53; + optional uint32 tick_missratenet_p95_x10 = 54; + optional uint32 tick_missratenet_p99_x10 = 55; + optional sint32 recvmargin_p1 = 61; + optional sint32 recvmargin_p5 = 62; + optional sint32 recvmargin_p25 = 63; + optional sint32 recvmargin_p50 = 64; + optional sint32 recvmargin_p75 = 65; + optional sint32 recvmargin_p95 = 66; +} + +message CCLCMsg_Diagnostic { + optional .CMsgSource2SystemSpecs system_specs = 1; + optional .CMsgSource2VProfLiteReport vprof_report = 2; +} + +message CSource2Metrics_MatchPerfSummary_Notification { + message Client { + optional .CMsgSource2SystemSpecs system_specs = 1; + optional .CMsgSource2VProfLiteReport profile = 2; + optional uint32 build_id = 3; + optional fixed64 steamid = 10; + } + + optional uint32 appid = 1; + optional string game_mode = 2; + optional uint32 server_build_id = 3; + optional .CMsgSource2VProfLiteReport server_profile = 10; + repeated .CSource2Metrics_MatchPerfSummary_Notification.Client clients = 11; + optional string map = 20; +} + message CSVCMsg_ServerInfo { optional int32 protocol = 1; optional int32 server_count = 2; @@ -385,7 +471,7 @@ message CSVCMsg_PacketEntities { optional bytes serialized_entities = 13; repeated .CSVCMsg_PacketEntities.alternate_baseline_t alternate_baselines = 15; optional uint32 has_pvs_vis_bits = 16; - optional uint32 last_cmd_recv_margin = 18; + repeated sint32 cmd_recv_status = 22 [packed = true]; optional .CSVCMsg_PacketEntities.non_transmitted_entities_t non_transmitted_entities = 19; optional uint32 cq_starved_command_ticks = 20; optional uint32 cq_discarded_command_ticks = 21; @@ -618,6 +704,7 @@ message CMsgServerUserCmd { optional int32 cmd_number = 2; optional int32 player_slot = 3 [default = -1]; optional int32 server_tick_executed = 4; + optional int32 client_tick = 5; } message CSVCMsg_UserCommands { diff --git a/src/DemoFile/Protobufs/network_connection.proto b/src/DemoFile/Protobufs/network_connection.proto index dbade48..e148d22 100644 --- a/src/DemoFile/Protobufs/network_connection.proto +++ b/src/DemoFile/Protobufs/network_connection.proto @@ -1,9 +1,10 @@ -syntax = "proto2"; +syntax = "proto2"; import "google/protobuf/descriptor.proto"; extend .google.protobuf.EnumValueOptions { optional string network_connection_token = 50500; + optional string network_connection_detail_token = 50501; } enum ENetworkDisconnectionReason { @@ -125,4 +126,7 @@ enum ENetworkDisconnectionReason { NETWORK_DISCONNECT_KICKED_SUICIDE = 159 [(network_connection_token) = "#Player_DisconnectReason_Suicide"]; NETWORK_DISCONNECT_KICKED_NOSTEAMLOGIN = 160 [(network_connection_token) = "#Player_DisconnectReason_NoSteamLogin"]; NETWORK_DISCONNECT_KICKED_NOSTEAMTICKET = 161 [(network_connection_token) = "#Player_DisconnectReason_NoSteamTicket"]; + NETWORK_DISCONNECT_KICKED_INPUTAUTOMATION = 162 [(network_connection_token) = "#Player_DisconnectReason_InputAutomation", (network_connection_detail_token) = "#Player_DisconnectReason_InputAutomation_Detail"]; + NETWORK_DISCONNECT_KICKED_VACNETABNORMALBEHAVIOR = 163 [(network_connection_token) = "#Player_DisconnectReason_VacNetAbnormalBehavior"]; + NETWORK_DISCONNECT_KICKED_INSECURECLIENT = 164 [(network_connection_token) = "#Player_DisconnectReason_InsecureClient"]; } diff --git a/src/DemoFile/Protobufs/networkbasetypes.proto b/src/DemoFile/Protobufs/networkbasetypes.proto index 1066857..5ef5b2a 100644 --- a/src/DemoFile/Protobufs/networkbasetypes.proto +++ b/src/DemoFile/Protobufs/networkbasetypes.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; import "network_connection.proto"; @@ -107,22 +107,17 @@ message CNETMsg_SplitScreenUser { optional int32 slot = 1; } -message CNETMsg_Disconnect_Legacy { - optional .ENetworkDisconnectionReason reason = 2 [default = NETWORK_DISCONNECT_INVALID]; -} - message CNETMsg_Tick { optional uint32 tick = 1; - optional uint32 host_frametime = 2; - optional uint32 host_frametime_std_deviation = 3; optional uint32 host_computationtime = 4; optional uint32 host_computationtime_std_deviation = 5; - optional uint32 host_framestarttime_std_deviation = 6; - optional uint32 host_loss = 7; + optional uint32 legacy_host_loss = 7; optional uint32 host_unfiltered_frametime = 8; optional uint32 hltv_replay_flags = 9; optional uint32 expected_long_tick = 10; optional string expected_long_tick_reason = 11; + optional uint32 host_frame_dropped_pct_x10 = 12; + optional uint32 host_frame_irregular_arrival_pct_x10 = 13; } message CNETMsg_StringCmd { diff --git a/src/DemoFile/Protobufs/te.proto b/src/DemoFile/Protobufs/te.proto index 6568f46..3c53fec 100644 --- a/src/DemoFile/Protobufs/te.proto +++ b/src/DemoFile/Protobufs/te.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; import "networkbasetypes.proto"; @@ -199,6 +199,9 @@ message CMsgTEExplosion { optional bool affect_ragdolls = 9; optional string effect_name = 10; optional uint32 explosion_type = 11; + optional bool create_debris = 12; + optional .CMsgVector debris_origin = 13; + optional fixed32 debris_surfaceprop = 14; } message CMsgTEDust { diff --git a/src/DemoFile/Protobufs/usermessages.proto b/src/DemoFile/Protobufs/usermessages.proto index ac27b04..8c006b8 100644 --- a/src/DemoFile/Protobufs/usermessages.proto +++ b/src/DemoFile/Protobufs/usermessages.proto @@ -1,4 +1,4 @@ -syntax = "proto2"; +syntax = "proto2"; import "networkbasetypes.proto"; @@ -109,6 +109,8 @@ enum PARTICLE_MESSAGE { GAME_PARTICLE_MANAGER_EVENT_CLEAR_MODELLIST_OVERRIDE = 31; GAME_PARTICLE_MANAGER_EVENT_CREATE_PHYSICS_SIM = 32; GAME_PARTICLE_MANAGER_EVENT_DESTROY_PHYSICS_SIM = 33; + GAME_PARTICLE_MANAGER_EVENT_SET_VDATA = 34; + GAME_PARTICLE_MANAGER_EVENT_SET_MATERIAL_OVERRIDE = 35; } enum EHapticPulseType { @@ -352,6 +354,7 @@ message CUserMsg_ParticleManager { optional string control_point_configuration = 7; optional bool cluster = 8; optional float endcap_time = 9; + optional .CMsgVector aggregation_position = 10; } message DestroyParticle { @@ -533,11 +536,22 @@ message CUserMsg_ParticleManager { message CreatePhysicsSim { optional string prop_group_name = 1; + optional bool use_high_quality_simulation = 2; + optional uint32 max_particle_count = 3; } message DestroyPhysicsSim { } + message SetVData { + optional string vdata_name = 1; + } + + message SetMaterialOverride { + optional string material_name = 1; + optional bool include_children = 2; + } + required .PARTICLE_MESSAGE type = 1 [default = GAME_PARTICLE_MANAGER_EVENT_CREATE]; required uint32 index = 2; optional .CUserMsg_ParticleManager.ReleaseParticleIndex release_particle_index = 3; @@ -573,6 +587,8 @@ message CUserMsg_ParticleManager { optional .CUserMsg_ParticleManager.ClearModellistOverride clear_modellist_override = 34; optional .CUserMsg_ParticleManager.CreatePhysicsSim create_physics_sim = 35; optional .CUserMsg_ParticleManager.DestroyPhysicsSim destroy_physics_sim = 36; + optional .CUserMsg_ParticleManager.SetVData set_vdata = 37; + optional .CUserMsg_ParticleManager.SetMaterialOverride set_material_override = 38; extensions 100 to 201; } @@ -779,6 +795,13 @@ message CUserMessage_NotifyResponseFound { optional string response_value = 3; optional string response_concept = 4; repeated .CUserMessage_NotifyResponseFound.Criteria criteria = 5; + repeated uint32 int_criteria_names = 6 [packed = true]; + repeated int32 int_criteria_values = 7 [packed = true]; + repeated uint32 float_criteria_names = 8 [packed = true]; + repeated float float_criteria_values = 9; + repeated uint32 symbol_criteria_names = 10 [packed = true]; + repeated uint32 symbol_criteria_values = 11 [packed = true]; + optional int32 speak_result = 12; } message CUserMessage_PlayResponseConditional { @@ -786,4 +809,6 @@ message CUserMessage_PlayResponseConditional { repeated int32 player_slots = 2; optional string response = 3; optional .CMsgVector ent_origin = 4; + optional float pre_delay = 5; + optional int32 mix_priority = 6; }