From e87162368f4ae347d2401860173424876304c2ee Mon Sep 17 00:00:00 2001
From: dogan <gfldogan@gmail.com>
Date: Sun, 8 Nov 2020 15:21:06 +0100
Subject: [PATCH] intial release: KnifeBan

---
 KnifeBan/scripting/KnifeBan.sp | 503 +++++++++++++++++++++++++++++++++
 1 file changed, 503 insertions(+)
 create mode 100644 KnifeBan/scripting/KnifeBan.sp

diff --git a/KnifeBan/scripting/KnifeBan.sp b/KnifeBan/scripting/KnifeBan.sp
new file mode 100644
index 00000000..048a6565
--- /dev/null
+++ b/KnifeBan/scripting/KnifeBan.sp
@@ -0,0 +1,503 @@
+#pragma semicolon 1
+
+#include <sourcemod>
+#include <sdktools>
+#include <sdkhooks>
+#include <cstrike>
+#include <multicolors>
+#include <zombiereloaded>
+
+char g_sBanListFilePath[256];
+
+bool g_bKnifeBanned[MAXPLAYERS + 1];
+bool g_bKnifeBan;
+
+ArrayList g_TempBanned;
+
+KeyValues Banlist;
+
+int g_hActiveWeapon;
+
+public Plugin myinfo =
+{
+	name = "KnifeBan",
+	author = "Dogan",
+	description = "Tools to handle Zombie Knifers in ZE",
+	version = "1.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");
+	RegAdminCmd("sm_getrawtime", Command_Getrawtime, ADMFLAG_RCON, "Retreives the raw time of the server");
+	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("Couldn't 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);
+
+	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, length, time);
+	}
+
+	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_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 = GetTime() - time;
+
+	if(timesinceknifeban < length * 60)
+		g_bKnifeBanned[client] = true;
+	else
+	{
+		g_bKnifeBanned[client] = false;
+		Banlist.Rewind();
+
+		if(Banlist.JumpToKey(sAuth))
+		{
+			Banlist.SetNum("time", 0);
+			Banlist.SetNum("duration", 0);
+			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(!g_bKnifeBan)
+		return Plugin_Continue;
+
+	if(!g_bKnifeBanned[attacker])
+		return Plugin_Continue;
+
+	if(!ZR_IsClientZombie(victim))
+		return Plugin_Continue;
+
+	char sWeapon[32];
+	int iWeapon = GetEntDataEnt2(attacker, g_hActiveWeapon);
+	GetEdictClassname(iWeapon, sWeapon, sizeof(sWeapon));
+
+	if(!StrEqual(sWeapon, "weapon_knife"))
+		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(g_bKnifeBanned[target])
+	{
+		CReplyToCommand(client, "\x07%s[KnifeBan] \x07%sThe given client is already knifebanned.", "E01B5D", "F16767");
+		return Plugin_Handled;
+	}
+
+	g_bKnifeBanned[target] = true;
+
+	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 minutes.", "E01B5D", "EDEDED", client, "F16767", "EDEDED", target, "F16767", "EDEDED", length, "F16767");
+			LogAction(client, target, "%L knifebanned %L for %d minutes.", client, target, length);
+			int time = GetTime();
+			if(Banlist.JumpToKey(sAuth, true))
+			{
+				int history = Banlist.GetNum("history");
+				Banlist.SetNum("history", history + 1);
+				Banlist.SetNum("time", time);
+				Banlist.SetNum("duration", length);
+				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", 0);
+				Banlist.SetNum("duration", -1);
+				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.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.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_Getrawtime(int client, int args)
+{
+	int time = GetTime();
+	ReplyToCommand(client, "%d", time);
+
+	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 = GetTime() - time;
+			int iTimeRemaining = length * 60 - timesinceknifeban;
+
+			int iDays    = (iTimeRemaining / 86400);
+			int iHours   = (iTimeRemaining / 3600) % 24;
+			int iMinutes = (iTimeRemaining / 60) % 60;
+			int iSeconds = (iTimeRemaining % 60);
+
+			if (iDays)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Days %d Hours %d Minutes %d Seconds", iDays, iHours, iMinutes, iSeconds);
+			else if (iHours)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours %d Minutes %d Seconds", iHours, iMinutes, iSeconds);
+			else if (iMinutes)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Minutes %d Seconds", iMinutes, iSeconds);
+			else
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Seconds", iSeconds);
+
+			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 = GetTime() - time;
+			int iTimeRemaining = length * 60 - timesinceknifeban;
+
+
+			int iDays    = (iTimeRemaining / 86400);
+			int iHours   = (iTimeRemaining / 3600) % 24;
+			int iMinutes = (iTimeRemaining / 60) % 60;
+			int iSeconds = (iTimeRemaining % 60);
+
+			if (iDays)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Days %d Hours %d Minutes %d Seconds", iDays, iHours, iMinutes, iSeconds);
+			else if (iHours)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Hours %d Minutes %d Seconds", iHours, iMinutes, iSeconds);
+			else if (iMinutes)
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Minutes %d Seconds", iMinutes, iSeconds);
+			else
+				Format(sTimeRemaining, sizeof(sTimeRemaining), "%d Seconds", iSeconds);
+
+			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");
+
+	return Plugin_Handled;
+}
\ No newline at end of file