Skip to content

Commit

Permalink
Merge branch 'SirPlease:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
altair-sossai authored Jul 23, 2024
2 parents f48eeee + 9ce8280 commit 5b18c99
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 108 deletions.
Binary file modified addons/sourcemod/plugins/optional/specrates.smx
Binary file not shown.
45 changes: 45 additions & 0 deletions addons/sourcemod/scripting/include/specrates.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#if defined _specrates_included
#endinput
#endif
#define _specrates_included

enum StatusRates
{
RatesLimit = 0,
RatesFree = 1,
}

/**
* Sets the status rates for a specific client.
*
* @param client The client index.
* @param Status The status rates to set.
*/
native void SetStatusRates(int client, StatusRates Status);

/**
* Retrieves the status rates for a given client.
*
* @param client The client index.
* @return The StatusRates structure containing the status rates.
*/
native StatusRates GetStatusRates(int client);

public SharedPlugin __pl_specrates =
{
name = "specrates",
file = "specrates.smx",
#if defined REQUIRE_PLUGIN
required = 1,
#else
required = 0,
#endif
};

#if !defined REQUIRE_PLUGIN
public void __pl_specrates_SetNTVOptional()
{
MarkNativeAsOptional("SetStatusRates");
MarkNativeAsOptional("GetStatusRates");
}
#endif
281 changes: 173 additions & 108 deletions addons/sourcemod/scripting/specrates.sp
Original file line number Diff line number Diff line change
@@ -1,167 +1,232 @@
#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <sdktools>

#undef REQUIRE_PLUGIN
#include <caster_system>
#define REQUIRE_PLUGIN

enum L4D2Team
enum L4DTeam
{
L4D2Team_None = 0,
L4D2Team_Spectator,
L4D2Team_Survivor,
L4D2Team_Infected
};

new bool:readyUpIsAvailable;
new Handle:sv_mincmdrate;
new Handle:sv_maxcmdrate;
new Handle:sv_minupdaterate;
new Handle:sv_maxupdaterate;
new Handle:sv_minrate;
new Handle:sv_maxrate;
new Handle:sv_client_min_interp_ratio;
new Handle:sv_client_max_interp_ratio;

new String:netvars[8][8];
L4DTeam_Unassigned = 0,
L4DTeam_Spectator = 1,
L4DTeam_Survivor = 2,
L4DTeam_Infected = 3
}

new Float:fLastAdjusted[MAXPLAYERS + 1];
enum StatusRates
{
RatesLimit = 0,
RatesFree = 1,
}

public Plugin:myinfo =
enum struct Player
{
name = "Lightweight Spectating",
author = "Visor",
description = "Forces low rates on spectators",
version = "1.2.1",
url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
float LastAdjusted;
StatusRates Status;
}

bool
g_bCasterSystem,
g_bLateload;

ConVar
sv_mincmdrate,
sv_maxcmdrate,
sv_minupdaterate,
sv_maxupdaterate,
sv_minrate,
sv_maxrate,
sv_client_min_interp_ratio,
sv_client_max_interp_ratio;

char
g_sNetVars[8][8];

Player
g_Players[MAXPLAYERS + 1];

public Plugin myinfo =
{
name = "Lightweight Spectating",
author = "Visor, lechuga",
description = "Forces low rates on spectators",
version = "1.3",
url = "https://github.com/SirPlease/L4D2-Competitive-Rework"
};

public OnPluginStart()
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
sv_mincmdrate = FindConVar("sv_mincmdrate");
sv_maxcmdrate = FindConVar("sv_maxcmdrate");
sv_minupdaterate = FindConVar("sv_minupdaterate");
sv_maxupdaterate = FindConVar("sv_maxupdaterate");
sv_minrate = FindConVar("sv_minrate");
sv_maxrate = FindConVar("sv_maxrate");
sv_client_min_interp_ratio = FindConVar("sv_client_min_interp_ratio");
sv_client_max_interp_ratio = FindConVar("sv_client_max_interp_ratio");
CreateNative("SetStatusRates", Native_SetStatusRates);
CreateNative("GetStatusRates", Native_GetStatusRates);

HookEvent("player_team", OnTeamChange);
g_bLateload = late;
RegPluginLibrary("specrates");
return APLRes_Success;
}

