diff --git a/SelectiveBhop/scripting/SelectiveBhop.sp b/SelectiveBhop/scripting/SelectiveBhop.sp index ebfb7eec..325654de 100644 --- a/SelectiveBhop/scripting/SelectiveBhop.sp +++ b/SelectiveBhop/scripting/SelectiveBhop.sp @@ -1,6 +1,7 @@ #pragma semicolon 1 #pragma newdecls required +#include #include #include #include @@ -14,12 +15,12 @@ ConVar g_CVar_zr_disablebunnyhopping; enum { - LIMITED_NONE = 0, - LIMITED_GENERAL = 1, - LIMITED_PLUGIN = 2, + LIMITED_NONE = 0, + LIMITED_GENERAL = 1, + LIMITED_PLUGIN = 2, - // Temp - LIMITED_ZOMBIE = 4 + // Temp + LIMITED_ZOMBIE = 4 } bool g_bEnabled = false; @@ -31,391 +32,418 @@ int g_ActiveLimitedFlags = LIMITED_GENERAL | LIMITED_PLUGIN; StringMap g_ClientLimitedCache; +Handle g_hCookie_BlockBhop; + public Plugin myinfo = { - name = "Selective Bunnyhop", - author = "BotoX", - description = "Disables bunnyhop on certain players/groups", - version = "0.1" + name = "Selective Bunnyhop", + author = "BotoX", + description = "Disables bunnyhop on certain players/groups", + version = "0.1" } public void OnPluginStart() { - LoadTranslations("common.phrases"); + LoadTranslations("common.phrases"); - g_CVar_sv_enablebunnyhopping = FindConVar("sv_enablebunnyhopping"); - g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_REPLICATED; - g_CVar_sv_enablebunnyhopping.AddChangeHook(OnConVarChanged); - g_bEnabled = g_CVar_sv_enablebunnyhopping.BoolValue; + g_CVar_sv_enablebunnyhopping = FindConVar("sv_enablebunnyhopping"); + g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_REPLICATED; + g_CVar_sv_enablebunnyhopping.AddChangeHook(OnConVarChanged); + g_bEnabled = g_CVar_sv_enablebunnyhopping.BoolValue; - g_CVar_zr_disablebunnyhopping = CreateConVar("zr_disablebunnyhopping", "0", "Disable bhop for zombies.", FCVAR_NOTIFY); - g_CVar_zr_disablebunnyhopping.AddChangeHook(OnConVarChanged); - g_bZombieEnabled = g_CVar_zr_disablebunnyhopping.BoolValue; + g_CVar_zr_disablebunnyhopping = CreateConVar("zr_disablebunnyhopping", "0", "Disable bhop for zombies.", FCVAR_NOTIFY); + g_CVar_zr_disablebunnyhopping.AddChangeHook(OnConVarChanged); + g_bZombieEnabled = g_CVar_zr_disablebunnyhopping.BoolValue; - g_ClientLimitedCache = new StringMap(); + g_ClientLimitedCache = new StringMap(); - HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); + g_hCookie_BlockBhop = RegClientCookie("blocking_bhop_cookie", "", CookieAccess_Private); - RegAdminCmd("sm_bhop", Command_Bhop, ADMFLAG_GENERIC, "sm_bhop <#userid|name> <0|1>"); + HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy); - RegConsoleCmd("sm_bhopstatus", Command_Status, "sm_bhopstatus [#userid|name]"); + RegAdminCmd("sm_bhop", Command_Bhop, ADMFLAG_GENERIC, "sm_bhop <#userid|name> <0|1>"); - /* Late load */ - for(int i = 1; i <= MaxClients; i++) + RegConsoleCmd("sm_bhopstatus", Command_Status, "sm_bhopstatus [#userid|name]"); + + /* Late load */ + for(int i = 1; i <= MaxClients; i++) + { + if(!IsClientInGame(i) || IsFakeClient(i)) + return; + + if(ZR_IsClientZombie(i)) + AddLimitedFlag(i, LIMITED_ZOMBIE); + if(AreClientCookiesCached(i)) + OnClientCookiesCached(i); + } + + UpdateLimitedFlags(); + UpdateClients(); +} + +public void OnClientCookiesCached(int client) +{ + char sBuffer[16]; + GetClientCookie(client, g_hCookie_BlockBhop, sBuffer, sizeof(sBuffer)); + + if (StrEqual(sBuffer, "1", false)) { - if(!IsClientInGame(i) || IsFakeClient(i)) - return; - - if(ZR_IsClientZombie(i)) - AddLimitedFlag(i, LIMITED_ZOMBIE); + AddLimitedFlag(client, LIMITED_GENERAL); + g_ClientLimited[client] = 1; } - - UpdateLimitedFlags(); - UpdateClients(); } public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { - CreateNative("LimitBhop", Native_LimitBhop); - CreateNative("IsBhopLimited", Native_IsBhopLimited); - RegPluginLibrary("SelectiveBhop"); + CreateNative("LimitBhop", Native_LimitBhop); + CreateNative("IsBhopLimited", Native_IsBhopLimited); + RegPluginLibrary("SelectiveBhop"); - return APLRes_Success; + return APLRes_Success; } public void OnPluginEnd() { - g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; - g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_REPLICATED|FCVAR_NOTIFY; + g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; + g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_REPLICATED|FCVAR_NOTIFY; - for(int i = 1; i <= MaxClients; i++) - { - if(IsClientInGame(i) && !IsFakeClient(i)) - { - if(g_CVar_sv_enablebunnyhopping.BoolValue) - g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "1"); - else - g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "0"); - } - } + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i) && !IsFakeClient(i)) + { + if(g_CVar_sv_enablebunnyhopping.BoolValue) + g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "1"); + else + g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "0"); + } + } } public void OnMapEnd() { - g_ClientLimitedCache.Clear(); + g_ClientLimitedCache.Clear(); } public void OnClientPutInServer(int client) { - TransmitConVar(client); + TransmitConVar(client); } public void OnClientDisconnect(int client) { - // Remove temp - int LimitedFlag = g_ClientLimited[client] & ~(LIMITED_ZOMBIE); + // Remove temp + int LimitedFlag = g_ClientLimited[client] & ~(LIMITED_ZOMBIE); - if(LimitedFlag != LIMITED_NONE) - { - char sSteamID[64]; - if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID))) - g_ClientLimitedCache.SetValue(sSteamID, LimitedFlag, true); - } + if(LimitedFlag != LIMITED_NONE) + { + char sSteamID[64]; + if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID))) + g_ClientLimitedCache.SetValue(sSteamID, LimitedFlag, true); + } - g_ClientLimited[client] = LIMITED_NONE; + g_ClientLimited[client] = LIMITED_NONE; } public void OnClientPostAdminCheck(int client) { - char sSteamID[64]; - if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID))) - { - int LimitedFlag; - if(g_ClientLimitedCache.GetValue(sSteamID, LimitedFlag)) - { - AddLimitedFlag(client, LimitedFlag); - g_ClientLimitedCache.Remove(sSteamID); - } - } + char sSteamID[64]; + if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID))) + { + int LimitedFlag; + if(g_ClientLimitedCache.GetValue(sSteamID, LimitedFlag)) + { + AddLimitedFlag(client, LimitedFlag); + g_ClientLimitedCache.Remove(sSteamID); + } + } } public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) { - if(convar == g_CVar_sv_enablebunnyhopping) - { - if(g_bInOnPlayerRunCmd) - return; + if(convar == g_CVar_sv_enablebunnyhopping) + { + if(g_bInOnPlayerRunCmd) + return; - g_bEnabled = convar.BoolValue; - UpdateClients(); - } - else if(convar == g_CVar_zr_disablebunnyhopping) - { - g_bZombieEnabled = convar.BoolValue; - UpdateLimitedFlags(); - } + g_bEnabled = convar.BoolValue; + UpdateClients(); + } + else if(convar == g_CVar_zr_disablebunnyhopping) + { + g_bZombieEnabled = convar.BoolValue; + UpdateLimitedFlags(); + } } public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) { - if(!g_bEnabled) - return Plugin_Continue; + if(!g_bEnabled) + return Plugin_Continue; - bool bEnableBunnyhopping = !(g_ClientLimited[client] & g_ActiveLimitedFlags); - if(bEnableBunnyhopping == g_CVar_sv_enablebunnyhopping.BoolValue) - return Plugin_Continue; + bool bEnableBunnyhopping = !(g_ClientLimited[client] & g_ActiveLimitedFlags); + if(bEnableBunnyhopping == g_CVar_sv_enablebunnyhopping.BoolValue) + return Plugin_Continue; - if(!g_bInOnPlayerRunCmd) - { - g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_NOTIFY; - g_bInOnPlayerRunCmd = true; - } + if(!g_bInOnPlayerRunCmd) + { + g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_NOTIFY; + g_bInOnPlayerRunCmd = true; + } - g_CVar_sv_enablebunnyhopping.BoolValue = bEnableBunnyhopping; + g_CVar_sv_enablebunnyhopping.BoolValue = bEnableBunnyhopping; - return Plugin_Continue; + return Plugin_Continue; } public void OnRunThinkFunctionsPost(bool simulating) { - if(g_bInOnPlayerRunCmd) - { - g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; - g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_NOTIFY; - g_bInOnPlayerRunCmd = false; - } + if(g_bInOnPlayerRunCmd) + { + g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled; + g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_NOTIFY; + g_bInOnPlayerRunCmd = false; + } } public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn) { - AddLimitedFlag(client, LIMITED_ZOMBIE); + AddLimitedFlag(client, LIMITED_ZOMBIE); } public void ZR_OnClientHumanPost(int client, bool respawn, bool protect) { - RemoveLimitedFlag(client, LIMITED_ZOMBIE); + RemoveLimitedFlag(client, LIMITED_ZOMBIE); } public void ZR_OnClientRespawned(int client, ZR_RespawnCondition condition) { - if(condition == ZR_Respawn_Human) - RemoveLimitedFlag(client, LIMITED_ZOMBIE); - else - AddLimitedFlag(client, LIMITED_ZOMBIE); + if(condition == ZR_Respawn_Human) + RemoveLimitedFlag(client, LIMITED_ZOMBIE); + else + AddLimitedFlag(client, LIMITED_ZOMBIE); } public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) { - RemoveLimitedFlag(-1, LIMITED_ZOMBIE); + RemoveLimitedFlag(-1, LIMITED_ZOMBIE); } void UpdateLimitedFlags() { - int Flags = LIMITED_GENERAL; + int Flags = LIMITED_GENERAL; - if(g_bZombieEnabled) - Flags |= LIMITED_ZOMBIE; + if(g_bZombieEnabled) + Flags |= LIMITED_ZOMBIE; - if(g_ActiveLimitedFlags != Flags) - { - g_ActiveLimitedFlags = Flags; - UpdateClients(); - } - g_ActiveLimitedFlags = Flags; + if(g_ActiveLimitedFlags != Flags) + { + g_ActiveLimitedFlags = Flags; + UpdateClients(); + } + g_ActiveLimitedFlags = Flags; } stock void AddLimitedFlag(int client, int Flag) { - if(client == -1) - { - for(int i = 1; i <= MaxClients; i++) - _AddLimitedFlag(i, Flag); - } - else - _AddLimitedFlag(client, Flag); + if(client == -1) + { + for(int i = 1; i <= MaxClients; i++) + _AddLimitedFlag(i, Flag); + } + else + _AddLimitedFlag(client, Flag); } stock void _AddLimitedFlag(int client, int Flag) { - bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); - g_ClientLimited[client] |= Flag; - bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); + bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); + g_ClientLimited[client] |= Flag; + bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); - if(bIsLimited != bWasLimited) - TransmitConVar(client); + if(bIsLimited != bWasLimited) + TransmitConVar(client); } stock void RemoveLimitedFlag(int client, int Flag) { - if(client == -1) - { - for(int i = 1; i <= MaxClients; i++) - _RemoveLimitedFlag(i, Flag); - } - else - _RemoveLimitedFlag(client, Flag); + if(client == -1) + { + for(int i = 1; i <= MaxClients; i++) + _RemoveLimitedFlag(i, Flag); + } + else + _RemoveLimitedFlag(client, Flag); } stock void _RemoveLimitedFlag(int client, int Flag) { - bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); - g_ClientLimited[client] &= ~Flag; - bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); + bool bWasLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); + g_ClientLimited[client] &= ~Flag; + bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); - if(bIsLimited != bWasLimited) - TransmitConVar(client); + if(bIsLimited != bWasLimited) + TransmitConVar(client); } stock void UpdateClients() { - for(int i = 1; i <= MaxClients; i++) - { - if(IsClientInGame(i)) - TransmitConVar(i); - } + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientInGame(i)) + TransmitConVar(i); + } } stock void TransmitConVar(int client) { - if(!IsClientInGame(client) || IsFakeClient(client)) - return; + if(!IsClientInGame(client) || IsFakeClient(client)) + return; - bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); + bool bIsLimited = view_as(g_ClientLimited[client] & g_ActiveLimitedFlags); - if(g_bEnabled && !bIsLimited) - g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "1"); - else - g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "0"); + if(g_bEnabled && !bIsLimited) + g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "1"); + else + g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "0"); } public Action Command_Bhop(int client, int argc) { - if(argc < 2) - { - ReplyToCommand(client, "[SM] Usage: sm_bhop <#userid|name> <0|1>"); - return Plugin_Handled; - } + if(argc < 2) + { + ReplyToCommand(client, "[SM] Usage: sm_bhop <#userid|name> <0|1>"); + return Plugin_Handled; + } - char sArg[64]; - char sArg2[2]; - char sTargetName[MAX_TARGET_LENGTH]; - int iTargets[MAXPLAYERS]; - int iTargetCount; - bool bIsML; - bool bValue; + char sArg[64]; + char sArg2[2]; + char sTargetName[MAX_TARGET_LENGTH]; + int iTargets[MAXPLAYERS]; + int iTargetCount; + bool bIsML; + bool bValue; - GetCmdArg(1, sArg, sizeof(sArg)); - GetCmdArg(2, sArg2, sizeof(sArg2)); + GetCmdArg(1, sArg, sizeof(sArg)); + GetCmdArg(2, sArg2, sizeof(sArg2)); - bValue = sArg2[0] == '1' ? true : false; + bValue = sArg2[0] == '1' ? true : false; - if((iTargetCount = ProcessTargetString(sArg, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sTargetName, sizeof(sTargetName), bIsML)) <= 0) - { - ReplyToTargetError(client, iTargetCount); - return Plugin_Handled; - } + if((iTargetCount = ProcessTargetString(sArg, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sTargetName, sizeof(sTargetName), bIsML)) <= 0) + { + ReplyToTargetError(client, iTargetCount); + return Plugin_Handled; + } - for(int i = 0; i < iTargetCount; i++) - { - if(bValue) - RemoveLimitedFlag(iTargets[i], LIMITED_GENERAL | LIMITED_PLUGIN); - else - AddLimitedFlag(iTargets[i], LIMITED_GENERAL); - } + char sBuffer[16]; + for(int i = 0; i < iTargetCount; i++) + { + if(bValue) + { + RemoveLimitedFlag(iTargets[i], LIMITED_GENERAL | LIMITED_PLUGIN); + Format(sBuffer, sizeof(sBuffer), "%s", "0"); + SetClientCookie(iTargets[i], g_hCookie_BlockBhop, sBuffer); + } + else + { + AddLimitedFlag(iTargets[i], LIMITED_GENERAL); + Format(sBuffer, sizeof(sBuffer), "%s", "1"); + SetClientCookie(iTargets[i], g_hCookie_BlockBhop, sBuffer); + } + } - ShowActivity2(client, "\x01[SM] \x04", "\x01\x04%s\x01 bunnyhop on target \x04%s", bValue ? "Un-limited" : "Limited", sTargetName); + ShowActivity2(client, "\x01[SM] \x04", "\x01\x04%s\x01 bunnyhop on target \x04%s", bValue ? "Un-limited" : "Limited", sTargetName); - if(iTargetCount > 1) - LogAction(client, -1, "\"%L\" %s bunnyhop on target \"%s\"", client, bValue ? "Un-limited" : "Limited", sTargetName); - else - LogAction(client, iTargets[0], "\"%L\" %s bunnyhop on target \"%L\"", client, bValue ? "Un-limited" : "Limited", iTargets[0]); + if(iTargetCount > 1) + LogAction(client, -1, "\"%L\" %s bunnyhop on target \"%s\"", client, bValue ? "Un-limited" : "Limited", sTargetName); + else + LogAction(client, iTargets[0], "\"%L\" %s bunnyhop on target \"%L\"", client, bValue ? "Un-limited" : "Limited", iTargets[0]); - return Plugin_Handled; + return Plugin_Handled; } public Action Command_Status(int client, int argc) { - if (argc && CheckCommandAccess(client, "", ADMFLAG_BAN, true)) - { - char sArgument[64]; - GetCmdArg(1, sArgument, sizeof(sArgument)); + if (argc && CheckCommandAccess(client, "", ADMFLAG_BAN, true)) + { + char sArgument[64]; + GetCmdArg(1, sArgument, sizeof(sArgument)); - int target = -1; - if((target = FindTarget(client, sArgument, true, false)) == -1) - return Plugin_Handled; + int target = -1; + if((target = FindTarget(client, sArgument, true, false)) == -1) + return Plugin_Handled; - bool bLimited = view_as(g_ClientLimited[target] & (LIMITED_GENERAL | LIMITED_PLUGIN)); + bool bLimited = view_as(g_ClientLimited[target] & (LIMITED_GENERAL | LIMITED_PLUGIN)); - if(bLimited) - { - ReplyToCommand(client, "[SM] %N their bhop is currently: limited", target); - return Plugin_Handled; - } - else - { - ReplyToCommand(client, "[SM] %N their bhop is currently: unlimited", target); - return Plugin_Handled; - } - } - else - { - bool bLimited = view_as(g_ClientLimited[client] & (LIMITED_GENERAL | LIMITED_PLUGIN)); + if(bLimited) + { + ReplyToCommand(client, "[SM] %N their bhop is currently: limited", target); + return Plugin_Handled; + } + else + { + ReplyToCommand(client, "[SM] %N their bhop is currently: unlimited", target); + return Plugin_Handled; + } + } + else + { + bool bLimited = view_as(g_ClientLimited[client] & (LIMITED_GENERAL | LIMITED_PLUGIN)); - if(bLimited) - { - ReplyToCommand(client, "[SM] your bhop is currently: limited"); - return Plugin_Handled; - } - else - { - ReplyToCommand(client, "[SM] your bhop is currently: unlimited"); - return Plugin_Handled; - } - } + if(bLimited) + { + ReplyToCommand(client, "[SM] your bhop is currently: limited"); + return Plugin_Handled; + } + else + { + ReplyToCommand(client, "[SM] your bhop is currently: unlimited"); + return Plugin_Handled; + } + } } public int Native_LimitBhop(Handle plugin, int numParams) { - int client = GetNativeCell(1); - bool bLimited = view_as(GetNativeCell(2)); + int client = GetNativeCell(1); + bool bLimited = view_as(GetNativeCell(2)); - if(client > MaxClients || client <= 0) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid."); - return -1; - } + if(client > MaxClients || client <= 0) + { + ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid."); + return -1; + } - if(!IsClientInGame(client)) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game."); - return -1; - } + if(!IsClientInGame(client)) + { + ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game."); + return -1; + } - if(bLimited) - AddLimitedFlag(client, LIMITED_PLUGIN); - else - RemoveLimitedFlag(client, LIMITED_PLUGIN); + if(bLimited) + AddLimitedFlag(client, LIMITED_PLUGIN); + else + RemoveLimitedFlag(client, LIMITED_PLUGIN); - return 0; + return 0; } public int Native_IsBhopLimited(Handle plugin, int numParams) { - int client = GetNativeCell(1); + int client = GetNativeCell(1); - if(client > MaxClients || client <= 0) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid."); - return -1; - } + if(client > MaxClients || client <= 0) + { + ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid."); + return -1; + } - if(!IsClientInGame(client)) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game."); - return -1; - } + if(!IsClientInGame(client)) + { + ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game."); + return -1; + } - int LimitedFlag = g_ClientLimited[client] & LIMITED_PLUGIN; + int LimitedFlag = g_ClientLimited[client] & LIMITED_PLUGIN; - return LimitedFlag != LIMITED_NONE; + return LimitedFlag != LIMITED_NONE; }