first adaption of perm self mute, probably fine
This commit is contained in:
parent
189e4b10e2
commit
993c311388
@ -28,8 +28,12 @@ bool g_bIsProtoBuf = false;
|
|||||||
|
|
||||||
Handle g_hCookieTorchMuted = null;
|
Handle g_hCookieTorchMuted = null;
|
||||||
|
|
||||||
#define PLUGIN_VERSION "2.4"
|
bool g_bClientMuteTempOrPerm[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
Database g_hDatabase;
|
||||||
|
|
||||||
|
#define PLUGIN_VERSION "2.5"
|
||||||
|
//may 20th 2024 jenz edit to add option for perm sm, stored in database.
|
||||||
public Plugin myinfo =
|
public Plugin myinfo =
|
||||||
{
|
{
|
||||||
name = "SelfMute",
|
name = "SelfMute",
|
||||||
@ -58,13 +62,187 @@ int g_SpecialMutes[MAXPLAYERS + 1];
|
|||||||
|
|
||||||
char g_PlayerNames[MAXPLAYERS+1][MAX_NAME_LENGTH];
|
char g_PlayerNames[MAXPLAYERS+1][MAX_NAME_LENGTH];
|
||||||
|
|
||||||
|
/*
|
||||||
|
CREATE TABLE SelfMute.unloze_selfmute (
|
||||||
|
`client_name` varchar(64) NOT NULL,
|
||||||
|
`client_steamid` varchar(32) NOT NULL,
|
||||||
|
`target_name` varchar(64) NOT NULL,
|
||||||
|
`target_steamid` varchar(32) NOT NULL,
|
||||||
|
PRIMARY KEY (`client_steamid`, `target_steamid`)
|
||||||
|
)
|
||||||
|
|
||||||
|
CREATE TABLE SelfMute.is_online (
|
||||||
|
`client_name` varchar(64) NOT NULL,
|
||||||
|
`client_steamid` varchar(32) NOT NULL,
|
||||||
|
PRIMARY KEY (`client_steamid`)
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void SQL_OnDatabaseConnect(Database db, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if(!db || strlen(error))
|
||||||
|
{
|
||||||
|
LogError("Database error: %s", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_hDatabase = db;
|
||||||
|
|
||||||
|
char sQuery[512];
|
||||||
|
Format(sQuery, sizeof(sQuery), "truncate table `is_online`");
|
||||||
|
g_hDatabase.Query(SQL_OnQueryCompletedTruncate, sQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_OnQueryCompletedTruncate(Database db, DBResultSet results, const char[] error, int iSerial)
|
||||||
|
{
|
||||||
|
if (!db || strlen(error))
|
||||||
|
{
|
||||||
|
delete results;
|
||||||
|
LogError("Query error 3: %s", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete results;
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsValidClient(i) && !IsFakeClient(i))
|
||||||
|
{
|
||||||
|
OnClientPostAdminCheck(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadClientsToPermMuteForClient(int client)
|
||||||
|
{
|
||||||
|
char csSID[64];
|
||||||
|
GetClientAuthId(client, AuthId_Steam2, csSID, sizeof(csSID));
|
||||||
|
char sQuery[512];
|
||||||
|
//limits this way to only select online clients to apply self mute for.
|
||||||
|
Format(sQuery, sizeof(sQuery), "select target_steamid from `unloze_selfmute` where client_steamid = '%s' and target_steamid in (select client_steamid from `is_online`)", csSID);
|
||||||
|
g_hDatabase.Query(SQL_GetClientsToSelfMuteForClient, sQuery, GetClientSerial(client), DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_GetClientsToSelfMuteForClient(Database db, DBResultSet results, const char[] error, int iSerial)
|
||||||
|
{
|
||||||
|
if (!db || strlen(error))
|
||||||
|
{
|
||||||
|
delete results;
|
||||||
|
LogError("Query error 3: %s", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int client;
|
||||||
|
if ((client = GetClientFromSerial(iSerial)) == 0)
|
||||||
|
{
|
||||||
|
delete results;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (results.RowCount && results.FetchRow())
|
||||||
|
{
|
||||||
|
char cSID[64];
|
||||||
|
results.FetchString(0, cSID, sizeof(cSID));
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsValidClient(i) && !IsFakeClient(i))
|
||||||
|
{
|
||||||
|
char sAuth[64];
|
||||||
|
GetClientAuthId(i, AuthId_Steam2, sAuth, sizeof(sAuth));
|
||||||
|
if (StrEqual(cSID, sAuth) && !GetIgnored(client, i))
|
||||||
|
{
|
||||||
|
Ignore(client, i);
|
||||||
|
PrintToChat(client, "Player you permanent muted connected: %N", i);
|
||||||
|
UpdateIgnored(); //no clue if it needs to update that often.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnClientPostAdminCheck(int client)
|
||||||
|
{
|
||||||
|
g_bClientMuteTempOrPerm[client] = false;
|
||||||
|
if(!IsValidClient(client) || IsFakeClient(client))
|
||||||
|
return;
|
||||||
|
if (!g_hDatabase)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsFakeClient(client))
|
||||||
|
{
|
||||||
|
insert_client_as_online(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete_client_from_online(int client)
|
||||||
|
{
|
||||||
|
char csSID[64];
|
||||||
|
GetClientAuthId(client, AuthId_Steam2, csSID, sizeof(csSID));
|
||||||
|
char sQuery[512];
|
||||||
|
Format(sQuery, sizeof(sQuery), "delete from `is_online` where client_steamid = '%s'", csSID);
|
||||||
|
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insert_client_as_online(int client)
|
||||||
|
{
|
||||||
|
char csSID[64];
|
||||||
|
GetClientAuthId(client, AuthId_Steam2, csSID, sizeof(csSID));
|
||||||
|
char sName[MAX_NAME_LENGTH];
|
||||||
|
GetClientName(client, sName, sizeof(sName));
|
||||||
|
int size2 = 2 * strlen(sName) + 1;
|
||||||
|
char[] sEscapedName = new char[size2 + 1];
|
||||||
|
g_hDatabase.Escape(sName, sEscapedName, size2 + 1);
|
||||||
|
char sQuery[512];
|
||||||
|
Format(sQuery, sizeof(sQuery), "INSERT IGNORE INTO `is_online` (`client_name`, `client_steamid`) VALUES ('%s', '%s')", sEscapedName, csSID);
|
||||||
|
g_hDatabase.Query(SQL_FinishedQueryUpdateMutes, sQuery, _, DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_FinishedQueryUpdateMutes(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if (!db || strlen(error))
|
||||||
|
{
|
||||||
|
LogError("Query error 3: %s", error);
|
||||||
|
}
|
||||||
|
delete results;
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsValidClient(i) && !IsFakeClient(i))
|
||||||
|
{
|
||||||
|
ReadClientsToPermMuteForClient(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SQL_FinishedQuery(Database db, DBResultSet results, const char[] error, any data)
|
||||||
|
{
|
||||||
|
if (!db || strlen(error))
|
||||||
|
{
|
||||||
|
LogError("Query error 3: %s", error);
|
||||||
|
}
|
||||||
|
delete results;
|
||||||
|
}
|
||||||
|
|
||||||
public void OnPluginStart()
|
public void OnPluginStart()
|
||||||
{
|
{
|
||||||
|
if (!g_hDatabase)
|
||||||
|
{
|
||||||
|
Database.Connect(SQL_OnDatabaseConnect, "SelfMute");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsValidClient(i) && !IsFakeClient(i))
|
||||||
|
{
|
||||||
|
OnClientPostAdminCheck(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
LoadTranslations("common.phrases");
|
LoadTranslations("common.phrases");
|
||||||
|
|
||||||
CreateConVar("sm_selfmute_version", PLUGIN_VERSION, "Version of Self-Mute", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
|
CreateConVar("sm_selfmute_version", PLUGIN_VERSION, "Version of Self-Mute", FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
|
||||||
|
|
||||||
RegConsoleCmd("sm_sm", Command_SelfMute, "Mute player by typing !sm [playername]");
|
RegConsoleCmd("sm_sm", Command_SelfMute, "Mute player by typing !sm [playername]");
|
||||||
|
RegConsoleCmd("sm_psm", Command_SelfMutePerm, "Mute player by typing !psm [playername] but permanently");
|
||||||
RegConsoleCmd("sm_su", Command_SelfUnMute, "Unmute player by typing !su [playername]");
|
RegConsoleCmd("sm_su", Command_SelfUnMute, "Unmute player by typing !su [playername]");
|
||||||
RegConsoleCmd("sm_cm", Command_CheckMutes, "Check who you have self-muted");
|
RegConsoleCmd("sm_cm", Command_CheckMutes, "Check who you have self-muted");
|
||||||
RegAdminCmd("sm_debugtorch", Command_CheckPermaTorchMutes, ADMFLAG_GENERIC, "Check who has permanently self-muted Torch");
|
RegAdminCmd("sm_debugtorch", Command_CheckPermaTorchMutes, ADMFLAG_GENERIC, "Check who has permanently self-muted Torch");
|
||||||
@ -144,8 +322,20 @@ public void OnClientPutInServer(int client)
|
|||||||
GetCookiesForTorch(client);
|
GetCookiesForTorch(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapEnd()
|
||||||
|
{
|
||||||
|
char sQuery[512];
|
||||||
|
Format(sQuery, sizeof(sQuery), "truncate table `is_online`");
|
||||||
|
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
public void OnClientDisconnect(int client)
|
||||||
{
|
{
|
||||||
|
g_bClientMuteTempOrPerm[client] = false;
|
||||||
|
if (!IsFakeClient(client))
|
||||||
|
{
|
||||||
|
delete_client_from_online(client);
|
||||||
|
}
|
||||||
g_SpecialMutes[client] = MUTE_NONE;
|
g_SpecialMutes[client] = MUTE_NONE;
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
for(int i = 1; i <= MaxClients; i++)
|
||||||
{
|
{
|
||||||
@ -489,11 +679,141 @@ public Action Command_CheckPermaTorchMutes(int client, int args)
|
|||||||
iPlayers++;
|
iPlayers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplyToCommand(client, "[SM] There are currently %d out of %d Players who've got Torch permanently self-muted.", iTorchPermMuted, iPlayers);
|
ReplyToCommand(client, "[SM] There are currently %d out of %d Players whove got Torch permanently self-muted.", iTorchPermMuted, iPlayers);
|
||||||
|
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Action Command_SelfMutePerm(int client, int args)
|
||||||
|
{
|
||||||
|
if(client == 0)
|
||||||
|
{
|
||||||
|
PrintToServer("[SM] Cannot use command from server console.");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
g_bClientMuteTempOrPerm[client] = true; //true for perm
|
||||||
|
|
||||||
|
if(args < 1)
|
||||||
|
{
|
||||||
|
PrintToChat(client, "\x04[Self-Mute]\x01 Permanent mutes are dangerous. You need to specify the name of the target to permanently self mute.");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char Argument[65];
|
||||||
|
GetCmdArg(1, Argument, sizeof(Argument));
|
||||||
|
|
||||||
|
char Filtered[65];
|
||||||
|
strcopy(Filtered, sizeof(Filtered), Argument);
|
||||||
|
StripQuotes(Filtered);
|
||||||
|
TrimString(Filtered);
|
||||||
|
|
||||||
|
if(MuteSpecial(client, Filtered))
|
||||||
|
return Plugin_Handled;
|
||||||
|
|
||||||
|
char sTargetName[MAX_TARGET_LENGTH];
|
||||||
|
int aTargetList[MAXPLAYERS];
|
||||||
|
int TargetCount;
|
||||||
|
bool TnIsMl;
|
||||||
|
|
||||||
|
if((TargetCount = ProcessTargetString(
|
||||||
|
Argument,
|
||||||
|
client,
|
||||||
|
aTargetList,
|
||||||
|
MAXPLAYERS,
|
||||||
|
COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_IMMUNITY,
|
||||||
|
sTargetName,
|
||||||
|
sizeof(sTargetName),
|
||||||
|
TnIsMl)) <= 0)
|
||||||
|
{
|
||||||
|
ReplyToTargetError(client, TargetCount);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(TargetCount == 1)
|
||||||
|
{
|
||||||
|
if(aTargetList[0] == client)
|
||||||
|
{
|
||||||
|
PrintToChat(client, "\x04[Self-Mute]\x01 You can't mute yourself, don't be silly.");
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IsClientSourceTV(aTargetList[0]))
|
||||||
|
{
|
||||||
|
Ignore(client, aTargetList[0]);
|
||||||
|
SetClientCookie(client, g_hCookieTorchMuted, "1");
|
||||||
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have permanently self-muted:\x04 %s", sTargetName);
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetExempt(client, aTargetList[0]))
|
||||||
|
{
|
||||||
|
UnExempt(client, aTargetList[0]);
|
||||||
|
|
||||||
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have removed exempt from self-mute:\x04 %s", sTargetName);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < TargetCount; i++)
|
||||||
|
{
|
||||||
|
if(aTargetList[i] == client)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Ignore(client, aTargetList[i]);
|
||||||
|
if (!IsFakeClient(aTargetList[i]))
|
||||||
|
{
|
||||||
|
AddClientMutingClient(client, aTargetList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateIgnored();
|
||||||
|
|
||||||
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have permanently self-muted:\x04 %s. !su can revert this decision.", sTargetName);
|
||||||
|
|
||||||
|
return Plugin_Handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddClientMutingClient(int client, int target)
|
||||||
|
{
|
||||||
|
char csSID[64];
|
||||||
|
GetClientAuthId(client, AuthId_Steam2, csSID, sizeof(csSID));
|
||||||
|
char csSIDTarget[64];
|
||||||
|
GetClientAuthId(target, AuthId_Steam2, csSIDTarget, sizeof(csSIDTarget));
|
||||||
|
|
||||||
|
char sName[MAX_NAME_LENGTH];
|
||||||
|
GetClientName(client, sName, sizeof(sName));
|
||||||
|
int size2 = 2 * strlen(sName) + 1;
|
||||||
|
char[] sEscapedName = new char[size2 + 1];
|
||||||
|
g_hDatabase.Escape(sName, sEscapedName, size2 + 1);
|
||||||
|
|
||||||
|
GetClientName(target, sName, sizeof(sName));
|
||||||
|
size2 = 2 * strlen(sName) + 1;
|
||||||
|
char[] sEscapedNameTarget = new char[size2 + 1];
|
||||||
|
g_hDatabase.Escape(sName, sEscapedNameTarget, size2 + 1);
|
||||||
|
|
||||||
|
char sQuery[512];
|
||||||
|
|
||||||
|
Format(sQuery, sizeof(sQuery), "insert ignore into `unloze_selfmute` (`client_name`, `client_steamid`, `target_name`, `target_steamid`) VALUES ('%s', '%s', '%s', '%s')", sEscapedName, csSID, sEscapedNameTarget, csSIDTarget);
|
||||||
|
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete_client_from_permMute(int client, int target)
|
||||||
|
{
|
||||||
|
if (IsFakeClient(target))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char csSID[64];
|
||||||
|
GetClientAuthId(client, AuthId_Steam2, csSID, sizeof(csSID));
|
||||||
|
|
||||||
|
char csSIDTarget[64];
|
||||||
|
GetClientAuthId(target, AuthId_Steam2, csSIDTarget, sizeof(csSIDTarget));
|
||||||
|
|
||||||
|
char sQuery[512];
|
||||||
|
Format(sQuery, sizeof(sQuery), "delete from `unloze_selfmute` where client_steamid = '%s' and target_steamid = '%s'", csSID, csSIDTarget);
|
||||||
|
g_hDatabase.Query(SQL_FinishedQuery, sQuery, _, DBPrio_Low);
|
||||||
|
}
|
||||||
|
|
||||||
public Action Command_SelfMute(int client, int args)
|
public Action Command_SelfMute(int client, int args)
|
||||||
{
|
{
|
||||||
if(client == 0)
|
if(client == 0)
|
||||||
@ -501,6 +821,7 @@ public Action Command_SelfMute(int client, int args)
|
|||||||
PrintToServer("[SM] Cannot use command from server console.");
|
PrintToServer("[SM] Cannot use command from server console.");
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
g_bClientMuteTempOrPerm[client] = false; //false for temp
|
||||||
|
|
||||||
if(args < 1)
|
if(args < 1)
|
||||||
{
|
{
|
||||||
@ -573,7 +894,7 @@ public Action Command_SelfMute(int client, int args)
|
|||||||
}
|
}
|
||||||
UpdateIgnored();
|
UpdateIgnored();
|
||||||
|
|
||||||
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted:\x04 %s", sTargetName);
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted:\x04 %s. \x01 You can use !psm <playername> for permanent self mute now.", sTargetName);
|
||||||
|
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
@ -626,7 +947,7 @@ public Action Command_SelfUnMute(int client, int args)
|
|||||||
{
|
{
|
||||||
if(aTargetList[0] == client)
|
if(aTargetList[0] == client)
|
||||||
{
|
{
|
||||||
PrintToChat(client, "\x04[Self-Mute]\x01 Unmuting won't work either.");
|
PrintToChat(client, "\x04[Self-Mute]\x01 Unmuting wont work either.");
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,6 +975,7 @@ public Action Command_SelfUnMute(int client, int args)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
UnIgnore(client, aTargetList[i]);
|
UnIgnore(client, aTargetList[i]);
|
||||||
|
delete_client_from_permMute(client, aTargetList[i]);
|
||||||
}
|
}
|
||||||
UpdateIgnored();
|
UpdateIgnored();
|
||||||
|
|
||||||
@ -867,6 +1189,7 @@ public int MenuHandler_MuteMenu(Menu menu, MenuAction action, int param1, int pa
|
|||||||
{
|
{
|
||||||
UnIgnore(param1, client);
|
UnIgnore(param1, client);
|
||||||
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %N", client);
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %N", client);
|
||||||
|
delete_client_from_permMute(param1, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(GetExempt(param1, client))
|
else if(GetExempt(param1, client))
|
||||||
@ -885,7 +1208,7 @@ public int MenuHandler_MuteMenu(Menu menu, MenuAction action, int param1, int pa
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Ignore(param1, client);
|
Ignore(param1, client);
|
||||||
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-muted:\x04 %N", client);
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-muted:\x04 %N. \x01 You can now use !psm to permanent self mute a player.", client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
||||||
@ -1108,6 +1431,7 @@ public int MenuHandler_UnMuteMenu(Menu menu, MenuAction action, int param1, int
|
|||||||
{
|
{
|
||||||
UnIgnore(param1, client);
|
UnIgnore(param1, client);
|
||||||
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %N", client);
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %N", client);
|
||||||
|
delete_client_from_permMute(param1, client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(GetExempt(param1, client))
|
else if(GetExempt(param1, client))
|
||||||
@ -1356,3 +1680,10 @@ void SetExempt(int client, int target, bool exempt)
|
|||||||
{
|
{
|
||||||
g_Exempt[client][target] = exempt;
|
g_Exempt[client][target] = exempt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stock bool IsValidClient(int client)
|
||||||
|
{
|
||||||
|
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user