public OnPluginEnd()
public void OnAllPluginsLoaded()
{
SetConVarString(sv_minupdaterate, netvars[2]);
SetConVarString(sv_mincmdrate, netvars[0]);
g_bCasterSystem = LibraryExists("caster_system");
}

public OnAllPluginsLoaded()
public void OnLibraryRemoved(const char[] name)
{
readyUpIsAvailable = LibraryExists("caster_system");
if (StrEqual(name, "caster_system", true))
g_bCasterSystem = false;
}

public OnLibraryRemoved(const String:name[])
public void OnLibraryAdded(const char[] name)
{
if (StrEqual(name, "caster_system", true))
{
readyUpIsAvailable = false;
}
if (StrEqual(name, "caster_system", true))
g_bCasterSystem = true;
}

public OnLibraryAdded(const String:name[])
public void OnPluginStart()
{
if (StrEqual(name, "caster_system", true))
{
readyUpIsAvailable = true;
}
sv_mincmdrate = FindConVar("sv_mincmdrate");
sv_maxcmdrate = FindConVar("sv_maxcmdrate");
sv_minupdaterate = FindConVar("sv_minupdaterate");
sv_maxupdaterate = FindConVar("sv_maxupdaterate");
sv_minrate = FindConVar("sv_minrate");
sv_maxrate = FindConVar("sv_maxrate");
sv_client_min_interp_ratio = FindConVar("sv_client_min_interp_ratio");
sv_client_max_interp_ratio = FindConVar("sv_client_max_interp_ratio");

HookEvent("player_team", OnTeamChange);

if (!g_bLateload)
return;

g_bCasterSystem = LibraryExists("caster_system");
}

public OnConfigsExecuted()
public void OnPluginEnd()
{
GetConVarString(sv_mincmdrate, netvars[0], 8);
GetConVarString(sv_maxcmdrate, netvars[1], 8);
GetConVarString(sv_minupdaterate, netvars[2], 8);
GetConVarString(sv_maxupdaterate, netvars[3], 8);
GetConVarString(sv_minrate, netvars[4], 8);
GetConVarString(sv_maxrate, netvars[5], 8);
GetConVarString(sv_client_min_interp_ratio, netvars[6], 8);
GetConVarString(sv_client_max_interp_ratio, netvars[7], 8);

SetConVarInt(sv_minupdaterate, 30);
SetConVarInt(sv_mincmdrate, 30);
sv_minupdaterate.SetString(g_sNetVars[2]);
sv_mincmdrate.SetString(g_sNetVars[0]);
}

public OnClientPutInServer(client)
public void OnConfigsExecuted()
{
fLastAdjusted[client] = 0.0;
sv_mincmdrate.GetString(g_sNetVars[0], 8);
sv_maxcmdrate.GetString(g_sNetVars[1], 8);
sv_minupdaterate.GetString(g_sNetVars[2], 8);
sv_maxupdaterate.GetString(g_sNetVars[3], 8);
sv_minrate.GetString(g_sNetVars[4], 8);
sv_maxrate.GetString(g_sNetVars[5], 8);
sv_client_min_interp_ratio.GetString(g_sNetVars[6], 8);
sv_client_max_interp_ratio.GetString(g_sNetVars[7], 8);

sv_minupdaterate.SetInt(30);
sv_mincmdrate.SetInt(30);
}

void OnTeamChange(Handle:event, String:name[], bool:dontBroadcast)
public void OnClientPutInServer(int client)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
CreateTimer(10.0, TimerAdjustRates, client, TIMER_FLAG_NO_MAPCHANGE);
g_Players[client].LastAdjusted = 0.0;
g_Players[client].Status = RatesLimit;
}

Action:TimerAdjustRates(Handle:timer, any:client)
void OnTeamChange(Event event, const char[] name, bool dontBroadcast)
{
AdjustRates(client);
return Plugin_Handled;
int client = GetClientOfUserId(event.GetInt("userid"));
CreateTimer(10.0, TimerAdjustRates, client, TIMER_FLAG_NO_MAPCHANGE);
}

public OnClientSettingsChanged(client)
Action TimerAdjustRates(Handle timer, any client)
{
AdjustRates(client);
AdjustRates(client);
return Plugin_Handled;
}

AdjustRates(client)
public void OnClientSettingsChanged(int client)
{
if (!IsValidClient(client))
return;
AdjustRates(client);
}

