//Rate Enforcer 1.0
//TigerOx
#include <sourcemod>
stock const String:RateEnforcer_Version[] = "1.0";
new g_MinRate, g_MinCmdrate, g_MinUpdaterate;
new client_rate, client_cmdrate, client_updaterate;
new config_rate, config_cmdrate, config_updaterate;
new String:g_cmdString[192], String:g_msgString[192], String:g_cmdStringMotd[192];
new bool:g_LogEnable;
//Config rates
new Handle:En_Rate = INVALID_HANDLE;
new Handle:En_CmdRate = INVALID_HANDLE;
new Handle:En_UpdateRate = INVALID_HANDLE;
new Handle:En_CheckTime = INVALID_HANDLE;
new Handle:En_Mode = INVALID_HANDLE;
new Handle:En_Log = INVALID_HANDLE;
//Main rate check timer
new Handle:g_CheckTimer = INVALID_HANDLE;
public Plugin:myinfo =
{
name = "Rate Enforcer",
author = "TigerOx",
description = "Enforces server rates on client.",
version = RateEnforcer_Version,
url = ""
}
public OnPluginStart()
{
new Handle:Version = CreateConVar("rate_enforcer", RateEnforcer_Version, "Rate Enforcer Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
SetConVarString(Version, RateEnforcer_Version);
En_Mode = CreateConVar("rate_enforcer_mode", "0", "Rate Enforcer mode - 0: Set to sv_min rates, 1: Set to Rate Enforcer default, 2: Fixed rate (check and set rates to Rate Enforcer default).", FCVAR_PLUGIN, true, 0.0, true, 2.0);
En_CheckTime = CreateConVar("rate_enforcer_time", "15", "Seconds between Rate Enforcer checks.", FCVAR_PLUGIN, true, 10.0, true, 600.0);
En_Rate = CreateConVar("rate_enforcer_rate", "30000", "Rate Enforcer default rate.", FCVAR_PLUGIN, true, 10.0, true, 100000.0);
En_CmdRate = CreateConVar("rate_enforcer_cmdrate", "100", "Rate Enforcer default cl_cmdrate.", FCVAR_PLUGIN, true, 10.0, true, 1000.0);
En_UpdateRate = CreateConVar("rate_enforcer_updaterate", "100", "Rate Enforcer default cl_updaterate.", FCVAR_PLUGIN, true, 10.0, true, 1000.0);
En_Log = CreateConVar("rate_enforcer_log", "0", "Enable logging of invalid rates.", FCVAR_PLUGIN, true, 0.0, true, 1.0);
HookConVarChange(En_Mode,ConVarChanged);
HookConVarChange(En_CheckTime,ConVarChanged);
HookConVarChange(En_Rate,ConVarChanged);
HookConVarChange(En_CmdRate,ConVarChanged);
HookConVarChange(En_UpdateRate,ConVarChanged);
HookConVarChange(En_Log,ConVarChanged);
//Save config
AutoExecConfig(true, "rate_enforcer");
}
public OnConfigsExecuted()
{
//Initial setup
config_rate = GetConVarInt(En_Rate);
config_cmdrate = GetConVarInt(En_CmdRate);
config_updaterate = GetConVarInt(En_UpdateRate);
g_LogEnable = GetConVarBool(En_Log);
ConfigEnforcer(GetConVarInt(En_Mode));
if(g_CheckTimer != INVALID_HANDLE)
KillTimer(g_CheckTimer);
g_CheckTimer = CreateTimer(GetConVarFloat(En_CheckTime),TimedRateCheck,_,TIMER_REPEAT);
}
public ConVarChanged(Handle:convar, const String:oldValue[], const String:newValue[])
{
if(convar == En_CheckTime)
{
if(g_CheckTimer != INVALID_HANDLE)
KillTimer(g_CheckTimer);
g_CheckTimer = CreateTimer(GetConVarFloat(En_CheckTime),TimedRateCheck,_,TIMER_REPEAT);
return;
}
if(convar == En_Log)
{
g_LogEnable = GetConVarBool(En_Log);
return;
}
//Reconfigure rates
if(convar == En_Rate)
config_rate = GetConVarInt(En_Rate);
if(convar == En_CmdRate)
config_cmdrate = GetConVarInt(En_CmdRate);
if(convar == En_UpdateRate)
config_updaterate = GetConVarInt(En_UpdateRate);
ConfigEnforcer(GetConVarInt(En_Mode));
}
ConfigEnforcer(mode)
{
//Enfore sv_minrate
if (mode < 2)
{
new Handle:svRate = FindConVar("sv_minrate");
new Handle:svCmdrate = FindConVar("sv_mincmdrate");
new Handle:svUpdaterate = FindConVar("sv_minupdaterate");
//Setup rates to be checked
g_MinRate = GetConVarInt(svRate);
g_MinCmdrate = GetConVarInt(svCmdrate);
g_MinUpdaterate = GetConVarInt(svUpdaterate);
//Set client rate to sv_minrate
client_rate = g_MinRate;
client_cmdrate = g_MinCmdrate;
client_updaterate = g_MinUpdaterate;
}
if(mode > 0)
{
//Set client rate to rate enforcer config rate
client_rate = config_rate;
client_cmdrate = config_cmdrate;
client_updaterate = config_updaterate;
//Enforce a fixed rate - configured
if(mode == 2)
{
g_MinRate = config_rate;
g_MinCmdrate = config_cmdrate;
g_MinUpdaterate = config_updaterate;
}
}
//Set rate string
Format(g_cmdString, sizeof(g_cmdString), "rate %d;cl_cmdrate %d;cl_updaterate %d;cl_interp 0.01;",client_rate, client_updaterate, client_cmdrate);
Format(g_cmdStringMotd, sizeof(g_cmdStringMotd), "rate %d;cl_cmdrate %d;cl_updaterate %d;cl_interp 0.01;chooseteam;",client_rate, client_updaterate, client_cmdrate);
//Set gui message for rates
Format(g_msgString, sizeof(g_msgString), "Your rates are invalid, rates have been set to server default.\n\nMinimum Rates:\nrate %d\ncl_cmdrate %d\ncl_updaterate %d", g_MinRate, g_MinUpdaterate, g_MinCmdrate);
}
EnforceRates(client)
{
new Handle:Kv = CreateKeyValues("data");
KvSetString(Kv, "title","Rate Enforcer");
KvSetString(Kv, "type", "0");
KvSetString(Kv, "msg", g_msgString);
//if enforce on connect - send team selection
if(GetClientTeam(client) > 0)
KvSetString(Kv, "cmd", g_cmdString);
else
KvSetString(Kv, "cmd", g_cmdStringMotd);
ShowVGUIPanel(client, "info", Kv);
CloseHandle(Kv);
}
CheckRates(client)
{
QueryClientConVar(client, "rate", ConVarQueryFinished:ClientConVar, client);
QueryClientConVar(client, "cl_cmdrate", ConVarQueryFinished:ClientConVar, client);
QueryClientConVar(client, "cl_updaterate", ConVarQueryFinished:ClientConVar, client);
}
public ClientConVar(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
{
new rateCheck;
if(StrEqual("rate",cvarName,false))
rateCheck = g_MinRate;
else if(StrEqual("cl_cmdrate",cvarName,false))
rateCheck = g_MinCmdrate;
else if(StrEqual("cl_updaterate",cvarName,false))
rateCheck = g_MinUpdaterate;
if(rateCheck && IsClientInGame(client) && StringToInt(cvarValue) < rateCheck)
{
EnforceRates(client);
if(g_LogEnable)
LogAction(client, -1, "%L had invalid %s, value %s", client, cvarName, cvarValue);
}
}
public Action:TimedRateCheck(Handle:Timer)
{
for(new client = 1; client <= MaxClients; client++)
{
if(IsClientInGame(client) && !IsFakeClient(client))
CheckRates(client);
}
return Plugin_Continue;
}