1683 lines
47 KiB
SourcePawn
1683 lines
47 KiB
SourcePawn
#pragma semicolon 1
|
|
|
|
#include <sourcemod>
|
|
#include <sdktools>
|
|
#include <adminmenu>
|
|
#include <cstrike>
|
|
#include <clientprefs>
|
|
|
|
#undef REQUIRE_PLUGIN
|
|
#include <ccc>
|
|
#include <zombiereloaded>
|
|
#tryinclude <voiceannounce_ex>
|
|
#include <AdvancedTargeting>
|
|
#define REQUIRE_PLUGIN
|
|
|
|
#undef REQUIRE_EXTENSIONS
|
|
#tryinclude <voice>
|
|
#define REQUIRE_EXTENSIONS
|
|
|
|
#pragma newdecls required
|
|
|
|
bool g_Plugin_ccc = false;
|
|
bool g_Plugin_zombiereloaded = false;
|
|
bool g_Plugin_voiceannounce_ex = false;
|
|
bool g_Plugin_AdvancedTargeting = false;
|
|
bool g_Extension_Voice = false;
|
|
bool g_bIsProtoBuf = false;
|
|
|
|
Handle g_hCookieTorchMuted = null;
|
|
|
|
|
|
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 =
|
|
{
|
|
name = "SelfMute",
|
|
author = "BotoX",
|
|
description = "Ignore other players in text and voicechat.",
|
|
version = PLUGIN_VERSION,
|
|
url = ""
|
|
};
|
|
|
|
enum
|
|
{
|
|
MUTE_NONE = 0,
|
|
MUTE_SPEC = 1,
|
|
MUTE_CT = 2,
|
|
MUTE_T = 4,
|
|
MUTE_DEAD = 8,
|
|
MUTE_ALIVE = 16,
|
|
MUTE_NOTFRIENDS = 32,
|
|
MUTE_ALL = 64,
|
|
MUTE_LAST = 64
|
|
};
|
|
|
|
bool g_Ignored[(MAXPLAYERS + 1) * (MAXPLAYERS + 1)];
|
|
bool g_Exempt[MAXPLAYERS + 1][MAXPLAYERS + 1];
|
|
int g_SpecialMutes[MAXPLAYERS + 1];
|
|
|
|
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_High);
|
|
}
|
|
|
|
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))
|
|
{
|
|
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)
|
|
{
|
|
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_High);
|
|
}
|
|
|
|
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()
|
|
{
|
|
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");
|
|
|
|
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_psm", Command_SelfMutePerm, "Mute player by typing !psm [playername] but permanently");
|
|
RegConsoleCmd("sm_su", Command_SelfUnMute, "Unmute player by typing !su [playername]");
|
|
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");
|
|
|
|
HookEvent("round_start", Event_Round);
|
|
HookEvent("round_end", Event_Round);
|
|
HookEvent("player_team", Event_TeamChange);
|
|
|
|
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
|
|
g_bIsProtoBuf = true;
|
|
|
|
UserMsg RadioText = GetUserMessageId("RadioText");
|
|
if(RadioText == INVALID_MESSAGE_ID)
|
|
SetFailState("This game doesn't support RadioText user messages.");
|
|
|
|
HookUserMessage(RadioText, Hook_UserMessageRadioText, true);
|
|
|
|
UserMsg SendAudio = GetUserMessageId("SendAudio");
|
|
if(SendAudio == INVALID_MESSAGE_ID)
|
|
SetFailState("This game doesn't support SendAudio user messages.");
|
|
|
|
HookUserMessage(SendAudio, Hook_UserMessageSendAudio, true);
|
|
|
|
g_hCookieTorchMuted = RegClientCookie("torch_muted", "is torch muted", CookieAccess_Protected);
|
|
}
|
|
|
|
public void OnAllPluginsLoaded()
|
|
{
|
|
g_Plugin_ccc = LibraryExists("ccc");
|
|
g_Plugin_zombiereloaded = LibraryExists("zombiereloaded");
|
|
g_Plugin_voiceannounce_ex = LibraryExists("voiceannounce_ex");
|
|
g_Plugin_AdvancedTargeting = LibraryExists("AdvancedTargeting");
|
|
g_Extension_Voice = LibraryExists("Voice");
|
|
|
|
LogMessage("SelfMute capabilities:\nProtoBuf: %s\nCCC: %s\nZombieReloaded: %s\nVoiceAnnounce: %s\nAdvancedTargeting: %s\nVoice: %s",
|
|
(g_bIsProtoBuf ? "yes" : "no"),
|
|
(g_Plugin_ccc ? "loaded" : "not loaded"),
|
|
(g_Plugin_zombiereloaded ? "loaded" : "not loaded"),
|
|
(g_Plugin_voiceannounce_ex ? "loaded" : "not loaded"),
|
|
(g_Plugin_AdvancedTargeting ? "loaded" : "not loaded"),
|
|
(g_Extension_Voice ? "loaded" : "not loaded"));
|
|
}
|
|
|
|
void OnLibrary(const char[] name, bool added)
|
|
{
|
|
if(StrEqual(name, "ccc"))
|
|
g_Plugin_ccc = added;
|
|
else if(StrEqual(name, "zombiereloaded"))
|
|
g_Plugin_zombiereloaded = added;
|
|
else if(StrEqual(name, "voiceannounce_ex"))
|
|
g_Plugin_voiceannounce_ex = added;
|
|
else if(StrEqual(name, "AdvancedTargeting"))
|
|
g_Plugin_AdvancedTargeting = added;
|
|
else if(StrEqual(name, "Voice"))
|
|
g_Extension_Voice = added;
|
|
|
|
}
|
|
|
|
public void OnLibraryAdded(const char[] name) { OnLibrary(name, true); }
|
|
public void OnLibraryRemoved(const char[] name) { OnLibrary(name, false); }
|
|
|
|
public void OnClientPutInServer(int client)
|
|
{
|
|
g_SpecialMutes[client] = MUTE_NONE;
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
SetIgnored(client, i, false);
|
|
SetExempt(client, i, false);
|
|
|
|
SetIgnored(i, client, false);
|
|
SetExempt(i, client, false);
|
|
}
|
|
|
|
UpdateSpecialMutesOtherClients(client);
|
|
UpdateIgnored();
|
|
|
|
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)
|
|
{
|
|
if (!IsFakeClient(client))
|
|
{
|
|
delete_client_from_online(client);
|
|
}
|
|
g_SpecialMutes[client] = MUTE_NONE;
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
SetIgnored(client, i, false);
|
|
SetExempt(client, i, false);
|
|
|
|
SetIgnored(i, client, false);
|
|
SetExempt(i, client, false);
|
|
|
|
if(IsClientInGame(i) && i != client)
|
|
SetListenOverride(i, client, Listen_Yes);
|
|
}
|
|
|
|
UpdateIgnored();
|
|
}
|
|
|
|
public void GetCookiesForTorch(int client)
|
|
{
|
|
char sBuffer[2];
|
|
|
|
GetClientCookie(client, g_hCookieTorchMuted, sBuffer, sizeof(sBuffer));
|
|
if(sBuffer[0] != '\0')
|
|
{
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(IsClientInGame(i) && IsClientSourceTV(i))
|
|
Ignore(client, i);
|
|
}
|
|
}
|
|
|
|
UpdateIgnored();
|
|
}
|
|
|
|
public void Event_Round(Handle event, const char[] name, bool dontBroadcast)
|
|
{
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(IsClientInGame(i))
|
|
UpdateSpecialMutesThisClient(i);
|
|
}
|
|
}
|
|
|
|
public void Event_TeamChange(Handle event, const char[] name, bool dontBroadcast)
|
|
{
|
|
int client = GetClientOfUserId(GetEventInt(event, "userid"));
|
|
|
|
UpdateSpecialMutesOtherClients(client);
|
|
}
|
|
|
|
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
{
|
|
UpdateSpecialMutesOtherClients(client);
|
|
}
|
|
|
|
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
|
{
|
|
UpdateSpecialMutesOtherClients(client);
|
|
}
|
|
|
|
/*
|
|
* Mutes this client on other players
|
|
*/
|
|
void UpdateSpecialMutesOtherClients(int client)
|
|
{
|
|
bool Alive = IsPlayerAlive(client);
|
|
int Team = GetClientTeam(client);
|
|
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(i == client || !IsClientInGame(i))
|
|
continue;
|
|
|
|
int Flags = MUTE_NONE;
|
|
|
|
if(g_SpecialMutes[i] & MUTE_SPEC && Team == CS_TEAM_SPECTATOR)
|
|
Flags |= MUTE_SPEC;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_CT && Alive &&
|
|
((g_Plugin_zombiereloaded && ZR_IsClientHuman(client)) || (!g_Plugin_zombiereloaded && Team == CS_TEAM_CT)))
|
|
Flags |= MUTE_CT;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_T && Alive &&
|
|
((g_Plugin_zombiereloaded && ZR_IsClientZombie(client)) || (!g_Plugin_zombiereloaded && Team == CS_TEAM_T)))
|
|
Flags |= MUTE_T;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_DEAD && !Alive)
|
|
Flags |= MUTE_DEAD;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_ALIVE && Alive)
|
|
Flags |= MUTE_ALIVE;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_NOTFRIENDS &&
|
|
g_Plugin_AdvancedTargeting && IsClientFriend(i, client) == 0)
|
|
Flags |= MUTE_NOTFRIENDS;
|
|
|
|
else if(g_SpecialMutes[i] & MUTE_ALL)
|
|
Flags |= MUTE_ALL;
|
|
|
|
if(Flags && !GetExempt(i, client))
|
|
SetListenOverride(i, client, Listen_No);
|
|
else if(!GetIgnored(i, client))
|
|
SetListenOverride(i, client, Listen_Yes);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Mutes other players on this client
|
|
*/
|
|
void UpdateSpecialMutesThisClient(int client)
|
|
{
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(i == client || !IsClientInGame(i))
|
|
continue;
|
|
|
|
bool Alive = IsPlayerAlive(i);
|
|
int Team = GetClientTeam(i);
|
|
|
|
int Flags = MUTE_NONE;
|
|
|
|
if(g_SpecialMutes[client] & MUTE_SPEC && Team == CS_TEAM_SPECTATOR)
|
|
Flags |= MUTE_SPEC;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_CT && Alive &&
|
|
((g_Plugin_zombiereloaded && ZR_IsClientHuman(i) || (!g_Plugin_zombiereloaded) && Team == CS_TEAM_CT)))
|
|
Flags |= MUTE_CT;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_T && Alive &&
|
|
((g_Plugin_zombiereloaded && ZR_IsClientZombie(i) || (!g_Plugin_zombiereloaded) && Team == CS_TEAM_T)))
|
|
Flags |= MUTE_T;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_DEAD && !Alive)
|
|
Flags |= MUTE_DEAD;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_ALIVE && Alive)
|
|
Flags |= MUTE_ALIVE;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_NOTFRIENDS &&
|
|
g_Plugin_AdvancedTargeting && IsClientFriend(client, i) == 0)
|
|
Flags |= MUTE_NOTFRIENDS;
|
|
|
|
else if(g_SpecialMutes[client] & MUTE_ALL)
|
|
Flags |= MUTE_ALL;
|
|
|
|
if(Flags && !GetExempt(client, i))
|
|
SetListenOverride(client, i, Listen_No);
|
|
else if(!GetIgnored(client, i))
|
|
SetListenOverride(client, i, Listen_Yes);
|
|
}
|
|
}
|
|
|
|
int GetSpecialMutesFlags(char[] Argument)
|
|
{
|
|
int SpecialMute = MUTE_NONE;
|
|
if(StrEqual(Argument, "@spec", false) || StrEqual(Argument, "@!ct", false) || StrEqual(Argument, "@!t", false))
|
|
SpecialMute |= MUTE_SPEC;
|
|
if(StrEqual(Argument, "@ct", false) || StrEqual(Argument, "@!t", false) || StrEqual(Argument, "@!spec", false))
|
|
SpecialMute |= MUTE_CT;
|
|
if(StrEqual(Argument, "@t", false) || StrEqual(Argument, "@!ct", false) || StrEqual(Argument, "@!spec", false))
|
|
SpecialMute |= MUTE_T;
|
|
if(StrEqual(Argument, "@dead", false) || StrEqual(Argument, "@!alive", false))
|
|
SpecialMute |= MUTE_DEAD;
|
|
if(StrEqual(Argument, "@alive", false) || StrEqual(Argument, "@!dead", false))
|
|
SpecialMute |= MUTE_ALIVE;
|
|
if(g_Plugin_AdvancedTargeting && StrEqual(Argument, "@!friends", false))
|
|
SpecialMute |= MUTE_NOTFRIENDS;
|
|
if(StrEqual(Argument, "@all", false))
|
|
SpecialMute |= MUTE_ALL;
|
|
|
|
return SpecialMute;
|
|
}
|
|
|
|
void FormatSpecialMutes(int SpecialMute, char[] aBuf, int BufLen)
|
|
{
|
|
if(!SpecialMute)
|
|
{
|
|
StrCat(aBuf, BufLen, "none");
|
|
return;
|
|
}
|
|
|
|
bool Status = false;
|
|
if(SpecialMute & MUTE_ALL)
|
|
{
|
|
StrCat(aBuf, BufLen, "Everyone, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_SPEC)
|
|
{
|
|
StrCat(aBuf, BufLen, "Spectators, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_CT)
|
|
{
|
|
StrCat(aBuf, BufLen, "Counter-Terrorists, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_T)
|
|
{
|
|
StrCat(aBuf, BufLen, "Terrorists, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_DEAD)
|
|
{
|
|
StrCat(aBuf, BufLen, "Dead players, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_ALIVE)
|
|
{
|
|
StrCat(aBuf, BufLen, "Alive players, ");
|
|
Status = true;
|
|
}
|
|
if(SpecialMute & MUTE_NOTFRIENDS)
|
|
{
|
|
StrCat(aBuf, BufLen, "Not Steam friends, ");
|
|
Status = true;
|
|
}
|
|
|
|
// Cut off last ', '
|
|
if(Status)
|
|
aBuf[strlen(aBuf) - 2] = 0;
|
|
}
|
|
|
|
bool MuteSpecial(int client, char[] Argument)
|
|
{
|
|
bool RetValue = false;
|
|
int SpecialMute = GetSpecialMutesFlags(Argument);
|
|
|
|
if(SpecialMute & MUTE_NOTFRIENDS && g_Plugin_AdvancedTargeting && ReadClientFriends(client) != 1)
|
|
{
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 Could not read your friendslist, your profile must be set to public!");
|
|
SpecialMute &= ~MUTE_NOTFRIENDS;
|
|
RetValue = true;
|
|
}
|
|
|
|
if(SpecialMute)
|
|
{
|
|
if(SpecialMute & MUTE_ALL || g_SpecialMutes[client] & MUTE_ALL)
|
|
{
|
|
g_SpecialMutes[client] = MUTE_ALL;
|
|
SpecialMute = MUTE_ALL;
|
|
}
|
|
else
|
|
g_SpecialMutes[client] |= SpecialMute;
|
|
|
|
UpdateSpecialMutesThisClient(client);
|
|
|
|
char aBuf[128];
|
|
FormatSpecialMutes(SpecialMute, aBuf, sizeof(aBuf));
|
|
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted group:\x04 %s", aBuf);
|
|
RetValue = true;
|
|
}
|
|
|
|
return RetValue;
|
|
}
|
|
|
|
bool UnMuteSpecial(int client, char[] Argument)
|
|
{
|
|
int SpecialMute = GetSpecialMutesFlags(Argument);
|
|
|
|
if(SpecialMute)
|
|
{
|
|
if(SpecialMute & MUTE_ALL)
|
|
{
|
|
if(g_SpecialMutes[client])
|
|
{
|
|
SpecialMute = g_SpecialMutes[client];
|
|
g_SpecialMutes[client] = MUTE_NONE;
|
|
}
|
|
else
|
|
{
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(IsClientInGame(i) && !IsClientSourceTV(i))
|
|
UnIgnore(client, i);
|
|
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 all players");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
g_SpecialMutes[client] &= ~SpecialMute;
|
|
|
|
UpdateSpecialMutesThisClient(client);
|
|
|
|
char aBuf[256];
|
|
FormatSpecialMutes(SpecialMute, aBuf, sizeof(aBuf));
|
|
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted group:\x04 %s", aBuf);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Ignore(int client, int target)
|
|
{
|
|
SetIgnored(client, target, true);
|
|
SetListenOverride(client, target, Listen_No);
|
|
}
|
|
|
|
void UnIgnore(int client, int target)
|
|
{
|
|
SetIgnored(client, target, false);
|
|
SetListenOverride(client, target, Listen_Yes);
|
|
}
|
|
|
|
void Exempt(int client, int target)
|
|
{
|
|
SetExempt(client, target, true);
|
|
UpdateSpecialMutesThisClient(client);
|
|
}
|
|
|
|
void UnExempt(int client, int target)
|
|
{
|
|
SetExempt(client, target, false);
|
|
UpdateSpecialMutesThisClient(client);
|
|
}
|
|
|
|
/*
|
|
* CHAT COMMANDS
|
|
*/
|
|
|
|
public Action Command_CheckPermaTorchMutes(int client, int args)
|
|
{
|
|
int iTorchPermMuted;
|
|
int iPlayers;
|
|
char sBuffer[2];
|
|
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(!IsClientInGame(i) || IsFakeClient(i))
|
|
continue;
|
|
|
|
GetClientCookie(i, g_hCookieTorchMuted, sBuffer, sizeof(sBuffer));
|
|
|
|
if(sBuffer[0] != '\0')
|
|
iTorchPermMuted++;
|
|
|
|
iPlayers++;
|
|
}
|
|
|
|
ReplyToCommand(client, "[SM] There are currently %d out of %d Players whove got Torch permanently self-muted.", iTorchPermMuted, iPlayers);
|
|
|
|
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;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if(client == 0)
|
|
{
|
|
PrintToServer("[SM] Cannot use command from server console.");
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
if(args < 1)
|
|
{
|
|
DisplayMuteMenu(client);
|
|
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]);
|
|
}
|
|
UpdateIgnored();
|
|
|
|
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;
|
|
}
|
|
|
|
public Action Command_SelfUnMute(int client, int args)
|
|
{
|
|
if(client == 0)
|
|
{
|
|
PrintToServer("[SM] Cannot use command from server console.");
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
if(args < 1)
|
|
{
|
|
DisplayUnMuteMenu(client);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
char Argument[65];
|
|
GetCmdArg(1, Argument, sizeof(Argument));
|
|
|
|
char Filtered[65];
|
|
strcopy(Filtered, sizeof(Filtered), Argument);
|
|
StripQuotes(Filtered);
|
|
TrimString(Filtered);
|
|
|
|
if(UnMuteSpecial(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 Unmuting wont work either.");
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
if(IsClientSourceTV(aTargetList[0]))
|
|
{
|
|
UnIgnore(client, aTargetList[0]);
|
|
SetClientCookie(client, g_hCookieTorchMuted, "");
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have permanently self-unmuted:\x04 %s", sTargetName);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
if(!GetIgnored(client, aTargetList[0]))
|
|
{
|
|
Exempt(client, aTargetList[0]);
|
|
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have exempted from self-mute:\x04 %s", sTargetName);
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
}
|
|
|
|
for(int i = 0; i < TargetCount; i++)
|
|
{
|
|
if(aTargetList[i] == client)
|
|
continue;
|
|
|
|
UnIgnore(client, aTargetList[i]);
|
|
delete_client_from_permMute(client, aTargetList[i]);
|
|
}
|
|
UpdateIgnored();
|
|
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-unmuted:\x04 %s", sTargetName);
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public Action Command_CheckMutes(int client, int args)
|
|
{
|
|
if(client == 0)
|
|
{
|
|
PrintToServer("[SM] Cannot use command from server console.");
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
char aMuted[1024];
|
|
char aExempted[1024];
|
|
char aName[MAX_NAME_LENGTH];
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(!IsClientInGame(i))
|
|
continue;
|
|
|
|
GetClientName(i, aName, sizeof(aName));
|
|
|
|
if(GetIgnored(client, i))
|
|
{
|
|
StrCat(aMuted, sizeof(aMuted), aName);
|
|
StrCat(aMuted, sizeof(aMuted), ", ");
|
|
}
|
|
|
|
if(GetExempt(client, i))
|
|
{
|
|
StrCat(aExempted, sizeof(aExempted), aName);
|
|
StrCat(aExempted, sizeof(aExempted), ", ");
|
|
}
|
|
}
|
|
|
|
if(strlen(aMuted))
|
|
{
|
|
aMuted[strlen(aMuted) - 2] = 0;
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted:\x04 %s", aMuted);
|
|
}
|
|
|
|
if(g_SpecialMutes[client] != MUTE_NONE)
|
|
{
|
|
aMuted[0] = 0;
|
|
FormatSpecialMutes(g_SpecialMutes[client], aMuted, sizeof(aMuted));
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have self-muted group:\x04 %s", aMuted);
|
|
}
|
|
else if(!strlen(aMuted) && !strlen(aExempted))
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have not self-muted anyone!");
|
|
|
|
if(strlen(aExempted))
|
|
{
|
|
aExempted[strlen(aExempted) - 2] = 0;
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You have exempted from self-mute:\x04 %s", aExempted);
|
|
}
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
stock bool _IsClientSpeaking(int client)
|
|
{
|
|
#if defined _voiceannounceex_included_
|
|
if(g_Plugin_voiceannounce_ex)
|
|
return IsClientSpeaking(client);
|
|
#endif
|
|
|
|
#if defined _voice_included
|
|
if(g_Extension_Voice)
|
|
return IsClientTalking(client);
|
|
#endif
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* MENU
|
|
*/
|
|
void DisplayMuteMenu(int client)
|
|
{
|
|
Menu menu = new Menu(MenuHandler_MuteMenu, MenuAction_Select|MenuAction_Cancel|MenuAction_End|MenuAction_DrawItem|MenuAction_DisplayItem);
|
|
menu.ExitButton = true;
|
|
|
|
int[] aClients = new int[MaxClients + 1];
|
|
|
|
{
|
|
// Count talking players and insert id's into aClients array
|
|
int CurrentlyTalking = 0;
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(i != client && IsClientInGame(i) && _IsClientSpeaking(i))
|
|
aClients[CurrentlyTalking++] = i;
|
|
}
|
|
|
|
if(CurrentlyTalking > 0)
|
|
{
|
|
// insert player names into g_PlayerNames array
|
|
for(int i = 0; i < CurrentlyTalking; i++)
|
|
GetClientName(aClients[i], g_PlayerNames[aClients[i]], sizeof(g_PlayerNames[]));
|
|
|
|
// sort aClients array by player name
|
|
SortCustom1D(aClients, CurrentlyTalking, SortByPlayerName);
|
|
|
|
// insert players sorted
|
|
char aBuf[12];
|
|
for(int i = 0; i < CurrentlyTalking; i++)
|
|
{
|
|
IntToString(GetClientUserId(aClients[i]), aBuf, sizeof(aBuf));
|
|
menu.AddItem(aBuf, g_PlayerNames[aClients[i]]);
|
|
}
|
|
|
|
// insert spacers
|
|
int Entries = 7 - CurrentlyTalking % 7;
|
|
while(Entries--)
|
|
menu.AddItem("", "", ITEMDRAW_RAWLINE);
|
|
}
|
|
}
|
|
|
|
menu.AddItem("@all", "Everyone");
|
|
menu.AddItem("@spec", "Spectators");
|
|
menu.AddItem("@ct", "Counter-Terrorists");
|
|
menu.AddItem("@t", "Terrorists");
|
|
menu.AddItem("@dead", "Dead players");
|
|
menu.AddItem("@alive", "Alive players");
|
|
if(g_Plugin_AdvancedTargeting)
|
|
menu.AddItem("@!friends", "Not Steam friends");
|
|
else
|
|
menu.AddItem("", "", ITEMDRAW_RAWLINE);
|
|
|
|
// Count valid players and insert id's into aClients array
|
|
int Players = 0;
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(i != client && IsClientInGame(i))
|
|
aClients[Players++] = i;
|
|
}
|
|
|
|
// insert player names into g_PlayerNames array
|
|
for(int i = 0; i < Players; i++)
|
|
GetClientName(aClients[i], g_PlayerNames[aClients[i]], sizeof(g_PlayerNames[]));
|
|
|
|
// sort aClients array by player name
|
|
SortCustom1D(aClients, Players, SortByPlayerName);
|
|
|
|
// insert players sorted
|
|
char aBuf[12];
|
|
for(int i = 0; i < Players; i++)
|
|
{
|
|
IntToString(GetClientUserId(aClients[i]), aBuf, sizeof(aBuf));
|
|
menu.AddItem(aBuf, g_PlayerNames[aClients[i]]);
|
|
}
|
|
|
|
menu.Display(client, MENU_TIME_FOREVER);
|
|
}
|
|
|
|
public int MenuHandler_MuteMenu(Menu menu, MenuAction action, int param1, int param2)
|
|
{
|
|
switch(action)
|
|
{
|
|
case MenuAction_End:
|
|
{
|
|
if(param1 != MenuEnd_Selected)
|
|
CloseHandle(menu);
|
|
}
|
|
case MenuAction_Select:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
char aDisp[MAX_NAME_LENGTH + 4];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
|
|
|
if(Style != ITEMDRAW_DEFAULT || !aItem[0])
|
|
{
|
|
PrintToChat(param1, "Internal error: aItem[0] -> %d | Style -> %d", aItem[0], Style);
|
|
return 0;
|
|
}
|
|
|
|
if(aItem[0] == '@')
|
|
{
|
|
int Flag = GetSpecialMutesFlags(aItem);
|
|
if(Flag && g_SpecialMutes[param1] & Flag)
|
|
UnMuteSpecial(param1, aItem);
|
|
else
|
|
MuteSpecial(param1, aItem);
|
|
|
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
|
return 0;
|
|
}
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client)
|
|
{
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 Player no longer available.");
|
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
|
return 0;
|
|
}
|
|
|
|
if(GetIgnored(param1, client))
|
|
{
|
|
if(IsClientSourceTV(client))
|
|
{
|
|
UnIgnore(param1, client);
|
|
SetClientCookie(param1, g_hCookieTorchMuted, "");
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have permanently self-unmuted:\x04 %N", client);
|
|
}
|
|
else
|
|
{
|
|
UnIgnore(param1, 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))
|
|
{
|
|
UnExempt(param1, client);
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have removed exempt from self-mute:\x04 %N", client);
|
|
}
|
|
else
|
|
{
|
|
if(IsClientSourceTV(client))
|
|
{
|
|
Ignore(param1, client);
|
|
SetClientCookie(param1, g_hCookieTorchMuted, "1");
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have permanently self-muted:\x04 %N", client);
|
|
}
|
|
else
|
|
{
|
|
Ignore(param1, 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);
|
|
return 0;
|
|
}
|
|
case MenuAction_DrawItem:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style);
|
|
|
|
if(!aItem[0])
|
|
return ITEMDRAW_DISABLED;
|
|
|
|
if(aItem[0] == '@')
|
|
{
|
|
int Flag = GetSpecialMutesFlags(aItem);
|
|
if(Flag & MUTE_ALL)
|
|
return Style;
|
|
else if(g_SpecialMutes[param1] & MUTE_ALL)
|
|
return ITEMDRAW_DISABLED;
|
|
|
|
return Style;
|
|
}
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client) // Player disconnected
|
|
return ITEMDRAW_DISABLED;
|
|
|
|
return Style;
|
|
}
|
|
case MenuAction_DisplayItem:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
char aDisp[MAX_NAME_LENGTH + 4];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
|
|
|
// Start of current page
|
|
if((param2 + 1) % 7 == 1)
|
|
{
|
|
if(aItem[0] == '@')
|
|
menu.SetTitle("[Self-Mute] Groups");
|
|
else if(param2 == 0)
|
|
menu.SetTitle("[Self-Mute] Talking players");
|
|
else
|
|
menu.SetTitle("[Self-Mute] All players");
|
|
}
|
|
|
|
if(!aItem[0])
|
|
return 0;
|
|
|
|
if(aItem[0] == '@')
|
|
{
|
|
int Flag = GetSpecialMutesFlags(aItem);
|
|
if(Flag && g_SpecialMutes[param1] & Flag)
|
|
{
|
|
char aBuf[32] = "[M] ";
|
|
FormatSpecialMutes(Flag, aBuf, sizeof(aBuf));
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client) // Player disconnected
|
|
{
|
|
char aBuf[MAX_NAME_LENGTH + 4] = "[D] ";
|
|
StrCat(aBuf, sizeof(aBuf), aDisp);
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
|
|
if(GetIgnored(param1, client))
|
|
{
|
|
char aBuf[MAX_NAME_LENGTH + 4] = "[M] ";
|
|
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
|
StrCat(aBuf, sizeof(aBuf), g_PlayerNames[client]);
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
else if(GetExempt(param1, client))
|
|
{
|
|
char aBuf[MAX_NAME_LENGTH + 4] = "[E] ";
|
|
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
|
StrCat(aBuf, sizeof(aBuf), g_PlayerNames[client]);
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
else
|
|
{
|
|
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
|
if(!StrEqual(aDisp, g_PlayerNames[client]))
|
|
return RedrawMenuItem(g_PlayerNames[client]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void DisplayUnMuteMenu(int client)
|
|
{
|
|
Menu menu = new Menu(MenuHandler_UnMuteMenu, MenuAction_Select|MenuAction_Cancel|MenuAction_End|MenuAction_DrawItem|MenuAction_DisplayItem);
|
|
menu.SetTitle("[Self-UnMute]");
|
|
menu.ExitButton = true;
|
|
|
|
if(g_SpecialMutes[client] & MUTE_ALL)
|
|
menu.AddItem("@all", "Everyone");
|
|
if(g_SpecialMutes[client] & MUTE_SPEC)
|
|
menu.AddItem("@spec", "Spectators");
|
|
if(g_SpecialMutes[client] & MUTE_CT)
|
|
menu.AddItem("@ct", "Counter-Terrorists");
|
|
if(g_SpecialMutes[client] & MUTE_T)
|
|
menu.AddItem("@t", "Terrorists");
|
|
if(g_SpecialMutes[client] & MUTE_DEAD)
|
|
menu.AddItem("@dead", "Dead players");
|
|
if(g_SpecialMutes[client] & MUTE_ALIVE)
|
|
menu.AddItem("@alive", "Alive players");
|
|
if(g_SpecialMutes[client] & MUTE_NOTFRIENDS)
|
|
menu.AddItem("@!friends", "Not Steam friends");
|
|
if(g_SpecialMutes[client])
|
|
menu.AddItem("", "", ITEMDRAW_RAWLINE);
|
|
|
|
int[] aClients = new int[MaxClients + 1];
|
|
|
|
// Count valid players and insert id's into aClients array
|
|
int Players = 0;
|
|
for(int i = 1; i <= MaxClients; i++)
|
|
{
|
|
if(i != client && IsClientInGame(i) && (GetIgnored(client, i) || GetExempt(client, i)))
|
|
aClients[Players++] = i;
|
|
}
|
|
|
|
// insert player names into g_PlayerNames array
|
|
for(int i = 0; i < Players; i++)
|
|
{
|
|
GetClientName(aClients[i], g_PlayerNames[aClients[i]], sizeof(g_PlayerNames[]));
|
|
}
|
|
|
|
// sort aClients array by player name
|
|
SortCustom1D(aClients, Players, SortByPlayerName);
|
|
|
|
// insert players sorted
|
|
char aBuf[12];
|
|
for(int i = 0; i < Players; i++)
|
|
{
|
|
IntToString(GetClientUserId(aClients[i]), aBuf, sizeof(aBuf));
|
|
menu.AddItem(aBuf, g_PlayerNames[aClients[i]]);
|
|
}
|
|
|
|
if(!menu.ItemCount)
|
|
{
|
|
delete menu;
|
|
PrintToChat(client, "\x04[Self-Mute]\x01 You haven't muted or exempted anyone.");
|
|
return;
|
|
}
|
|
|
|
menu.Display(client, MENU_TIME_FOREVER);
|
|
}
|
|
|
|
|
|
public int MenuHandler_UnMuteMenu(Menu menu, MenuAction action, int param1, int param2)
|
|
{
|
|
switch(action)
|
|
{
|
|
case MenuAction_End:
|
|
{
|
|
if(param1 != MenuEnd_Selected)
|
|
CloseHandle(menu);
|
|
}
|
|
case MenuAction_Select:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
char aDisp[MAX_NAME_LENGTH + 4];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
|
|
|
if(Style != ITEMDRAW_DEFAULT || !aItem[0])
|
|
{
|
|
PrintToChat(param1, "Internal error: aItem[0] -> %d | Style -> %d", aItem[0], Style);
|
|
return 0;
|
|
}
|
|
|
|
if(aItem[0] == '@')
|
|
{
|
|
int Flag = GetSpecialMutesFlags(aItem);
|
|
if(Flag && g_SpecialMutes[param1] & Flag)
|
|
UnMuteSpecial(param1, aItem);
|
|
|
|
menu.RemoveItem(GetMenuSelectionPosition());
|
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
|
return 0;
|
|
}
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client)
|
|
{
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 Player no longer available.");
|
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
|
return 0;
|
|
}
|
|
|
|
if(GetIgnored(param1, client))
|
|
{
|
|
if(IsClientSourceTV(client))
|
|
{
|
|
UnIgnore(param1, client);
|
|
SetClientCookie(param1, g_hCookieTorchMuted, "");
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have permanently self-unmuted:\x04 %N", client);
|
|
}
|
|
else
|
|
{
|
|
UnIgnore(param1, 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))
|
|
{
|
|
UnExempt(param1, client);
|
|
PrintToChat(param1, "\x04[Self-Mute]\x01 You have removed exempt from self-mute:\x04 %N", client);
|
|
}
|
|
|
|
menu.RemoveItem(GetMenuSelectionPosition());
|
|
menu.DisplayAt(param1, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
|
|
return 0;
|
|
}
|
|
case MenuAction_DrawItem:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style);
|
|
|
|
if(!aItem[0])
|
|
return ITEMDRAW_DISABLED;
|
|
|
|
if(aItem[0] == '@')
|
|
return Style;
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client) // Player disconnected
|
|
return ITEMDRAW_DISABLED;
|
|
|
|
return Style;
|
|
}
|
|
case MenuAction_DisplayItem:
|
|
{
|
|
int Style;
|
|
char aItem[32];
|
|
char aDisp[MAX_NAME_LENGTH + 4];
|
|
menu.GetItem(param2, aItem, sizeof(aItem), Style, aDisp, sizeof(aDisp));
|
|
|
|
if(!aItem[0])
|
|
return 0;
|
|
|
|
int UserId = StringToInt(aItem);
|
|
int client = GetClientOfUserId(UserId);
|
|
if(!client) // Player disconnected
|
|
{
|
|
char aBuf[MAX_NAME_LENGTH + 4] = "[D] ";
|
|
StrCat(aBuf, sizeof(aBuf), aDisp);
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
|
|
if(GetExempt(param1, client))
|
|
{
|
|
char aBuf[MAX_NAME_LENGTH + 4] = "[E] ";
|
|
GetClientName(client, g_PlayerNames[client], sizeof(g_PlayerNames[]));
|
|
StrCat(aBuf, sizeof(aBuf), g_PlayerNames[client]);
|
|
if(!StrEqual(aDisp, aBuf))
|
|
return RedrawMenuItem(aBuf);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* HOOKS
|
|
*/
|
|
int g_MsgDest;
|
|
int g_MsgClient;
|
|
char g_MsgName[256];
|
|
char g_MsgParam1[256];
|
|
char g_MsgParam2[256];
|
|
char g_MsgParam3[256];
|
|
char g_MsgParam4[256];
|
|
char g_MsgRadioSound[256];
|
|
int g_MsgPlayersNum;
|
|
int g_MsgPlayers[MAXPLAYERS + 1];
|
|
|
|
public Action Hook_UserMessageRadioText(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
|
{
|
|
if(g_bIsProtoBuf)
|
|
{
|
|
g_MsgDest = PbReadInt(bf, "msg_dst");
|
|
g_MsgClient = PbReadInt(bf, "client");
|
|
PbReadString(bf, "msg_name", g_MsgName, sizeof(g_MsgName));
|
|
PbReadString(bf, "params", g_MsgParam1, sizeof(g_MsgParam1), 0);
|
|
PbReadString(bf, "params", g_MsgParam2, sizeof(g_MsgParam2), 1);
|
|
PbReadString(bf, "params", g_MsgParam3, sizeof(g_MsgParam3), 2);
|
|
PbReadString(bf, "params", g_MsgParam4, sizeof(g_MsgParam4), 3);
|
|
}
|
|
else
|
|
{
|
|
g_MsgDest = BfReadByte(bf);
|
|
g_MsgClient = BfReadByte(bf);
|
|
BfReadString(bf, g_MsgName, sizeof(g_MsgName), false);
|
|
BfReadString(bf, g_MsgParam1, sizeof(g_MsgParam1), false);
|
|
BfReadString(bf, g_MsgParam2, sizeof(g_MsgParam2), false);
|
|
BfReadString(bf, g_MsgParam3, sizeof(g_MsgParam3), false);
|
|
BfReadString(bf, g_MsgParam4, sizeof(g_MsgParam4), false);
|
|
}
|
|
|
|
// Check which clients need to be excluded.
|
|
g_MsgPlayersNum = 0;
|
|
for(int i = 0; i < playersNum; i++)
|
|
{
|
|
int client = players[i];
|
|
if(!GetIgnored(client, g_MsgClient))
|
|
g_MsgPlayers[g_MsgPlayersNum++] = client;
|
|
}
|
|
|
|
// No clients were excluded.
|
|
if(g_MsgPlayersNum == playersNum)
|
|
{
|
|
g_MsgClient = -1;
|
|
return Plugin_Continue;
|
|
}
|
|
else if(g_MsgPlayersNum == 0) // All clients were excluded and there is no need to broadcast.
|
|
{
|
|
g_MsgClient = -2;
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public Action Hook_UserMessageSendAudio(UserMsg msg_id, Handle bf, const int[] players, int playersNum, bool reliable, bool init)
|
|
{
|
|
if(g_MsgClient == -1)
|
|
return Plugin_Continue;
|
|
else if(g_MsgClient == -2)
|
|
return Plugin_Handled;
|
|
|
|
if(g_bIsProtoBuf)
|
|
PbReadString(bf, "radio_sound", g_MsgRadioSound, sizeof(g_MsgRadioSound));
|
|
else
|
|
BfReadString(bf, g_MsgRadioSound, sizeof(g_MsgRadioSound), false);
|
|
|
|
if(StrEqual(g_MsgRadioSound, "radio.locknload"))
|
|
return Plugin_Continue;
|
|
|
|
DataPack pack = new DataPack();
|
|
pack.WriteCell(g_MsgDest);
|
|
pack.WriteCell(g_MsgClient);
|
|
pack.WriteString(g_MsgName);
|
|
pack.WriteString(g_MsgParam1);
|
|
pack.WriteString(g_MsgParam2);
|
|
pack.WriteString(g_MsgParam3);
|
|
pack.WriteString(g_MsgParam4);
|
|
pack.WriteString(g_MsgRadioSound);
|
|
pack.WriteCell(g_MsgPlayersNum);
|
|
|
|
for(int i = 0; i < g_MsgPlayersNum; i++)
|
|
pack.WriteCell(g_MsgPlayers[i]);
|
|
|
|
RequestFrame(OnPlayerRadio, pack);
|
|
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public void OnPlayerRadio(DataPack pack)
|
|
{
|
|
pack.Reset();
|
|
g_MsgDest = pack.ReadCell();
|
|
g_MsgClient = pack.ReadCell();
|
|
pack.ReadString(g_MsgName, sizeof(g_MsgName));
|
|
pack.ReadString(g_MsgParam1, sizeof(g_MsgParam1));
|
|
pack.ReadString(g_MsgParam2, sizeof(g_MsgParam2));
|
|
pack.ReadString(g_MsgParam3, sizeof(g_MsgParam3));
|
|
pack.ReadString(g_MsgParam4, sizeof(g_MsgParam4));
|
|
pack.ReadString(g_MsgRadioSound, sizeof(g_MsgRadioSound));
|
|
g_MsgPlayersNum = pack.ReadCell();
|
|
|
|
int playersNum = 0;
|
|
for(int i = 0; i < g_MsgPlayersNum; i++)
|
|
{
|
|
int client_ = pack.ReadCell();
|
|
if(IsClientInGame(client_))
|
|
g_MsgPlayers[playersNum++] = client_;
|
|
}
|
|
CloseHandle(pack);
|
|
|
|
Handle RadioText = StartMessage("RadioText", g_MsgPlayers, playersNum, USERMSG_RELIABLE);
|
|
if(g_bIsProtoBuf)
|
|
{
|
|
PbSetInt(RadioText, "msg_dst", g_MsgDest);
|
|
PbSetInt(RadioText, "client", g_MsgClient);
|
|
PbSetString(RadioText, "msg_name", g_MsgName);
|
|
PbSetString(RadioText, "params", g_MsgParam1, 0);
|
|
PbSetString(RadioText, "params", g_MsgParam2, 1);
|
|
PbSetString(RadioText, "params", g_MsgParam3, 2);
|
|
PbSetString(RadioText, "params", g_MsgParam4, 3);
|
|
}
|
|
else
|
|
{
|
|
BfWriteByte(RadioText, g_MsgDest);
|
|
BfWriteByte(RadioText, g_MsgClient);
|
|
BfWriteString(RadioText, g_MsgName);
|
|
BfWriteString(RadioText, g_MsgParam1);
|
|
BfWriteString(RadioText, g_MsgParam2);
|
|
BfWriteString(RadioText, g_MsgParam3);
|
|
BfWriteString(RadioText, g_MsgParam4);
|
|
}
|
|
EndMessage();
|
|
|
|
Handle SendAudio = StartMessage("SendAudio", g_MsgPlayers, playersNum, USERMSG_RELIABLE);
|
|
if(g_bIsProtoBuf)
|
|
PbSetString(SendAudio, "radio_sound", g_MsgRadioSound);
|
|
else
|
|
BfWriteString(SendAudio, g_MsgRadioSound);
|
|
EndMessage();
|
|
}
|
|
|
|
/*
|
|
* HELPERS
|
|
*/
|
|
void UpdateIgnored()
|
|
{
|
|
if(g_Plugin_ccc)
|
|
CCC_UpdateIgnoredArray(g_Ignored);
|
|
}
|
|
|
|
public int SortByPlayerName(int elem1, int elem2, const int[] array, Handle hndl)
|
|
{
|
|
return strcmp(g_PlayerNames[elem1], g_PlayerNames[elem2], false);
|
|
}
|
|
|
|
bool GetIgnored(int client, int target)
|
|
{
|
|
return g_Ignored[(client * (MAXPLAYERS + 1) + target)];
|
|
}
|
|
|
|
void SetIgnored(int client, int target, bool ignored)
|
|
{
|
|
g_Ignored[(client * (MAXPLAYERS + 1) + target)] = ignored;
|
|
}
|
|
|
|
bool GetExempt(int client, int target)
|
|
{
|
|
return g_Exempt[client][target];
|
|
}
|
|
|
|
void SetExempt(int client, int target, bool exempt)
|
|
{
|
|
g_Exempt[client][target] = exempt;
|
|
}
|
|
|
|
stock bool IsValidClient(int client)
|
|
{
|
|
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
|
|
return true;
|
|
return false;
|
|
}
|