From 63811f41572b13570fe59766984bebb0b8b3b06a Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:24:24 +0100 Subject: [PATCH 01/10] refactor(v3): simplify notifications, translations support --- .github/workflows/ci.yml | 1 + README.md | 108 +++++++++ addons/sourcemod/scripting/BoostAlert.sp | 205 ++++++++++++------ .../translations/BoostAlert.phrases.txt | 142 ++++++++++++ 4 files changed, 391 insertions(+), 65 deletions(-) create mode 100644 README.md create mode 100644 addons/sourcemod/translations/BoostAlert.phrases.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99e65bd..e0112cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,7 @@ jobs: run: | mkdir -p /tmp/package cp -R .sourceknight/package/* /tmp/package + cp -R addons/sourcemod/translations /tmp/package/common/addons/sourcemod/ - name: Upload build archive for test runners uses: actions/upload-artifact@v4 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e725db1 --- /dev/null +++ b/README.md @@ -0,0 +1,108 @@ +# BoostAlert + +BoostAlert is a SourceMod plugin for ZombieReloaded servers that detects CT -> ZM boost patterns and knife follow-up interactions, then notifies admins with: + +- concise chat messages (localized) +- detailed console lines (localized) + +## Features + +- Detects high-impact boost hits from CT to T/ZM (shotguns/snipers). +- Detects knife hits from CT to T/ZM with configurable minimum damage. +- Detects follow-up infection/kill events after a recent knife hit. +- Detects boost-assisted infection chains in ZR. +- Sends notifications only to admins (or SourceTV). +- Logs relevant events to SourceMod logs. +- Exposes forwards for integrations with other plugins. +- Includes multilingual phrases: English, French, Spanish, Russian, Simplified Chinese. + +Optional: + +- `knifemode` (if present, alerts can be suppressed via cvar) + +## Installation + +1. Compile `addons/sourcemod/scripting/BoostAlert.sp` or download latest release. +2. Copy `BoostAlert.smx` to `addons/sourcemod/plugins/`. +3. Copy `addons/sourcemod/translations/BoostAlert.phrases.txt` to your server. +4. Restart map/server (or reload plugin). + +## Configuration (ConVars) + +### Knife + +- `sm_knifenotifytime` (default: `5`) + - Time window (seconds) where a recently knifed zombie is tracked for follow-up events. +- `sm_knifemod_blocked` (default: `1`) + - If KnifeMode is loaded: `1` blocks alerts, `0` allows alerts. +- `sm_knifemin_damage` (default: `15`) + - Minimum knife damage to trigger a knife alert. + +### Boost + +- `sm_boostalert_hitgroup` (default: `1`) + - `0` = any hitgroup, `1` = head-only (event hitgroup match). +- `sm_boostalert_spam` (default: `3`) + - Anti-spam delay before another boost warning can be sent for the same target. +- `sm_boostalert_delay` (default: `15`) + - Time window where a boosted target can still trigger follow-up infection warning. +- `sm_boostalert_min_damage` (default: `80`) + - Minimum damage to trigger boost warning. + +### Auth ID + +- `sm_boostalert_authid` (default: `1`) + - Auth ID type in detailed output: + - `0` = Engine + - `1` = Steam2 + - `2` = Steam3 + - `3` = Steam64 + +## Notifications + +### Chat + +Chat notifications are compact and intended for quick admin awareness. + +Examples: + +- `[BA] Wyatt boosted Yahn (awp, -84 HP)` +- `[BA] Wyatt infected Yahn (Recently knifed by Rushaway)` + +### Console + +Console notifications are detailed and include userid/auth details. + +Examples: + +- `[BA] Wyatt (#1390|U:1:...) boosted Yahn (#1391|U:1:...) with awp (-84 HP)` +- `[BA] Wyatt (#...) infected Yahn (#...) (Recently knifed by Rushaway (#...))` + +## Forwards + +BoostAlert exposes two global forwards: + +```pawn +BoostAlert_OnBoost(int attacker, int victim, int damage, const char[] weapon) +BoostAlert_OnBoostedKill(int attacker, int victim, int initialAttacker, int damage, const char[] weapon) +``` + +## Translation + +Translation file: + +- `addons/sourcemod/translations/BoostAlert.phrases.txt` + +Supported language keys: + +- `en` +- `fr` +- `es` +- `ru` +- `chi` (Simplified Chinese) + +## Notes + +- Boost detection weapon list is currently: `m3`, `xm1014`, `awp`, `scout`, `sg550`, `g3sg1`. +- Admin notification target is: SourceTV or users with `Admin_Generic`. +- config is Auto generated. diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index a2de8bc..36eaf2f 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -7,6 +7,8 @@ #include #include +#define BA_TAG "[BA]" + bool g_Plugin_ZR = false; bool g_bPlugin_KnifeMode = false; @@ -34,7 +36,7 @@ public Plugin myinfo = name = "Boost Notifications", description = "Notify admins when a zombie gets boosted", author = "Kelyan3, Obus + BotoX, maxime1907, .Rushaway", - version = "2.1.0", + version = "3.0.0", url = "https://github.com/srcdslab/sm-plugin-BoostAlert" }; @@ -49,6 +51,8 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max public void OnPluginStart() { + LoadTranslations("BoostAlert.phrases"); + // Knife Alert g_cvNotificationTime = CreateConVar("sm_knifenotifytime", "5", "Time before a knifed zombie is considered \"not knifed\"", 0, true, 0.0, true, 60.0); g_cvKnifeModMsgs = CreateConVar("sm_knifemod_blocked", "1", "Block Alert messages when KnifeMode library is detected [0 = Print Alert | 1 = Block Alert]"); @@ -90,9 +94,12 @@ public void OnLibraryRemoved(const char[] sName) public Action Event_PlayerHurt(Handle hEvent, const char[] name, bool dontBroadcast) { int victim = GetClientOfUserId(GetEventInt(hEvent, "userid")); - int attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker")); - if (!IsValidClient(victim) || !IsValidClient(attacker) || victim == attacker) + if (!IsValidClient(victim)) + return Plugin_Continue; + + int attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker")); + if (!IsValidClient(attacker) || victim == attacker) return Plugin_Continue; char sWepName[64]; @@ -135,8 +142,7 @@ bool IsBoostWeapon(const char[] weapon) { return (StrEqual(weapon, "m3") || StrEqual(weapon, "xm1014") // CS:S Shotguns || StrEqual(weapon, "awp") || StrEqual(weapon, "scout") // Snipers - || StrEqual(weapon, "sg550") || StrEqual(weapon, "g3sg1") // Semi-Auto Snipers - || StrEqual(weapon, "deagle")); // Pistols + || StrEqual(weapon, "sg550") || StrEqual(weapon, "g3sg1")); // Semi-Auto Snipers } void HandleKnifeAlert(int victim, int attacker, int damage) @@ -144,11 +150,12 @@ void HandleKnifeAlert(int victim, int attacker, int damage) g_iClientUserId[victim] = GetClientUserId(attacker); g_iNotificationTime[victim] = (GetTime() + g_cvNotificationTime.IntValue); - char sMessage[1024]; - Format(sMessage, sizeof(sMessage), "%L Knifed %L", attacker, victim); - LogMessage(sMessage); + LogMessage("%L Knifed %L (-%d HP)", attacker, victim, damage); - NotifyAdmins("{green}[SM] {blue}%N {default}knifed {red}%N{default}. (-%d HP)", attacker, victim, damage); + char sAttackerId[64], sVictimId[64]; + BuildUserIdString(attacker, sAttackerId, sizeof(sAttackerId)); + BuildUserIdString(victim, sVictimId, sizeof(sVictimId)); + NotifyKnifeEvent(attacker, sAttackerId, victim, sVictimId, damage); Forward_OnBoost(attacker, victim, damage, "knife"); } @@ -159,43 +166,26 @@ void HandleKnifedZombieInfection(int victim, int attacker, int damage) int pOldKnifer = GetClientOfUserId(g_iClientUserId[attacker]); if (victim != pOldKnifer) { - AuthIdType authType = view_as(GetConVarInt(g_cvAuthID)); - - char sMessage[1024], sAtkSID[64], OldKniferSteamID[64]; - GetClientAuthId(attacker, authType, sAtkSID, sizeof(sAtkSID)); - GetClientAuthId(pOldKnifer, authType, OldKniferSteamID, sizeof(OldKniferSteamID)); - - if (authType == AuthId_Steam3) - { - ReplaceString(sAtkSID, sizeof(sAtkSID), "[", ""); - ReplaceString(sAtkSID, sizeof(sAtkSID), "]", ""); - ReplaceString(OldKniferSteamID, sizeof(OldKniferSteamID), "[", ""); - ReplaceString(OldKniferSteamID, sizeof(OldKniferSteamID), "]", ""); - } - - Format(sAtkSID, sizeof(sAtkSID), "#%d|%s", GetClientUserId(attacker), sAtkSID); + char sAtkSID[64], sVictimId[64]; + BuildUserIdString(attacker, sAtkSID, sizeof(sAtkSID)); + BuildUserIdString(victim, sVictimId, sizeof(sVictimId)); if (pOldKnifer != -1) { - char sAtkAttackerName[MAX_NAME_LENGTH]; - GetClientName(pOldKnifer, sAtkAttackerName, sizeof(sAtkAttackerName)); - - Format(sMessage, sizeof(sMessage), "%L %s %L (Recently knifed by %L)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, pOldKnifer); - LogMessage(sMessage); - - CPrintToChatAll("{green}[SM]{red} %N ({lightgreen}%s{red}){default} %s{blue} %N{default}.", attacker, sAtkSID, g_Plugin_ZR ? "infected" : "killed", victim); - CPrintToChatAll("{green}[SM]{default} Knifed by{blue} %s{default}.", sAtkAttackerName); + char sOldKniferId[64]; + BuildUserIdString(pOldKnifer, sOldKniferId, sizeof(sOldKniferId)); + LogMessage("%L %s %L (Recently knifed by %L)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, pOldKnifer); + NotifyKnifeFollowupConnected(attacker, sAtkSID, victim, sVictimId, pOldKnifer, sOldKniferId, g_Plugin_ZR); Forward_OnBoostedKill(attacker, victim, pOldKnifer, damage, "knife"); } else { - Format(sMessage, sizeof(sMessage), "%L %s %L (Recently knifed by a disconnected player %s)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, OldKniferSteamID); - LogMessage(sMessage); - - CPrintToChatAll("{green}[SM]{red} %N ({lightgreen}%s{red}){green} %s{blue} %N{default}.", attacker, sAtkSID, g_Plugin_ZR ? "infected" : "killed", victim); - CPrintToChatAll("{green}[SM]{default} Knifed by a disconnected player. {lightgreen}%s", OldKniferSteamID); + char sOldKniferSteamID[64]; + BuildStoredUserIdString(g_iClientUserId[attacker], sOldKniferSteamID, sizeof(sOldKniferSteamID)); + LogMessage("%L %s %L (Recently knifed by a disconnected player %s)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, sOldKniferSteamID); + NotifyKnifeFollowupDisconnected(attacker, sAtkSID, victim, sVictimId, sOldKniferSteamID, g_Plugin_ZR); Forward_OnBoostedKill(attacker, victim, -1, damage, "knife"); } } @@ -212,7 +202,11 @@ void HandleBoostAlert(int victim, int attacker, const char[] weapon, int damage) if (time - g_cvBoostSpam.IntValue >= g_iGameTimeSpam[victim]) { g_iGameTimeSpam[victim] = time; - NotifyAdmins("{green}[SM] {blue}%N {default}boosted {red}%N{default}. ({olive}%s{default})", attacker, victim, weapon); + + char sAttackerId[64], sVictimId[64]; + BuildUserIdString(attacker, sAttackerId, sizeof(sAttackerId)); + BuildUserIdString(victim, sVictimId, sizeof(sVictimId)); + NotifyBoostEvent(attacker, sAttackerId, victim, sVictimId, weapon, damage); char sMessage[1024]; Format(sMessage, sizeof(sMessage), "%L Boosted %L (%s)", attacker, victim, weapon); @@ -242,50 +236,131 @@ public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, boo return; int time = GetTime(); - if (client != g_iAttackerIDs[attacker] && attacker == g_iDamagedIDs[attacker] - && g_iGameTimes[attacker] >= (time - g_cvBoostDelay.IntValue)) + if (client != g_iAttackerIDs[attacker] && attacker == g_iDamagedIDs[attacker] && g_iGameTimes[attacker] >= (time - g_cvBoostDelay.IntValue)) { if (IsValidClient(g_iAttackerIDs[attacker]) && IsValidClient(g_iDamagedIDs[attacker])) { - AuthIdType authType = view_as(GetConVarInt(g_cvAuthID)); + char sAttackerSteamID[64], sBoosterSteamID[64], sVictimId[64]; + BuildUserIdString(g_iDamagedIDs[attacker], sAttackerSteamID, sizeof(sAttackerSteamID)); + BuildUserIdString(g_iAttackerIDs[attacker], sBoosterSteamID, sizeof(sBoosterSteamID)); + BuildUserIdString(client, sVictimId, sizeof(sVictimId)); - char sAttackerSteamID[64], sBoosterSteamID[64]; - GetClientAuthId(g_iDamagedIDs[attacker], authType, sAttackerSteamID, sizeof(sAttackerSteamID)); - GetClientAuthId(g_iAttackerIDs[attacker], authType, sBoosterSteamID, sizeof(sBoosterSteamID)); + NotifyBoostInfectionEvent(g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); - if (authType == AuthId_Steam3) - { - ReplaceString(sAttackerSteamID, sizeof(sAttackerSteamID), "[", ""); - ReplaceString(sAttackerSteamID, sizeof(sAttackerSteamID), "]", ""); - ReplaceString(sBoosterSteamID, sizeof(sBoosterSteamID), "[", ""); - ReplaceString(sBoosterSteamID, sizeof(sBoosterSteamID), "]", ""); - } + Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); + } + } - Format(sAttackerSteamID, sizeof(sAttackerSteamID), "#%d|%s", GetClientUserId(g_iDamagedIDs[attacker]), sAttackerSteamID); - Format(sBoosterSteamID, sizeof(sBoosterSteamID), "#%d|%s", GetClientUserId(g_iAttackerIDs[attacker]), sBoosterSteamID); + LogMessage("[BA] %L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); +} - NotifyAdmins("{green}[SM] {red}%N ({lightgreen}%s{red}) {default}infected {red}%N{default}, boosted by {blue}%N ({lightgreen}%s{blue}){default}.", - g_iDamagedIDs[attacker], sAttackerSteamID, client, g_iAttackerIDs[attacker], sBoosterSteamID); +bool ShouldNotifyClient(int client) +{ + return IsValidClient(client) && (IsClientSourceTV(client) || GetAdminFlag(GetUserAdmin(client), Admin_Generic)); +} - Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); - } +void NotifyKnifeEvent(int attacker, const char[] attackerId, int victim, const char[] victimId, int damage) +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!ShouldNotifyClient(i)) + continue; + + CPrintToChat(i, "%t", "BA_Chat_Knife", BA_TAG, attacker, victim, damage); + PrintToConsole(i, "%T", "BA_Console_Knife", i, BA_TAG, attacker, attackerId, victim, victimId, damage); } } -void NotifyAdmins(const char[] format, any ...) +void NotifyBoostEvent(int attacker, const char[] attackerId, int victim, const char[] victimId, const char[] weapon, int damage) +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!ShouldNotifyClient(i)) + continue; + + CPrintToChat(i, "%t", "BA_Chat_Boost", BA_TAG, attacker, victim, weapon, damage); + PrintToConsole(i, "%T", "BA_Console_Boost", i, BA_TAG, attacker, attackerId, victim, victimId, weapon, damage); + } + + PrintToServer("%T", "BA_Console_Boost", 0, BA_TAG, attacker, attackerId, victim, victimId, weapon, damage); +} + +void NotifyKnifeFollowupConnected(int attacker, const char[] attackerId, int victim, const char[] victimId, int oldKnifer, const char[] oldKniferId, bool isInfection) { - char buffer[512]; - VFormat(buffer, sizeof(buffer), format, 2); + char chatKey[48], consoleKey[40]; + strcopy(chatKey, sizeof(chatKey), isInfection ? "BA_Chat_Knife_Followup_Infect" : "BA_Chat_Knife_Followup_Kill"); + strcopy(consoleKey, sizeof(consoleKey), isInfection ? "BA_Console_Knife_Followup_Infect" : "BA_Console_Knife_Followup_Kill"); for (int i = 1; i <= MaxClients; i++) { - if (IsValidClient(i) && (IsClientSourceTV(i) || GetAdminFlag(GetUserAdmin(i), Admin_Generic))) - { - CPrintToChat(i, buffer); - } + if (!ShouldNotifyClient(i)) + continue; + + CPrintToChat(i, "%t", chatKey, BA_TAG, attacker, victim, oldKnifer); + PrintToConsole(i, "%T", consoleKey, i, BA_TAG, attacker, attackerId, victim, victimId, oldKnifer, oldKniferId); + } +} + +void NotifyKnifeFollowupDisconnected(int attacker, const char[] attackerId, int victim, const char[] victimId, const char[] oldKniferId, bool isInfection) +{ + char chatKey[61], consoleKey[43]; + strcopy(chatKey, sizeof(chatKey), isInfection ? "BA_Chat_Knife_Followup_Infect_Disconnected" : "BA_Chat_Knife_Followup_Kill_Disconnected"); + strcopy(consoleKey, sizeof(consoleKey), isInfection ? "BA_Console_Knife_Followup_Infect_Disconnected" : "BA_Console_Knife_Followup_Kill_Disconnected"); + + for (int i = 1; i <= MaxClients; i++) + { + if (!ShouldNotifyClient(i)) + continue; + + CPrintToChat(i, "%t", chatKey, BA_TAG, attacker, victim, oldKniferId); + PrintToConsole(i, "%T", consoleKey, i, BA_TAG, attacker, attackerId, victim, victimId, oldKniferId); + } +} + +void NotifyBoostInfectionEvent(int attacker, const char[] attackerId, int victim, const char[] victimId, int booster, const char[] boosterId) +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!ShouldNotifyClient(i)) + continue; + + CPrintToChat(i, "%t", "BA_Chat_Boost_Infection", BA_TAG, attacker, victim, booster); + PrintToConsole(i, "%T", "BA_Console_Boost_Infection", i, BA_TAG, attacker, attackerId, victim, victimId, booster, boosterId); } } +void BuildUserIdString(int client, char[] buffer, int maxlen) +{ + AuthIdType authType = view_as(g_cvAuthID.IntValue); + GetClientAuthId(client, authType, buffer, maxlen, false); + + if (authType == AuthId_Steam3) + { + ReplaceString(buffer, maxlen, "[", ""); + ReplaceString(buffer, maxlen, "]", ""); + } + + Format(buffer, maxlen, "#%d|%s", GetClientUserId(client), buffer); +} + +void BuildStoredUserIdString(int userId, char[] buffer, int maxlen) +{ + if (userId <= 0) + { + strcopy(buffer, maxlen, "unknown"); + return; + } + + int client = GetClientOfUserId(userId); + if (IsValidClient(client)) + { + BuildUserIdString(client, buffer, maxlen); + return; + } + + Format(buffer, maxlen, "#%d|disconnected", userId); +} + stock bool IsValidClient(int client) { if (client <= 0 || client > MaxClients || !IsClientConnected(client)) @@ -320,4 +395,4 @@ public void KnifeMode_OnToggle(bool bEnabled) { g_bPlugin_KnifeMode = bEnabled; } -#endif +#endif \ No newline at end of file diff --git a/addons/sourcemod/translations/BoostAlert.phrases.txt b/addons/sourcemod/translations/BoostAlert.phrases.txt new file mode 100644 index 0000000..a7cf2cd --- /dev/null +++ b/addons/sourcemod/translations/BoostAlert.phrases.txt @@ -0,0 +1,142 @@ +"Phrases" +{ + "BA_Chat_Knife" + { + "#format" "{1:s},{2:N},{3:N},{4:d}" + "en" "{gold}{1} {deepskyblue}{2} {default}knifed {lightcoral}{3} {grey}(-{4} HP)" + "fr" "{gold}{1} {deepskyblue}{2} {default}a knife {lightcoral}{3} {grey}(-{4} HP)" + "es" "{gold}{1} {deepskyblue}{2} {default}acuchilló a {lightcoral}{3} {grey}(-{4} HP)" + "ru" "{gold}{1} {deepskyblue}{2} {default}ударил ножом {lightcoral}{3} {grey}(-{4} HP)" + "chi" "{gold}{1} {deepskyblue}{2} {default}刀了 {lightcoral}{3} {grey}(-{4} HP)" + } + + "BA_Console_Knife" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:d}" + "en" "{1} {2} ({3}) knifed {4} ({5}) (-{6} HP)" + "fr" "{1} {2} ({3}) a knife {4} ({5}) (-{6} HP)" + "es" "{1} {2} ({3}) acuchilló a {4} ({5}) (-{6} HP)" + "ru" "{1} {2} ({3}) ударил ножом {4} ({5}) (-{6} HP)" + "chi" "{1} {2} ({3}) 刀了 {4} ({5}) (-{6} HP)" + } + + "BA_Chat_Boost" + { + "#format" "{1:s},{2:N},{3:N},{4:s},{5:d}" + "en" "{gold}{1} {deepskyblue}{2} {default}boosted {lightcoral}{3} {grey}({4}, -{5} HP)" + "fr" "{gold}{1} {deepskyblue}{2} {default}a boost {lightcoral}{3} {grey}({4}, -{5} HP)" + "es" "{gold}{1} {deepskyblue}{2} {default}hizo boost a {lightcoral}{3} {grey}({4}, -{5} HP)" + "ru" "{gold}{1} {deepskyblue}{2} {default}сделал буст по {lightcoral}{3} {grey}({4}, -{5} HP)" + "chi" "{gold}{1} {deepskyblue}{2} {default}boost 了 {lightcoral}{3} {grey}({4}, -{5} HP)" + } + + "BA_Console_Boost" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s},{7:d}" + "en" "{1} {2} ({3}) boosted {4} ({5}) with {6} (-{7} HP)" + "fr" "{1} {2} ({3}) a boost {4} ({5}) avec {6} (-{7} HP)" + "es" "{1} {2} ({3}) hizo boost a {4} ({5}) con {6} (-{7} HP)" + "ru" "{1} {2} ({3}) сделал буст по {4} ({5}) из {6} (-{7} HP)" + "chi" "{1} {2} ({3}) 用 {6} boost 了 {4} ({5}) (-{7} HP)" + } + + "BA_Chat_Knife_Followup_Infect" + { + "#format" "{1:s},{2:N},{3:N},{4:N}" + "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" + "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" + "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" + } + + "BA_Chat_Knife_Followup_Kill" + { + "#format" "{1:s},{2:N},{3:N},{4:N}" + "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tue {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" + "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" + "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" + } + + "BA_Chat_Knife_Followup_Infect_Disconnected" + { + "#format" "{1:s},{2:N},{3:N},{4:s}" + "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" + "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" + "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" + } + + "BA_Chat_Knife_Followup_Kill_Disconnected" + { + "#format" "{1:s},{2:N},{3:N},{4:s}" + "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tue {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" + "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" + "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" + } + + "BA_Console_Knife_Followup_Infect" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" + "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by {6} ({7}))" + "fr" "{1} {2} ({3}) a infecte {4} ({5}) (Recemment knife par {6} ({7}))" + "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" + "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" + "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被 {6} ({7}) 刀过)" + } + + "BA_Console_Knife_Followup_Kill" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" + "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by {6} ({7}))" + "fr" "{1} {2} ({3}) a tue {4} ({5}) (Recemment knife par {6} ({7}))" + "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" + "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" + "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被 {6} ({7}) 刀过)" + } + + "BA_Console_Knife_Followup_Infect_Disconnected" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" + "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by a disconnected player: {6})" + "fr" "{1} {2} ({3}) a infecte {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" + "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" + "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被已离线玩家刀过:{6})" + } + + "BA_Console_Knife_Followup_Kill_Disconnected" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" + "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by a disconnected player: {6})" + "fr" "{1} {2} ({3}) a tue {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" + "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" + "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被已离线玩家刀过:{6})" + } + + "BA_Chat_Boost_Infection" + { + "#format" "{1:s},{2:N},{3:N},{4:N}" + "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(boosted by {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(boost par {deepskyblue}{4}{grey})" + "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(boost por {deepskyblue}{4}{grey})" + "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(буст от {deepskyblue}{4}{grey})" + "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(boost 来自 {deepskyblue}{4}{grey})" + } + + "BA_Console_Boost_Infection" + { + "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" + "en" "{1} {2} ({3}) infected {4} ({5}), boosted by {6} ({7})" + "fr" "{1} {2} ({3}) a infecte {4} ({5}), boost par {6} ({7})" + "es" "{1} {2} ({3}) infectó a {4} ({5}), boost por {6} ({7})" + "ru" "{1} {2} ({3}) заразил {4} ({5}), буст от {6} ({7})" + "chi" "{1} {2} ({3}) 感染了 {4} ({5}),由 {6} ({7}) 使用 boost" + } +} From 6a4cda2db4611d111dca87e281551db49fae6967 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:31:28 +0100 Subject: [PATCH 02/10] Adjust log position --- addons/sourcemod/scripting/BoostAlert.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index 36eaf2f..5370ca1 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -248,10 +248,10 @@ public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, boo NotifyBoostInfectionEvent(g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); + LogMessage("[BA] %L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); } } - LogMessage("[BA] %L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); } bool ShouldNotifyClient(int client) @@ -395,4 +395,4 @@ public void KnifeMode_OnToggle(bool bEnabled) { g_bPlugin_KnifeMode = bEnabled; } -#endif \ No newline at end of file +#endif From a40e877c0dca160471ff383bfe395c29ef5e8675 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:37:56 +0100 Subject: [PATCH 03/10] Update French translations for knife and boost phrases --- .../translations/BoostAlert.phrases.txt | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/addons/sourcemod/translations/BoostAlert.phrases.txt b/addons/sourcemod/translations/BoostAlert.phrases.txt index a7cf2cd..04477a5 100644 --- a/addons/sourcemod/translations/BoostAlert.phrases.txt +++ b/addons/sourcemod/translations/BoostAlert.phrases.txt @@ -4,7 +4,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:d}" "en" "{gold}{1} {deepskyblue}{2} {default}knifed {lightcoral}{3} {grey}(-{4} HP)" - "fr" "{gold}{1} {deepskyblue}{2} {default}a knife {lightcoral}{3} {grey}(-{4} HP)" + "fr" "{gold}{1} {deepskyblue}{2} {default}a poignardé {lightcoral}{3} {grey}(-{4} HP)" "es" "{gold}{1} {deepskyblue}{2} {default}acuchilló a {lightcoral}{3} {grey}(-{4} HP)" "ru" "{gold}{1} {deepskyblue}{2} {default}ударил ножом {lightcoral}{3} {grey}(-{4} HP)" "chi" "{gold}{1} {deepskyblue}{2} {default}刀了 {lightcoral}{3} {grey}(-{4} HP)" @@ -14,7 +14,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:d}" "en" "{1} {2} ({3}) knifed {4} ({5}) (-{6} HP)" - "fr" "{1} {2} ({3}) a knife {4} ({5}) (-{6} HP)" + "fr" "{1} {2} ({3}) a poignardé {4} ({5}) (-{6} HP)" "es" "{1} {2} ({3}) acuchilló a {4} ({5}) (-{6} HP)" "ru" "{1} {2} ({3}) ударил ножом {4} ({5}) (-{6} HP)" "chi" "{1} {2} ({3}) 刀了 {4} ({5}) (-{6} HP)" @@ -24,7 +24,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:s},{5:d}" "en" "{gold}{1} {deepskyblue}{2} {default}boosted {lightcoral}{3} {grey}({4}, -{5} HP)" - "fr" "{gold}{1} {deepskyblue}{2} {default}a boost {lightcoral}{3} {grey}({4}, -{5} HP)" + "fr" "{gold}{1} {deepskyblue}{2} {default}a boosté {lightcoral}{3} {grey}({4}, -{5} HP)" "es" "{gold}{1} {deepskyblue}{2} {default}hizo boost a {lightcoral}{3} {grey}({4}, -{5} HP)" "ru" "{gold}{1} {deepskyblue}{2} {default}сделал буст по {lightcoral}{3} {grey}({4}, -{5} HP)" "chi" "{gold}{1} {deepskyblue}{2} {default}boost 了 {lightcoral}{3} {grey}({4}, -{5} HP)" @@ -34,7 +34,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s},{7:d}" "en" "{1} {2} ({3}) boosted {4} ({5}) with {6} (-{7} HP)" - "fr" "{1} {2} ({3}) a boost {4} ({5}) avec {6} (-{7} HP)" + "fr" "{1} {2} ({3}) a boosté {4} ({5}) avec {6} (-{7} HP)" "es" "{1} {2} ({3}) hizo boost a {4} ({5}) con {6} (-{7} HP)" "ru" "{1} {2} ({3}) сделал буст по {4} ({5}) из {6} (-{7} HP)" "chi" "{1} {2} ({3}) 用 {6} boost 了 {4} ({5}) (-{7} HP)" @@ -44,7 +44,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:N}" "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" @@ -54,7 +54,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:N}" "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a tue {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" @@ -64,7 +64,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:s}" "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" @@ -74,7 +74,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:s}" "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a tue {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" @@ -84,7 +84,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by {6} ({7}))" - "fr" "{1} {2} ({3}) a infecte {4} ({5}) (Recemment knife par {6} ({7}))" + "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Recemment knife par {6} ({7}))" "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被 {6} ({7}) 刀过)" @@ -94,7 +94,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by {6} ({7}))" - "fr" "{1} {2} ({3}) a tue {4} ({5}) (Recemment knife par {6} ({7}))" + "fr" "{1} {2} ({3}) a tué {4} ({5}) (Recemment knife par {6} ({7}))" "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被 {6} ({7}) 刀过)" @@ -104,7 +104,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by a disconnected player: {6})" - "fr" "{1} {2} ({3}) a infecte {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被已离线玩家刀过:{6})" @@ -114,7 +114,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by a disconnected player: {6})" - "fr" "{1} {2} ({3}) a tue {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "fr" "{1} {2} ({3}) a tué {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被已离线玩家刀过:{6})" @@ -124,7 +124,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:N}" "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(boosted by {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a infecte {lightcoral}{3} {grey}(boost par {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(boost par {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(boost por {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(буст от {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(boost 来自 {deepskyblue}{4}{grey})" @@ -134,7 +134,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" "en" "{1} {2} ({3}) infected {4} ({5}), boosted by {6} ({7})" - "fr" "{1} {2} ({3}) a infecte {4} ({5}), boost par {6} ({7})" + "fr" "{1} {2} ({3}) a infecté {4} ({5}), boost par {6} ({7})" "es" "{1} {2} ({3}) infectó a {4} ({5}), boost por {6} ({7})" "ru" "{1} {2} ({3}) заразил {4} ({5}), буст от {6} ({7})" "chi" "{1} {2} ({3}) 感染了 {4} ({5}),由 {6} ({7}) 使用 boost" From d81eb48f0371bc9303637c6c5fa41d1a8e28b78c Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:38:19 +0100 Subject: [PATCH 04/10] Refactor BoostAlert plugin code structure --- addons/sourcemod/scripting/BoostAlert.sp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index 5370ca1..ccf423e 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -208,10 +208,7 @@ void HandleBoostAlert(int victim, int attacker, const char[] weapon, int damage) BuildUserIdString(victim, sVictimId, sizeof(sVictimId)); NotifyBoostEvent(attacker, sAttackerId, victim, sVictimId, weapon, damage); - char sMessage[1024]; - Format(sMessage, sizeof(sMessage), "%L Boosted %L (%s)", attacker, victim, weapon); - LogMessage(sMessage); - + LogMessage("%L %s %L with %s (-%d HP)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, weapon, damage); Forward_OnBoost(attacker, victim, damage, weapon); } } @@ -248,7 +245,7 @@ public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, boo NotifyBoostInfectionEvent(g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); - LogMessage("[BA] %L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); + LogMessage("%L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); } } @@ -281,8 +278,6 @@ void NotifyBoostEvent(int attacker, const char[] attackerId, int victim, const c CPrintToChat(i, "%t", "BA_Chat_Boost", BA_TAG, attacker, victim, weapon, damage); PrintToConsole(i, "%T", "BA_Console_Boost", i, BA_TAG, attacker, attackerId, victim, victimId, weapon, damage); } - - PrintToServer("%T", "BA_Console_Boost", 0, BA_TAG, attacker, attackerId, victim, victimId, weapon, damage); } void NotifyKnifeFollowupConnected(int attacker, const char[] attackerId, int victim, const char[] victimId, int oldKnifer, const char[] oldKniferId, bool isInfection) From fa3ca687864c9d8973f7b144d348f8493eec8392 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:55:25 +0100 Subject: [PATCH 05/10] README typo Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e725db1..7a2037c 100644 --- a/README.md +++ b/README.md @@ -105,4 +105,4 @@ Supported language keys: - Boost detection weapon list is currently: `m3`, `xm1014`, `awp`, `scout`, `sg550`, `g3sg1`. - Admin notification target is: SourceTV or users with `Admin_Generic`. -- config is Auto generated. +- Config is auto-generated. From a90609876ebbc8081c7328c462f4b70732601178 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:58:04 +0100 Subject: [PATCH 06/10] Refactor BoostAlert plugin for improved functionality --- addons/sourcemod/scripting/BoostAlert.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index ccf423e..a822f9c 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -208,7 +208,7 @@ void HandleBoostAlert(int victim, int attacker, const char[] weapon, int damage) BuildUserIdString(victim, sVictimId, sizeof(sVictimId)); NotifyBoostEvent(attacker, sAttackerId, victim, sVictimId, weapon, damage); - LogMessage("%L %s %L with %s (-%d HP)", attacker, g_Plugin_ZR ? "infected" : "killed", victim, weapon, damage); + LogMessage("%L boosted %L with %s (-%d HP)", attacker, victim, weapon, damage); Forward_OnBoost(attacker, victim, damage, weapon); } } From aa7dfd8b99971287350484f842ee08cd16ecd7ec Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 20:58:35 +0100 Subject: [PATCH 07/10] Fix French translations in BoostAlert phrases Updated French translations for knife follow-up messages to correct accents and phrasing. --- .../translations/BoostAlert.phrases.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/addons/sourcemod/translations/BoostAlert.phrases.txt b/addons/sourcemod/translations/BoostAlert.phrases.txt index 04477a5..92625c5 100644 --- a/addons/sourcemod/translations/BoostAlert.phrases.txt +++ b/addons/sourcemod/translations/BoostAlert.phrases.txt @@ -44,7 +44,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:N}" "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Récemment knifé par {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" @@ -54,7 +54,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:N}" "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Recemment knife par {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Récemment knifé par {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被 {deepskyblue}{4}{grey} 刀过)" @@ -64,7 +64,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:s}" "en" "{gold}{1} {deepskyblue}{2} {default}infected {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a infecté {lightcoral}{3} {grey}(Récemment knifé par un joueur déconnecté: {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}infectó a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}заразил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}感染了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" @@ -74,7 +74,7 @@ { "#format" "{1:s},{2:N},{3:N},{4:s}" "en" "{gold}{1} {deepskyblue}{2} {default}killed {lightcoral}{3} {grey}(Recently knifed by a disconnected player: {deepskyblue}{4}{grey})" - "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Recemment knife par un joueur deconnecte: {deepskyblue}{4}{grey})" + "fr" "{gold}{1} {deepskyblue}{2} {default}a tué {lightcoral}{3} {grey}(Récemment knifé par un joueur déconnecté: {deepskyblue}{4}{grey})" "es" "{gold}{1} {deepskyblue}{2} {default}mató a {lightcoral}{3} {grey}(Acuchillado recientemente por un jugador desconectado: {deepskyblue}{4}{grey})" "ru" "{gold}{1} {deepskyblue}{2} {default}убил {lightcoral}{3} {grey}(Недавно был ударен ножом отключившимся игроком: {deepskyblue}{4}{grey})" "chi" "{gold}{1} {deepskyblue}{2} {default}击杀了 {lightcoral}{3} {grey}(最近被已离线玩家刀过: {deepskyblue}{4}{grey})" @@ -84,7 +84,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by {6} ({7}))" - "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Recemment knife par {6} ({7}))" + "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Récemment knifé par {6} ({7}))" "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被 {6} ({7}) 刀过)" @@ -94,7 +94,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:N},{7:s}" "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by {6} ({7}))" - "fr" "{1} {2} ({3}) a tué {4} ({5}) (Recemment knife par {6} ({7}))" + "fr" "{1} {2} ({3}) a tué {4} ({5}) (Récemment knifé par {6} ({7}))" "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por {6} ({7}))" "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом: {6} ({7}))" "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被 {6} ({7}) 刀过)" @@ -104,7 +104,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" "en" "{1} {2} ({3}) infected {4} ({5}) (Recently knifed by a disconnected player: {6})" - "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "fr" "{1} {2} ({3}) a infecté {4} ({5}) (Récemment knifé par un joueur déconnecté: {6})" "es" "{1} {2} ({3}) infectó a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" "ru" "{1} {2} ({3}) заразил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" "chi" "{1} {2} ({3}) 感染了 {4} ({5})(最近被已离线玩家刀过:{6})" @@ -114,7 +114,7 @@ { "#format" "{1:s},{2:N},{3:s},{4:N},{5:s},{6:s}" "en" "{1} {2} ({3}) killed {4} ({5}) (Recently knifed by a disconnected player: {6})" - "fr" "{1} {2} ({3}) a tué {4} ({5}) (Recemment knife par un joueur deconnecte: {6})" + "fr" "{1} {2} ({3}) a tué {4} ({5}) (Récemment knifé par un joueur déconnecté: {6})" "es" "{1} {2} ({3}) mató a {4} ({5}) (Acuchillado recientemente por un jugador desconectado: {6})" "ru" "{1} {2} ({3}) убил {4} ({5}) (Недавно был ударен ножом отключившимся игроком: {6})" "chi" "{1} {2} ({3}) 击杀了 {4} ({5})(最近被已离线玩家刀过:{6})" From 7bb292ddcef9a610af9361b7bb6e48d0a50ff23a Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 21:07:38 +0100 Subject: [PATCH 08/10] Avoid unless check Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/sourcemod/scripting/BoostAlert.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index a822f9c..160dfa5 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -245,7 +245,7 @@ public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, boo NotifyBoostInfectionEvent(g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); - LogMessage("%L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], g_Plugin_ZR ? "infected" : "killed", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); + LogMessage("%L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], "infected", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); } } From 33b976eced471b0cb55fac02d03fe14f5d7f0bcb Mon Sep 17 00:00:00 2001 From: Rushaway Date: Mon, 16 Feb 2026 21:08:05 +0100 Subject: [PATCH 09/10] Increase buffer Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/sourcemod/scripting/BoostAlert.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index 160dfa5..ed037f5 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -298,7 +298,7 @@ void NotifyKnifeFollowupConnected(int attacker, const char[] attackerId, int vic void NotifyKnifeFollowupDisconnected(int attacker, const char[] attackerId, int victim, const char[] victimId, const char[] oldKniferId, bool isInfection) { - char chatKey[61], consoleKey[43]; + char chatKey[61], consoleKey[47]; strcopy(chatKey, sizeof(chatKey), isInfection ? "BA_Chat_Knife_Followup_Infect_Disconnected" : "BA_Chat_Knife_Followup_Kill_Disconnected"); strcopy(consoleKey, sizeof(consoleKey), isInfection ? "BA_Console_Knife_Followup_Infect_Disconnected" : "BA_Console_Knife_Followup_Kill_Disconnected"); From b98561cb33de71ac4c1652d838b546495033613d Mon Sep 17 00:00:00 2001 From: Rushaway Date: Tue, 17 Feb 2026 13:42:33 +0100 Subject: [PATCH 10/10] improved clarity --- addons/sourcemod/scripting/BoostAlert.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/BoostAlert.sp b/addons/sourcemod/scripting/BoostAlert.sp index ed037f5..274e446 100644 --- a/addons/sourcemod/scripting/BoostAlert.sp +++ b/addons/sourcemod/scripting/BoostAlert.sp @@ -245,7 +245,7 @@ public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, boo NotifyBoostInfectionEvent(g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); Forward_OnBoostedKill(g_iDamagedIDs[attacker], client, g_iAttackerIDs[attacker], 1, "zombie_claws_of_death"); - LogMessage("%L %s (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], "infected", sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); + LogMessage("%L infected (%s) infected %L (%s), boosted by %L (%s)", g_iDamagedIDs[attacker], sAttackerSteamID, client, sVictimId, g_iAttackerIDs[attacker], sBoosterSteamID); } }