From 4d3d774cc0896bf4b13fe1f84b02d52f390cd96f Mon Sep 17 00:00:00 2001 From: jenz Date: Thu, 8 Jan 2026 20:28:41 +0100 Subject: [PATCH] remade so its based on ingame play time instead of real time --- KnifeBan/scripting/KnifeBan_playtime.sp | 656 ++++++++++++++++++++++++ 1 file changed, 656 insertions(+) create mode 100644 KnifeBan/scripting/KnifeBan_playtime.sp diff --git a/KnifeBan/scripting/KnifeBan_playtime.sp b/KnifeBan/scripting/KnifeBan_playtime.sp new file mode 100644 index 0000000..2be4a15 --- /dev/null +++ b/KnifeBan/scripting/KnifeBan_playtime.sp @@ -0,0 +1,656 @@ +#pragma semicolon 1 + +#include +#include +#include +#include +#include +#include + +//2026: add playtime requirements for being unrestricted +#include + +char g_sBanListFilePath[256]; + +bool g_bKnifeBanned[MAXPLAYERS + 1]; +bool g_bKnifeBan; + +ArrayList g_TempBanned; + +KeyValues Banlist; + +int g_hActiveWeapon; +int g_iClientHours[MAXPLAYERS + 1]; + +public Plugin myinfo = +{ + name = "KnifeBan", + author = "Dogan", + description = "Tools to handle Zombie Knifers in ZE", + version = "2.0.0", + url = "" +} + +public void OnPluginStart() +{ + LoadTranslations("common.phrases"); + + ConVar cvar; + HookConVarChange((cvar = CreateConVar("sm_knifeban_block", "1", "1 = Knifebanned clients are blocked, 0 = Knifebanned clients are not blocked", FCVAR_NONE, true, 0.0, true, 1.0)), g_cvKnifeBan); + g_bKnifeBan = cvar.BoolValue; + delete cvar; + + AutoExecConfig(true, "plugin.KnifeBan"); + + RegAdminCmd("sm_knifeban", Command_Knifeban, ADMFLAG_BAN, "Knifebans a client"); + RegAdminCmd("sm_knifeunban", Command_Knifeunban, ADMFLAG_BAN, "Knifeunbans a client"); + RegConsoleCmd("sm_knifestatus", Command_Knifestatus, "Returns the knifestatus of a client"); + RegConsoleCmd("sm_knifebanlist", Command_Knifebanlist, "Returns the knifebanlist of all clients currently on the server"); + + g_hActiveWeapon = FindSendPropInfo("CBaseCombatCharacter", "m_hActiveWeapon"); + if(g_hActiveWeapon == -1) + SetFailState("Couldnt find CBaseCombatCharacter::m_hActiveWeapon"); + + CreateTimer(5.0, CheckKnifeBans, _, TIMER_REPEAT); + + g_TempBanned = new ArrayList(); + + Banlist = new KeyValues("banlist"); + BuildPath(Path_SM, g_sBanListFilePath, sizeof(g_sBanListFilePath), "configs/knifeban/banlist.cfg"); + Banlist.ImportFromFile(g_sBanListFilePath); + if(!FileExists(g_sBanListFilePath)) + SetFailState("[KnifeBan] Config file missing!"); + + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i)) + OnClientPostAdminCheck(i); + } +} + +public void OnPluginEnd() +{ + Banlist.Rewind(); + if(!Banlist.ExportToFile(g_sBanListFilePath)) + SetFailState("[KnifeBan] Config file missing!"); +} + +public void g_cvKnifeBan(ConVar convar, const char[] oldValue, const char[] newValue) +{ + g_bKnifeBan = convar.BoolValue; +} + +public void OnClientPostAdminCheck(int client) +{ + SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); + + g_iClientHours[client] = 0; + char sAuth[32]; + GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth)); + + Banlist.Rewind(); + + if(Banlist.JumpToKey(sAuth)) + { + int length = Banlist.GetNum("duration"); + int time = Banlist.GetNum("time"); + + if(length == -1) + g_bKnifeBanned[client] = true; + else if(length > 0) + CheckIfClientIsStillKnifeBanned(sAuth, client, time, length); + } + + int accountid = GetSteamAccountID(client); + if(accountid != 0) + { + int index = g_TempBanned.FindValue(accountid); + if(index != -1) + g_bKnifeBanned[client] = true; + } +} + +public void OnClientDisconnect(int client) +{ + g_iClientHours[client] = 0; + g_bKnifeBanned[client] = false; +} + +public void OnMapEnd() +{ + g_TempBanned.Clear(); +} + +public Action CheckKnifeBans(Handle timer) +{ + for(int i = 1; i <= MaxClients; i++) + { + if(!IsClientInGame(i)) + continue; + + if(g_bKnifeBanned[i]) + { + char sAuth[32]; + GetClientAuthId(i, AuthId_Steam2, sAuth, sizeof(sAuth)); + + Banlist.Rewind(); + + int length; + int time; + if(Banlist.JumpToKey(sAuth)) + { + length = Banlist.GetNum("duration"); + time = Banlist.GetNum("time"); + } + + if(length > 0) + CheckIfClientIsStillKnifeBanned(sAuth, i, time, length); + } + } + + return Plugin_Continue; +} + +public void CheckIfClientIsStillKnifeBanned(char sAuth[32], int client, int time, int length) +{ + int timesinceknifeban = g_iClientHours[client] - time; + + if(timesinceknifeban < length) + g_bKnifeBanned[client] = true; + else + { + g_bKnifeBanned[client] = false; + Banlist.Rewind(); + + if(Banlist.JumpToKey(sAuth)) + { + Banlist.SetNum("time", 0); + Banlist.SetNum("duration", 0); + Banlist.SetString("admin", ""); + Banlist.Rewind(); + Banlist.ExportToFile(g_sBanListFilePath); + } + } +} + +public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) +{ + if(attacker < 1 || attacker > MaxClients) + return Plugin_Continue; + + if(!IsPlayerAlive(victim)) + return Plugin_Continue; + + if(!IsPlayerAlive(attacker)) + return Plugin_Continue; + + if(!g_bKnifeBan) + return Plugin_Continue; + + if(!g_bKnifeBanned[attacker]) + return Plugin_Continue; + + if(!ZR_IsClientZombie(victim)) + return Plugin_Continue; + + if(!ZR_IsClientHuman(attacker)) + return Plugin_Continue; + + char sWeapon[32]; + int iWeapon = GetEntDataEnt2(attacker, g_hActiveWeapon); + if(iWeapon != INVALID_ENT_REFERENCE) + GetEdictClassname(iWeapon, sWeapon, sizeof(sWeapon)); + else + return Plugin_Continue; + + if(!StrEqual(sWeapon, "weapon_knife") || damagetype & DMG_BLAST) + return Plugin_Continue; + + CPrintToChat(attacker, "\x07%s[KnifeBan] \x07%sYou are currently knifebanned.", "E01B5D", "F16767"); + damage = 0.0; + return Plugin_Handled; +} + +public Action Command_Knifeban(int client, int args) +{ + if(!GetCmdArgs()) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sUsage: sm_knifeban <#userid/name> [duration]", "E01B5D", "F16767"); + return Plugin_Handled; + } + + char sArguments[2][32]; + GetCmdArg(1, sArguments[0], sizeof(sArguments[])); + GetCmdArg(2, sArguments[1], sizeof(sArguments[])); + + int target; + if((target = FindTarget(client, sArguments[0], true)) == -1) + return Plugin_Handled; + + int length; + if(GetCmdArgs() >= 2) + { + length = StringToInt(sArguments[1]); + + if(length < 0) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sThe given knifeban duration is invalid.", "E01B5D", "F16767"); + return Plugin_Handled; + } + + if(length < 60 && length != 0) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sKnifebans are now done in hours of gametime. Minimum value is 60.", "E01B5D", "F16767"); + return Plugin_Handled; + } + if (length != 0) + { + length /= 60; + } + } + + + if(g_bKnifeBanned[target]) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sThe given client is already knifebanned.", "E01B5D", "F16767"); + return Plugin_Handled; + } + + g_bKnifeBanned[target] = true; + int time = g_iClientHours[target]; + + char sAdmin[32]; + GetClientName(client, sAdmin, sizeof(sAdmin)); + if(client == 0) + sAdmin = "Console"; + + char sAuth[32]; + GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth)); + + Banlist.Rewind(); + + if(GetCmdArgs() >= 2) + { + if(length) + { + CPrintToChatAll("\x07%s[KnifeBan] \x07%s%N\x07%s knifebanned \x07%s%N\x07%s for \x07%s%d\x07%s hours Playtime.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767", "EDEDED", length, "F16767"); + LogAction(client, target, "%L knifebanned %L for %d hours.", client, target, length); + if(Banlist.JumpToKey(sAuth, true)) + { + int history = Banlist.GetNum("history"); + Banlist.SetNum("history", history + 1); + Banlist.SetNum("time", time); + Banlist.SetNum("duration", length); + Banlist.SetString("admin", sAdmin); + Banlist.Rewind(); + Banlist.ExportToFile(g_sBanListFilePath); + } + } + else + { + CPrintToChatAll("\x07%s[KnifeBan] \x07%s%N\x07%s knifebanned \x07%s%N\x07%s permanently.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); + LogAction(client, target, "%L knifebanned %L permanently.", client, target); + if(Banlist.JumpToKey(sAuth, true)) + { + int history = Banlist.GetNum("history"); + Banlist.SetNum("history", history + 1); + Banlist.SetNum("time", time); + Banlist.SetNum("duration", -1); + Banlist.SetString("admin", sAdmin); + Banlist.Rewind(); + Banlist.ExportToFile(g_sBanListFilePath); + } + } + } + else + { + CPrintToChatAll("\x07%s[KnifeBan] \x07%s%N\x07%s knifebanned \x07%s%N\x07%s temporarily.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); + LogAction(client, target, "%L knifebanned %L temporarily.", client, target); + if(Banlist.JumpToKey(sAuth, true)) + { + int history = Banlist.GetNum("history"); + Banlist.SetNum("history", history + 1); + Banlist.SetNum("time", time); + Banlist.SetString("admin", sAdmin); + Banlist.Rewind(); + Banlist.ExportToFile(g_sBanListFilePath); + int accountid = GetSteamAccountID(target); + g_TempBanned.Push(accountid); + } + } + + return Plugin_Handled; +} + +public Action Command_Knifeunban(int client, int args) +{ + if(!GetCmdArgs()) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sUsage: sm_knifeunban <#userid/name>", "E01B5D", "F16767"); + return Plugin_Handled; + } + + char sArguments[1][32]; + GetCmdArg(1, sArguments[0], sizeof(sArguments[])); + + int target; + if((target = FindTarget(client, sArguments[0], true)) == -1) + return Plugin_Handled; + + if(!g_bKnifeBanned[target]) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sThe given client is not knifebanned.", "E01B5D", "F16767"); + return Plugin_Handled; + } + + g_bKnifeBanned[target] = false; + Banlist.Rewind(); + + char sAuth[32]; + GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth)); + + if(Banlist.JumpToKey(sAuth)) + { + int history = Banlist.GetNum("history"); + Banlist.SetNum("history", history - 1); + Banlist.SetNum("time", 0); + Banlist.SetNum("duration", 0); + Banlist.SetString("admin", ""); + Banlist.Rewind(); + Banlist.ExportToFile(g_sBanListFilePath); + } + + int accountid = GetSteamAccountID(target); + if(accountid != 0) + { + int index = g_TempBanned.FindValue(accountid); + if(index != -1) + g_TempBanned.Erase(index); + } + + CPrintToChatAll("\x07%s[KnifeBan] \x07%s%N\x07%s knifeunbanned \x07%s%N\x07%s.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767"); + LogAction(client, target, "%L knifeunbanned %L.", client, target); + + return Plugin_Handled; +} + +public Action Command_Knifestatus(int client, int args) +{ + if(CheckCommandAccess(client, "", ADMFLAG_BAN) && GetCmdArgs()) + { + char sArguments[1][32]; + GetCmdArg(1, sArguments[0], sizeof(sArguments[])); + + int target; + if((target = FindTarget(client, sArguments[0], true)) == -1) + return Plugin_Handled; + + char sAuth[32]; + GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth)); + int accountid = GetSteamAccountID(target); + int index = g_TempBanned.FindValue(accountid); + + Banlist.Rewind(); + int length; + int time; + int history; + if(Banlist.JumpToKey(sAuth)) + { + length = Banlist.GetNum("duration"); + time = Banlist.GetNum("time"); + history = Banlist.GetNum("history"); + } + + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%s%N\x07%s has been knifebanned \x07%s%d\x07%s times before.", "E01B5D", "EDEDED", target, "F16767", "EDEDED", history, "F16767"); + + if(g_bKnifeBanned[target] && index != -1) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%s%N\x07%s is currently temporarily knifebanned.", "E01B5D", "EDEDED", target, "F16767"); + return Plugin_Handled; + } + else if(g_bKnifeBanned[target] && length == -1) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%s%N\x07%s is currently permanently knifebanned.", "E01B5D", "EDEDED", target, "F16767"); + return Plugin_Handled; + } + else if(g_bKnifeBanned[target] && length > 0) + { + char sTimeRemaining[64]; + int timesinceknifeban = g_iClientHours[client] - time; + int iTimeRemaining = length - timesinceknifeban; + Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours playtime", iTimeRemaining); + + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%s%N\x07%s is currently knifebanned for another \x07%s%s\x07%s.", "E01B5D", "EDEDED", target, "F16767", "EDEDED", sTimeRemaining, "F16767"); + return Plugin_Handled; + } + else + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%s%N\x07%s is currently not knifebanned.", "E01B5D", "EDEDED", target, "F16767"); + return Plugin_Handled; + } + } + else + { + char sAuth[32]; + GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth)); + int accountid = GetSteamAccountID(client); + int index = g_TempBanned.FindValue(accountid); + + Banlist.Rewind(); + int length; + int time; + if(Banlist.JumpToKey(sAuth)) + { + length = Banlist.GetNum("duration"); + time = Banlist.GetNum("time"); + } + + if(g_bKnifeBanned[client] && index != -1) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sYou are currently temporarily knifebanned.", "E01B5D", "F16767"); + return Plugin_Handled; + } + else if(g_bKnifeBanned[client] && length == -1) + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sYou are currently permanently knifebanned.", "E01B5D", "F16767"); + return Plugin_Handled; + } + else if (g_bKnifeBanned[client] && length > 0) + { + char sTimeRemaining[64]; + int timesinceknifeban = g_iClientHours[client] - time; + int iTimeRemaining = length - timesinceknifeban; + + Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours playtime", iTimeRemaining); + + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sYou are currently knifebanned for another \x07%s%s\x07%s.", "E01B5D", "F16767", "EDEDED", sTimeRemaining, "F16767"); + return Plugin_Handled; + } + else + { + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sYou are currently not knifebanned.", "E01B5D", "F16767"); + return Plugin_Handled; + } + } +} + +public Action Command_Knifebanlist(int client, int args) +{ + char aBuf[1024]; + char aBuf2[MAX_NAME_LENGTH]; + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + if(g_bKnifeBanned[i]) + { + GetClientName(i, aBuf2, sizeof(aBuf2)); + StrCat(aBuf, sizeof(aBuf), aBuf2); + StrCat(aBuf, sizeof(aBuf), ", "); + } + } + } + + if(strlen(aBuf)) + { + aBuf[strlen(aBuf) - 2] = 0; + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sCurrently knifebanned clients: \x07%s%s", "E01B5D", "F16767", "EDEDED", aBuf); + } + else + CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sCurrently knifebanned clients: \x07%snone", "E01B5D", "F16767", "EDEDED"); + + if(CheckCommandAccess(client, "", ADMFLAG_BAN)) + OpenKnifebanlistMenu(client); + + return Plugin_Handled; +} + +public void OpenKnifebanlistMenu(int client) +{ + if(client == 0) + return; + + Menu menu = new Menu(MenuHandler_MainMenu); + + menu.SetTitle("Currently knifebanned clients:", client); + + char sBuffer[32]; + int iMenuItem; + char sMenuItem[8]; + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + if(g_bKnifeBanned[i]) + { + GetClientName(i, sBuffer, sizeof(sBuffer)); + IntToString(iMenuItem, sMenuItem, sizeof(sMenuItem)); + menu.AddItem(sMenuItem, sBuffer); + iMenuItem++; + } + } + } + + menu.Display(client, MENU_TIME_FOREVER); +} + +public void MenuHandler_MainMenu(Menu menu, MenuAction action, int client, int selection) +{ + switch(action) + { + case(MenuAction_Select): + { + char sMenuItem[8]; + char sBuffer[32]; + int flag; + menu.GetItem(selection, sMenuItem, sizeof(sMenuItem), flag, sBuffer, sizeof(sBuffer)); + OpenKnifebanlistOfTheClient(client, sBuffer); + } + case(MenuAction_End): + { + delete menu; + } + } +} + +public void OpenKnifebanlistOfTheClient(int client, char sBuffer[32]) +{ + Menu menuclient = new Menu(MenuHandler_ClientMenu); + + char sTitle[64] = "Knifebanned client: "; + + StrCat(sTitle, sizeof(sTitle), sBuffer); + + int target; + char sName[32]; + + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i) && g_bKnifeBanned[i]) + { + GetClientName(i, sName, sizeof(sName)); + + if(StrEqual(sName, sBuffer)) + { + target = i; + break; + } + } + } + + char sAuth[32]; + GetClientAuthId(target, AuthId_Steam2, sAuth, sizeof(sAuth)); + + Banlist.Rewind(); + + int length; + int time; + int history; + char sAdmin[32]; + if(Banlist.JumpToKey(sAuth)) + { + length = Banlist.GetNum("duration"); + time = Banlist.GetNum("time"); + history = Banlist.GetNum("history"); + Banlist.GetString("admin", sAdmin, sizeof(sAdmin)); + } + + menuclient.SetTitle(sTitle, client); + + char sInfo[256]; + Format(sInfo, sizeof(sInfo), "Banned by: %s", sAdmin); + + menuclient.AddItem("0", sInfo); + + if(length > 0) + Format(sInfo, sizeof(sInfo), "Duration: %d Hours playtime", length); + else if(length == -1) + Format(sInfo, sizeof(sInfo), "Duration: Permanently"); + else + Format(sInfo, sizeof(sInfo), "Duration: Temporarly"); + + menuclient.AddItem("1", sInfo); + + char sTime[32]; + FormatTime(sTime, sizeof(sTime), "%c", time); + Format(sInfo, sizeof(sInfo), "Date: %s", sTime); + + menuclient.AddItem("2", sInfo); + + Format(sInfo, sizeof(sInfo), "Ban History: %d times", history); + + menuclient.AddItem("3", sInfo); + + menuclient.AddItem("4", "Back to List"); + + menuclient.Display(client, MENU_TIME_FOREVER); +} + +public void MenuHandler_ClientMenu(Menu menuclient, MenuAction action, int client, int selection) +{ + switch(action) + { + case(MenuAction_Select): + { + switch(selection) + { + case(4): OpenKnifebanlistMenu(client); + } + } + case(MenuAction_End): + { + delete menuclient; + } + } +} + +//---------------------------------------------------------------------------------------------------- +// Purpose: 2026 getting the ingame play time of the players. called with OnClientPostAdminCheck() forward and timer every 10 minutes +//---------------------------------------------------------------------------------------------------- +public void GetPlayerHoursServer(int client, int hours) +{ + g_iClientHours[client] = hours; +}