From 22277f14826390afe29ee9976d082bab7d190ab4 Mon Sep 17 00:00:00 2001 From: Vauff Date: Fri, 14 Nov 2025 18:01:51 -0500 Subject: [PATCH 1/7] Fix ZM knockback ignoring damage filters --- src/detours.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detours.cpp b/src/detours.cpp index 9d38e563..4fb1bb84 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -151,7 +151,7 @@ int64 FASTCALL Detour_CBaseEntity_TakeDamageOld(CBaseEntity* pThis, CTakeDamageI CBaseEntity_TakeDamageOld(pThis, pInfo, pResult); - if (pResult->m_nDamageDealt > 0 && g_cvarEnableZR.Get() && pThis->IsPawn()) + if (pResult->m_nDamageDealt > 0 && !pResult->m_bWasDamageSuppressed && g_cvarEnableZR.Get() && pThis->IsPawn()) ZR_OnPlayerTakeDamage(reinterpret_cast(pThis), pInfo, pResult->m_nDamageDealt); return 1; From a283a7e203ecba64be7dfd8df1b841bc2382dd60 Mon Sep 17 00:00:00 2001 From: Vauff Date: Fri, 14 Nov 2025 20:47:47 -0500 Subject: [PATCH 2/7] Fix round not ending when last player on team disconnects Initial fix attempt did not work, because it was still checking the players team after they had already been set to CS_TEAM_NONE --- src/cs2fixes.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index f10483b5..3bd66b00 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -953,9 +953,8 @@ void CS2Fixes::Hook_ClientDisconnect(CPlayerSlot slot, ENetworkDisconnectionReas if (g_cvarEnableZR.Get()) { - if (player) - ZR_CheckTeamWinConditions(player->m_iTeamNum == CS_TEAM_T ? CS_TEAM_CT : CS_TEAM_T); - else if (!ZR_CheckTeamWinConditions(CS_TEAM_T)) // If we cant get team num, just check both + // Controller team num is not valid post-disconnect, so just check both teams + if (!ZR_CheckTeamWinConditions(CS_TEAM_T)) ZR_CheckTeamWinConditions(CS_TEAM_CT); } From f3c08cbfff28eb32d8746c8302960c7a41631aa6 Mon Sep 17 00:00:00 2001 From: Vauff Date: Sun, 16 Nov 2025 22:08:42 -0500 Subject: [PATCH 3/7] Add !zsounds toggle --- src/cs2fixes.cpp | 117 +++++++++++++++++++++------------------ src/cs2fixes.h | 1 + src/playermanager.cpp | 17 ++++++ src/playermanager.h | 6 ++ src/user_preferences.cpp | 2 + src/zombiereborn.cpp | 31 +++++++++++ src/zombiereborn.h | 4 +- 7 files changed, 122 insertions(+), 56 deletions(-) diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 3bd66b00..10832b82 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -757,69 +757,76 @@ void CS2Fixes::Hook_PostEvent(CSplitScreenSlot nSlot, bool bLocalOnly, int nClie if (g_cvarEnableNoShake.Get()) *(uint64*)clients &= ~g_playerManager->GetNoShakeMask(); } - else if (g_cvarEnableStopSound.Get() && info->m_MessageId == GE_SosStartSoundEvent) + else if (info->m_MessageId == GE_SosStartSoundEvent) { - static std::set soundEventHashes; auto msg = const_cast(pData)->ToPB(); - ExecuteOnce( - soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.HitWall")); - soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Slash")); - soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Hit")); - soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Stab")); - soundEventHashes.insert(GetSoundEventHash("Weapon_sg556.ZoomIn")); - soundEventHashes.insert(GetSoundEventHash("Weapon_sg556.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_AUG.ZoomIn")); - soundEventHashes.insert(GetSoundEventHash("Weapon_AUG.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_SSG08.Zoom")); - soundEventHashes.insert(GetSoundEventHash("Weapon_SSG08.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_SCAR20.Zoom")); - soundEventHashes.insert(GetSoundEventHash("Weapon_SCAR20.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_G3SG1.Zoom")); - soundEventHashes.insert(GetSoundEventHash("Weapon_G3SG1.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_AWP.Zoom")); - soundEventHashes.insert(GetSoundEventHash("Weapon_AWP.ZoomOut")); - soundEventHashes.insert(GetSoundEventHash("Weapon_Revolver.Prepare")); - soundEventHashes.insert(GetSoundEventHash("Weapon.AutoSemiAutoSwitch"));); - - if (!soundEventHashes.contains(msg->soundevent_hash())) - return; - - uint64 stopSoundMask = g_playerManager->GetStopSoundMask(); - uint64 silenceSoundMask = g_playerManager->GetSilenceSoundMask(); - - if (!msg->has_source_entity_index()) - return; - - CBaseEntity* pSourceEntity = (CBaseEntity*)g_pEntitySystem->GetEntityInstance(CEntityIndex(msg->source_entity_index())); - int playerSlot = -1; - - if (!pSourceEntity) - return; - - if (!V_strcasecmp(pSourceEntity->GetClassname(), "player")) - { - playerSlot = ((CCSPlayerPawn*)pSourceEntity)->GetController()->GetPlayerSlot(); - } - else if (!V_strncasecmp(pSourceEntity->GetClassname(), "weapon_", 7)) + if (g_cvarEnableZR.Get()) + ZR_PostEventAbstract_SosStartSoundEvent(clients, msg); + + if (g_cvarEnableStopSound.Get()) { - CCSPlayerPawn* pPawn = (CCSPlayerPawn*)pSourceEntity->m_hOwnerEntity().Get(); + static std::set soundEventHashes; + + ExecuteOnce( + soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.HitWall")); + soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Slash")); + soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Hit")); + soundEventHashes.insert(GetSoundEventHash("Weapon_Knife.Stab")); + soundEventHashes.insert(GetSoundEventHash("Weapon_sg556.ZoomIn")); + soundEventHashes.insert(GetSoundEventHash("Weapon_sg556.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_AUG.ZoomIn")); + soundEventHashes.insert(GetSoundEventHash("Weapon_AUG.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_SSG08.Zoom")); + soundEventHashes.insert(GetSoundEventHash("Weapon_SSG08.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_SCAR20.Zoom")); + soundEventHashes.insert(GetSoundEventHash("Weapon_SCAR20.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_G3SG1.Zoom")); + soundEventHashes.insert(GetSoundEventHash("Weapon_G3SG1.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_AWP.Zoom")); + soundEventHashes.insert(GetSoundEventHash("Weapon_AWP.ZoomOut")); + soundEventHashes.insert(GetSoundEventHash("Weapon_Revolver.Prepare")); + soundEventHashes.insert(GetSoundEventHash("Weapon.AutoSemiAutoSwitch"));); + + if (!soundEventHashes.contains(msg->soundevent_hash())) + return; + + uint64 stopSoundMask = g_playerManager->GetStopSoundMask(); + uint64 silenceSoundMask = g_playerManager->GetSilenceSoundMask(); + + if (!msg->has_source_entity_index()) + return; + + CBaseEntity* pSourceEntity = (CBaseEntity*)g_pEntitySystem->GetEntityInstance(CEntityIndex(msg->source_entity_index())); + int playerSlot = -1; + + if (!pSourceEntity) + return; + + if (!V_strcasecmp(pSourceEntity->GetClassname(), "player")) + { + playerSlot = ((CCSPlayerPawn*)pSourceEntity)->GetController()->GetPlayerSlot(); + } + else if (!V_strncasecmp(pSourceEntity->GetClassname(), "weapon_", 7)) + { + CCSPlayerPawn* pPawn = (CCSPlayerPawn*)pSourceEntity->m_hOwnerEntity().Get(); - if (pPawn && pPawn->IsPawn()) - playerSlot = pPawn->GetController()->GetPlayerSlot(); - } + if (pPawn && pPawn->IsPawn()) + playerSlot = pPawn->GetController()->GetPlayerSlot(); + } - // Remove player who triggered this sound from masks - // Because some of these sounds never get played locally (Zoom's, Knife Hit/Stab) - if (playerSlot != -1 && g_playerManager->IsPlayerUsingStopSound(playerSlot)) - stopSoundMask &= ~((uint64)1 << playerSlot); + // Remove player who triggered this sound from masks + // Because some of these sounds never get played locally (Zoom's, Knife Hit/Stab) + if (playerSlot != -1 && g_playerManager->IsPlayerUsingStopSound(playerSlot)) + stopSoundMask &= ~((uint64)1 << playerSlot); - if (playerSlot != -1 && g_playerManager->IsPlayerUsingSilenceSound(playerSlot)) - silenceSoundMask &= ~((uint64)1 << playerSlot); + if (playerSlot != -1 && g_playerManager->IsPlayerUsingSilenceSound(playerSlot)) + silenceSoundMask &= ~((uint64)1 << playerSlot); - // Filter out people using stop/silence sound from hearing this sound from other players - *(uint64*)clients &= ~stopSoundMask; - *(uint64*)clients &= ~silenceSoundMask; + // Filter out people using stop/silence sound from hearing this sound from other players + *(uint64*)clients &= ~stopSoundMask; + *(uint64*)clients &= ~silenceSoundMask; + } } } diff --git a/src/cs2fixes.h b/src/cs2fixes.h index dd673234..b9c17ff0 100644 --- a/src/cs2fixes.h +++ b/src/cs2fixes.h @@ -53,6 +53,7 @@ extern CCSGameRules* g_pGameRules; extern CSpawnGroupMgrGameSystem* g_pSpawnGroupMgr; extern double g_flUniversalTime; extern CGlobalVars* GetGlobals(); +extern uint32 GetSoundEventHash(const char* pszSoundEventName); extern CUtlVector* GetClientList(); extern CServerSideClient* GetClientBySlot(CPlayerSlot slot); extern void FullUpdateAllClients(); diff --git a/src/playermanager.cpp b/src/playermanager.cpp index 14d00396..7af260f8 100644 --- a/src/playermanager.cpp +++ b/src/playermanager.cpp @@ -1772,6 +1772,22 @@ void CPlayerManager::SetPlayerSilenceSound(int slot, bool set) g_pUserPreferencesSystem->SetPreferenceInt(slot, SOUND_STATUS_PREF_KEY_NAME, iStopPreferenceStatus + iSilencePreferenceStatus); } +void CPlayerManager::SetPlayerZSounds(int slot, bool set) +{ + if (set) + m_nUsingZSounds |= ((uint64)1 << slot); + else + m_nUsingZSounds &= ~((uint64)1 << slot); + + // Set the user prefs if the player is ingame + ZEPlayer* pPlayer = m_vecPlayers[slot]; + if (!pPlayer) return; + + uint64 iSlotMask = (uint64)1 << slot; + int iZSoundsPreferenceStatus = (m_nUsingZSounds & iSlotMask) ? 1 : 0; + g_pUserPreferencesSystem->SetPreferenceInt(slot, ZSOUNDS_PREF_KEY_NAME, iZSoundsPreferenceStatus); +} + void CPlayerManager::SetPlayerStopDecals(int slot, bool set) { if (set) @@ -1808,6 +1824,7 @@ void CPlayerManager::ResetPlayerFlags(int slot) { SetPlayerStopSound(slot, true); SetPlayerSilenceSound(slot, false); + SetPlayerZSounds(slot, true); SetPlayerStopDecals(slot, true); SetPlayerNoShake(slot, false); } diff --git a/src/playermanager.h b/src/playermanager.h index c8e08933..5cf1e320 100644 --- a/src/playermanager.h +++ b/src/playermanager.h @@ -53,6 +53,7 @@ extern CConVar g_cvarFlashLightAttachment; #define SOUND_STATUS_PREF_KEY_NAME "sound_status" #define NO_SHAKE_PREF_KEY_NAME "no_shake" #define BUTTON_WATCH_PREF_KEY_NAME "button_watch" +#define ZSOUNDS_PREF_KEY_NAME "zsounds" #define INVALID_ZEPLAYERHANDLE_INDEX 0u static uint32 iZEPlayerHandleSerial = 0u; // this should actually be 3 bytes large, but no way enough players join in servers lifespan for this to be an issue @@ -398,6 +399,7 @@ class CPlayerManager V_memset(m_vecPlayers, 0, sizeof(m_vecPlayers)); m_nUsingStopSound = -1; // On by default m_nUsingSilenceSound = 0; + m_nUsingZSounds = -1; // On by default m_nUsingStopDecals = -1; // On by default m_nUsingNoShake = 0; } @@ -425,11 +427,13 @@ class CPlayerManager uint64 GetStopSoundMask() { return m_nUsingStopSound; } uint64 GetSilenceSoundMask() { return m_nUsingSilenceSound; } + uint64 GetZSoundsMask() { return m_nUsingZSounds; } uint64 GetStopDecalsMask() { return m_nUsingStopDecals; } uint64 GetNoShakeMask() { return m_nUsingNoShake; } void SetPlayerStopSound(int slot, bool set); void SetPlayerSilenceSound(int slot, bool set); + void SetPlayerZSounds(int slot, bool set); void SetPlayerStopDecals(int slot, bool set); void SetPlayerNoShake(int slot, bool set); @@ -437,6 +441,7 @@ class CPlayerManager bool IsPlayerUsingStopSound(int slot) { return m_nUsingStopSound & ((uint64)1 << slot); } bool IsPlayerUsingSilenceSound(int slot) { return m_nUsingSilenceSound & ((uint64)1 << slot); } + bool IsPlayerUsingZSounds(int slot) { return m_nUsingZSounds & ((uint64)1 << slot); } bool IsPlayerUsingStopDecals(int slot) { return m_nUsingStopDecals & ((uint64)1 << slot); } bool IsPlayerUsingNoShake(int slot) { return m_nUsingNoShake & ((uint64)1 << slot); } @@ -450,6 +455,7 @@ class CPlayerManager uint64 m_nUsingStopSound; uint64 m_nUsingSilenceSound; + uint64 m_nUsingZSounds; uint64 m_nUsingStopDecals; uint64 m_nUsingNoShake; }; diff --git a/src/user_preferences.cpp b/src/user_preferences.cpp index 7953fe9e..1e32219c 100644 --- a/src/user_preferences.cpp +++ b/src/user_preferences.cpp @@ -112,6 +112,7 @@ void CUserPreferencesSystem::OnPutPreferences(int iSlot) bool bHideDecals = (bool)GetPreferenceInt(iSlot, DECAL_PREF_KEY_NAME, 1); bool bNoShake = (bool)GetPreferenceInt(iSlot, NO_SHAKE_PREF_KEY_NAME, 0); int iButtonWatchMode = GetPreferenceInt(iSlot, BUTTON_WATCH_PREF_KEY_NAME, 0); + bool bZSounds = (bool)GetPreferenceInt(iSlot, ZSOUNDS_PREF_KEY_NAME, 1); // EntWatch int iEntwatchMode = GetPreferenceInt(iSlot, EW_PREF_HUD_MODE, 0); @@ -125,6 +126,7 @@ void CUserPreferencesSystem::OnPutPreferences(int iSlot) // Set the values that we just loaded --- the player is guaranteed available g_playerManager->SetPlayerStopSound(iSlot, bStopSound); g_playerManager->SetPlayerSilenceSound(iSlot, bSilenceSound); + g_playerManager->SetPlayerZSounds(iSlot, bZSounds); g_playerManager->SetPlayerStopDecals(iSlot, bHideDecals); g_playerManager->SetPlayerNoShake(iSlot, bNoShake); diff --git a/src/zombiereborn.cpp b/src/zombiereborn.cpp index d72a324f..08c134ab 100644 --- a/src/zombiereborn.cpp +++ b/src/zombiereborn.cpp @@ -1750,6 +1750,37 @@ void ZR_EndRoundAndAddTeamScore(int iTeamNum) } } +void ZR_PostEventAbstract_SosStartSoundEvent(const uint64* pClients, CNetMessagePB* pMsg) +{ + static std::set soundEventHashes; + + ExecuteOnce( + soundEventHashes.insert(GetSoundEventHash("zr.amb.scream")); + soundEventHashes.insert(GetSoundEventHash("zr.amb.zombie_die")); + soundEventHashes.insert(GetSoundEventHash("zr.amb.zombie_pain")); + soundEventHashes.insert(GetSoundEventHash("zr.amb.zombie_voice_idle"));); + + // Filter out people with zsounds disabled from hearing this sound + if (soundEventHashes.contains(pMsg->soundevent_hash())) + *(uint64*)pClients &= g_playerManager->GetZSoundsMask(); +} + +CON_COMMAND_CHAT(zsounds, "- Toggle zombie sounds") +{ + if (!player) + { + ClientPrint(player, HUD_PRINTCONSOLE, ZR_PREFIX "You cannot use this command from the server console."); + return; + } + + int iPlayer = player->GetPlayerSlot(); + bool bSet = !g_playerManager->IsPlayerUsingZSounds(iPlayer); + + g_playerManager->SetPlayerZSounds(iPlayer, bSet); + + ClientPrint(player, HUD_PRINTTALK, ZR_PREFIX "You have %s zombie sounds.", bSet ? "enabled" : "disabled"); +} + CON_COMMAND_CHAT(ztele, "- Teleport to spawn") { // Silently return so the command is completely hidden diff --git a/src/zombiereborn.h b/src/zombiereborn.h index 8cdc6f5a..dd3729ec 100644 --- a/src/zombiereborn.h +++ b/src/zombiereborn.h @@ -24,6 +24,7 @@ #include "entity/ccsplayerpawn.h" #include "eventlistener.h" #include "gamesystem.h" +#include "gameevents.pb.h" #include "vendor/nlohmann/json_fwd.hpp" using ordered_json = nlohmann::ordered_json; @@ -276,4 +277,5 @@ void ZR_Detour_CEntityIdentity_AcceptInput(CEntityIdentity* pThis, CUtlSymbolLar void ZR_Hook_ClientPutInServer(CPlayerSlot slot, char const* pszName, int type, uint64 xuid); void ZR_Hook_ClientCommand_JoinTeam(CPlayerSlot slot, const CCommand& args); void ZR_Precache(IEntityResourceManifest* pResourceManifest); -bool ZR_CheckTeamWinConditions(int iTeamNum); \ No newline at end of file +bool ZR_CheckTeamWinConditions(int iTeamNum); +void ZR_PostEventAbstract_SosStartSoundEvent(const uint64* pClients, CNetMessagePB* pMsg); \ No newline at end of file From 35891ff878bec3de50f1153c1be919dd2336a3f5 Mon Sep 17 00:00:00 2001 From: Vauff Date: Fri, 21 Nov 2025 23:34:06 -0500 Subject: [PATCH 4/7] Add a proper EntWatch config template --- PackageScript | 2 +- configs/entwatch/maps/example_config.jsonc | 30 ------------- configs/entwatch/maps/template.jsonc | 52 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 31 deletions(-) delete mode 100644 configs/entwatch/maps/example_config.jsonc create mode 100644 configs/entwatch/maps/template.jsonc diff --git a/PackageScript b/PackageScript index 509759c9..cda3090e 100644 --- a/PackageScript +++ b/PackageScript @@ -120,7 +120,7 @@ for task in MMSPlugin.binaries: builder.AddCopy(os.path.join('configs', 'zr', 'playerclass.jsonc.example'), zr_folder) builder.AddCopy(os.path.join('configs', 'zr', 'weapons.cfg.example'), zr_folder) builder.AddCopy(os.path.join('configs', 'zr', 'hitgroups.cfg.example'), zr_folder) - builder.AddCopy(os.path.join('configs', 'entwatch', 'maps', 'example_config.jsonc'), ew_maps_folder) + builder.AddCopy(os.path.join('configs', 'entwatch', 'maps', 'template.jsonc'), ew_maps_folder) builder.AddCopy(os.path.join('gamedata', 'cs2fixes.games.txt'), gamedata_folder) particles_cs2f_folder = builder.AddFolder(os.path.join(packages[sdk_name].sdk_name, 'particles', MMSPlugin.metadata['name'])) diff --git a/configs/entwatch/maps/example_config.jsonc b/configs/entwatch/maps/example_config.jsonc deleted file mode 100644 index 92cb463a..00000000 --- a/configs/entwatch/maps/example_config.jsonc +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "name": "Gravity Magic" - "shortname": "Gravity", - "hammerid": "12345", - "message": true, - "ui": true, - "transfer": true, - "color": "purple", - "templated": true, // only set false if the weapon is NOT in a template - "handlers": [ - { - "type": "button", - "hammerid": "buttonhammerid", - "event": "OnPressed", - "mode": 2, - "cooldown": 60, - "maxuses": 0, - "message": true, - "ui": true, - "templated": true // only set false if this entity is NOT in a template - } - ], - "triggers": ["3333", "22222"] - }, - { - "name": "Item 2", - // ... - } -] diff --git a/configs/entwatch/maps/template.jsonc b/configs/entwatch/maps/template.jsonc new file mode 100644 index 00000000..c1abd676 --- /dev/null +++ b/configs/entwatch/maps/template.jsonc @@ -0,0 +1,52 @@ +[ + { + "name": "Item Name", // Name of item that appears in chat + "shortname": "Short Name", // Name of item that appears on the HUD + "hammerid": "", // Hammerid of the weapon entity + "message": true, // Whether to show pickup/drop messages in chat + "ui": true, // Whether to show this item on the HUD + "transfer": true, // Whether to allow this item to be transferred (this auto detects false for knife items) + "color": "", // Color of the item for chat messages (see list of colors) + "triggers": [""], // Array of hammerids of any triggers that this item is associated with + "templated": true, // Whether the entity of this handler is templated with the item weapon, (auto detected if not specified) + "handlers": [ + { + "name": "Handler", // extra name to show in chat when used e.g. XXX has used Item Name (Handler) + "type": "button", // "button", + // "counterdown" - counter stops OnHitMin + // "counterup" - counter stops OnHitMax + // (anything else is ignored) + "hammerid": "", // hammerid of the entity + "event": "OnPressed", // Name of the output, counterup/down types always force "OutValue" + "mode": 2, // Mode of the handler + // 0/1 = None + // 2 = Cooldown, 3 = MaxUses (cooldown between each) + // 4 = CooldownAfterUses, 5 = CounterValue + "offset": [5,-9], // ADDS the specified offset to counter values, + // First number is counter value, Second is counter max + "cooldown": 60, // Cooldown duration if mode = 2,3,4 + "maxuses": 0, // Maxuses if mode = 3,4 + "message": true, // Whether to show when this is used in chat + "ui": true, // Whether to track this handler on the HUD + "templated": true // Whether the entity of this handler is templated with the item weapon, + } // (this will attempt to auto detect if not specified) + ] + } +] + +// LIST OF COLOR NAMES (grouped if they are the same) +// white, default +// darkred +// team +// green +// lightgreen +// olive +// red +// gray, grey +// yellow +// silver +// blue +// darkblue +// purple, pink +// red2 +// orange, gold \ No newline at end of file From 4683b77991b394731df9c0ac41d7534a83206e02 Mon Sep 17 00:00:00 2001 From: notkoen <45914779+notkoen@users.noreply.github.com> Date: Wed, 26 Nov 2025 16:38:48 -0800 Subject: [PATCH 5/7] detours: add edge case to chat timer detection (#410) --- src/detours.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/detours.cpp b/src/detours.cpp index 4fb1bb84..ae928b26 100644 --- a/src/detours.cpp +++ b/src/detours.cpp @@ -288,13 +288,21 @@ void SayChatMessageWithTimer(IRecipientFilter& filter, const char* pText, CCSPla uiNextWordLength = strlen(pNextWord); } - // Case: ... X sec(onds) ... or ... X min(utes) ... - if (pNextWord != NULL && uiNextWordLength > 2 && uiCurrentValue > 0) + // Case: ... X sec(onds) ... or ... X s ... or ... X min(utes) ... + if (pNextWord != NULL && uiCurrentValue > 0) { - if (pNextWord[0] == 's' && pNextWord[1] == 'e' && pNextWord[2] == 'c') - uiTriggerTimerLength = uiCurrentValue; - if (pNextWord[0] == 'm' && pNextWord[1] == 'i' && pNextWord[2] == 'n') - uiTriggerTimerLength = uiCurrentValue * 60; + if (uiNextWordLength == 1) + { + if (pNextWord[0] == 's') + uiTriggerTimerLength = uiCurrentValue; + } + else if (uiNextWordLength > 2) + { + if (pNextWord[0] == 's' && pNextWord[1] == 'e' && pNextWord[2] == 'c') + uiTriggerTimerLength = uiCurrentValue; + if (pNextWord[0] == 'm' && pNextWord[1] == 'i' && pNextWord[2] == 'n') + uiTriggerTimerLength = uiCurrentValue * 60; + } } // Case: ... Xs - only support up to 3 digit numbers (in seconds) for this timer parse method From 69b0dd41781f51f80524a9bcac5f19a942157e4e Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 1 Dec 2025 12:45:48 +0800 Subject: [PATCH 6/7] fix #414 nullify the damage --- src/cs2fixes.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cs2fixes.cpp b/src/cs2fixes.cpp index 10832b82..4625da83 100644 --- a/src/cs2fixes.cpp +++ b/src/cs2fixes.cpp @@ -1119,7 +1119,11 @@ bool CS2Fixes::Hook_OnTakeDamage_Alive(CTakeDamageResult* pDamageResult) CCSPlayerPawn* pPawn = META_IFACEPTR(CCSPlayerPawn); if (g_cvarEnableZR.Get() && ZR_Hook_OnTakeDamage_Alive(pDamageResult->m_pOriginatingInfo, pPawn)) + { + pDamageResult->m_bWasDamageSuppressed = true; + pDamageResult->m_nDamageDealt = 0; RETURN_META_VALUE(MRES_SUPERCEDE, false); + } // This is a shit place to be doing this, but player_death event is too late and there is no pre-hook alternative // Check if this is going to kill the player From 5cfd64c80a793ead37e9d3cb10d3cd8593efcbdb Mon Sep 17 00:00:00 2001 From: Vauff Date: Sat, 6 Dec 2025 03:06:33 -0500 Subject: [PATCH 7/7] Update SDK --- sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk b/sdk index 20ae6c37..3aa19369 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 20ae6c37f6c23551897821645a66cf8af547f6d7 +Subproject commit 3aa1936902b9730341f6f785999d51727cbcf394