if (fLastAdjusted[client] < GetEngineTime() - 1.0)
{
fLastAdjusted[client] = GetEngineTime();
void AdjustRates(int client)
{
if (!IsValidClient(client))
return;

if (g_Players[client].LastAdjusted < GetEngineTime() - 1.0)
{
g_Players[client].LastAdjusted = GetEngineTime();

L4DTeam team = L4D_GetClientTeam(client);
if (team == L4DTeam_Survivor || team == L4DTeam_Infected || (g_bCasterSystem && IsClientCaster(client)))
ResetRates(client);
else if (team == L4DTeam_Spectator)
{
if (g_Players[client].Status == RatesLimit)
SetSpectatorRates(client);
else
ResetRates(client);
}
}
}

void SetSpectatorRates(int client)
{
sv_mincmdrate.ReplicateToClient(client, "30");
sv_maxcmdrate.ReplicateToClient(client, "30");
sv_minupdaterate.ReplicateToClient(client, "30");
sv_maxupdaterate.ReplicateToClient(client, "30");
sv_minrate.ReplicateToClient(client, "10000");
sv_maxrate.ReplicateToClient(client, "10000");

new L4D2Team:team = L4D2Team:GetClientTeam(client);
if (team == L4D2Team_Survivor || team == L4D2Team_Infected || (readyUpIsAvailable && IsClientCaster(client)))
{
ResetRates(client);
}
else if (team == L4D2Team_Spectator)
{
SetSpectatorRates(client);
}
}
SetClientInfo(client, "cl_updaterate", "30");
SetClientInfo(client, "cl_cmdrate", "30");
}

SetSpectatorRates(client)
void ResetRates(int client)
{
SendConVarValue(client, sv_mincmdrate, "30");
SendConVarValue(client, sv_maxcmdrate, "30");
SendConVarValue(client, sv_minupdaterate, "30");
SendConVarValue(client, sv_maxupdaterate, "30");
SendConVarValue(client, sv_minrate, "10000");
SendConVarValue(client, sv_maxrate, "10000");
sv_mincmdrate.ReplicateToClient(client, g_sNetVars[0]);
sv_maxcmdrate.ReplicateToClient(client, g_sNetVars[1]);
sv_minupdaterate.ReplicateToClient(client, g_sNetVars[2]);
sv_maxupdaterate.ReplicateToClient(client, g_sNetVars[3]);
sv_minrate.ReplicateToClient(client, g_sNetVars[4]);
sv_maxrate.ReplicateToClient(client, g_sNetVars[5]);

SetClientInfo(client, "cl_updaterate", "30");
SetClientInfo(client, "cl_cmdrate", "30");
SetClientInfo(client, "cl_updaterate", g_sNetVars[3]);
SetClientInfo(client, "cl_cmdrate", g_sNetVars[1]);
}

ResetRates(client)
// void SetStatusRates(int client, StatusRates Status);
int Native_SetStatusRates(Handle plugin, int numParams)
{
SendConVarValue(client, sv_mincmdrate, netvars[0]);
SendConVarValue(client, sv_maxcmdrate, netvars[1]);
SendConVarValue(client, sv_minupdaterate, netvars[2]);
SendConVarValue(client, sv_maxupdaterate, netvars[3]);
SendConVarValue(client, sv_minrate, netvars[4]);
SendConVarValue(client, sv_maxrate, netvars[5]);
int client = GetNativeCell(1);
StatusRates status = view_as<StatusRates>(GetNativeCell(2));

SetClientInfo(client, "cl_updaterate", netvars[3]);
SetClientInfo(client, "cl_cmdrate", netvars[1]);
g_Players[client].Status = status;
AdjustRates(client);
return 0;
}

bool:IsValidClient(client)
// StatusRates GetStatusRates(int client);
any Native_GetStatusRates(Handle plugin, int numParams)
{
return client > 0 && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client);
int client = GetNativeCell(1);
return g_Players[client].Status;
}

bool IsValidClient(int client)
{
return client > 0 && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client);
}

/**
* Returns the clients team using L4DTeam.
*
* @param client Player's index.
* @return Current L4DTeam of player.
* @error Invalid client index.
*/
stock L4DTeam L4D_GetClientTeam(int client)
{
int team = GetClientTeam(client);
return view_as<L4DTeam>(team);
}
Loading

0 comments on commit 5b18c99

Please sign in to comment.