Added global pre and post forwards for client chat (bug 5394, r=psychonic).
This commit is contained in:
parent
37316fed84
commit
5d76ffef88
@ -63,6 +63,10 @@ ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
|
|||||||
m_PubTriggerSize = 1;
|
m_PubTriggerSize = 1;
|
||||||
m_PrivTriggerSize = 1;
|
m_PrivTriggerSize = 1;
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
|
m_bPluginIgnored = false;
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
m_bIsINS = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatTriggers::~ChatTriggers()
|
ChatTriggers::~ChatTriggers()
|
||||||
@ -106,6 +110,8 @@ void ChatTriggers::OnSourceModAllInitialized()
|
|||||||
{
|
{
|
||||||
m_pShouldFloodBlock = g_Forwards.CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell);
|
m_pShouldFloodBlock = g_Forwards.CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell);
|
||||||
m_pDidFloodBlock = g_Forwards.CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell);
|
m_pDidFloodBlock = g_Forwards.CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell);
|
||||||
|
m_pOnClientSayCmd = g_Forwards.CreateForward("OnClientSayCommand", ET_Event, 3, NULL, Param_Cell, Param_String, Param_String);
|
||||||
|
m_pOnClientSayCmd_Post = g_Forwards.CreateForward("OnClientSayCommand_Post", ET_Ignore, 3, NULL, Param_Cell, Param_String, Param_String);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTriggers::OnSourceModAllInitialized_Post()
|
void ChatTriggers::OnSourceModAllInitialized_Post()
|
||||||
@ -128,23 +134,62 @@ void ChatTriggers::OnSourceModGameInitialized()
|
|||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
m_bIsINS = (strncmp(g_SourceMod.GetGameFolderName(), "insurgency") == 0);
|
||||||
|
|
||||||
|
if (m_bIsINS)
|
||||||
|
{
|
||||||
|
m_pSay2Cmd = FindCommand("say2");
|
||||||
|
if (m_pSay2Cmd)
|
||||||
|
{
|
||||||
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
|
m_pSaySquadCmd = FindCommand("say_squad");
|
||||||
|
|
||||||
|
if (m_pSaySquadCmd)
|
||||||
|
{
|
||||||
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
|
SH_ADD_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTriggers::OnSourceModShutdown()
|
void ChatTriggers::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
if (m_pSayTeamCmd)
|
|
||||||
{
|
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
|
||||||
}
|
|
||||||
if (m_pSayCmd)
|
if (m_pSayCmd)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_pSayTeamCmd)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
if (m_bIsINS && m_pSay2Cmd)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
|
}
|
||||||
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
|
if (m_pSaySquadCmd)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
||||||
|
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
g_Forwards.ReleaseForward(m_pShouldFloodBlock);
|
g_Forwards.ReleaseForward(m_pShouldFloodBlock);
|
||||||
g_Forwards.ReleaseForward(m_pDidFloodBlock);
|
g_Forwards.ReleaseForward(m_pDidFloodBlock);
|
||||||
|
g_Forwards.ReleaseForward(m_pOnClientSayCmd);
|
||||||
|
g_Forwards.ReleaseForward(m_pOnClientSayCmd_Post);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
@ -158,21 +203,21 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
{
|
{
|
||||||
CCommand command;
|
CCommand command;
|
||||||
#endif
|
#endif
|
||||||
int client;
|
int client = g_ConCmds.GetCommandClient();
|
||||||
CPlayer *pPlayer;
|
|
||||||
|
|
||||||
client = g_ConCmds.GetCommandClient();
|
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
m_bWasFloodedMessage = false;
|
m_bWasFloodedMessage = false;
|
||||||
|
m_bPluginIgnored = false;
|
||||||
|
|
||||||
/* The server console cannot do this */
|
/* The server console cannot do this */
|
||||||
if (client == 0 || (pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
|
if (client == 0)
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||||
|
|
||||||
/* We guarantee the client is connected */
|
/* We guarantee the client is connected */
|
||||||
if (!pPlayer->IsConnected())
|
if (!pPlayer || !pPlayer->IsConnected())
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
@ -211,6 +256,14 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
is_quoted = true;
|
is_quoted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * pCommandName = command.Arg(0);
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
if (m_bIsINS && strncmp(pCommandName, "say2") && strlen(args) >= 4)
|
||||||
|
{
|
||||||
|
args += 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool is_trigger = false;
|
bool is_trigger = false;
|
||||||
bool is_silent = false;
|
bool is_silent = false;
|
||||||
|
|
||||||
@ -227,38 +280,37 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
args = &args[m_PrivTriggerSize];
|
args = &args[m_PrivTriggerSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_trigger)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if this is actually a command!
|
* Test if this is actually a command!
|
||||||
*/
|
*/
|
||||||
if (!PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
|
if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
|
||||||
{
|
{
|
||||||
CPlayer *pPlayer;
|
m_bIsChatTrigger = true;
|
||||||
if (is_silent
|
|
||||||
&& g_bSupressSilentFails
|
/**
|
||||||
&& client != 0
|
* We'll execute it in post.
|
||||||
&& (pPlayer = g_Players.GetPlayerByIndex(client)) != NULL
|
*/
|
||||||
&& pPlayer->GetAdminId() != INVALID_ADMIN_ID)
|
m_bWillProcessInPost = true;
|
||||||
{
|
m_bTriggerWasSilent = is_silent;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bIsChatTrigger = true;
|
if (m_pOnClientSayCmd->GetFunctionCount() != 0)
|
||||||
|
{
|
||||||
|
cell_t res = Pl_Continue;
|
||||||
|
m_pOnClientSayCmd->PushCell(client);
|
||||||
|
m_pOnClientSayCmd->PushString(pCommandName);
|
||||||
|
m_pOnClientSayCmd->PushString(command.ArgS());
|
||||||
|
m_pOnClientSayCmd->Execute(&res);
|
||||||
|
|
||||||
/**
|
if (res >= Pl_Handled)
|
||||||
* We'll execute it in post.
|
{
|
||||||
*/
|
m_bPluginIgnored = (res >= Pl_Stop);
|
||||||
m_bWillProcessInPost = true;
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
m_bTriggerWasSilent = is_silent;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If we're silent, block */
|
if (m_bWillProcessInPost || \
|
||||||
if (is_silent)
|
(is_silent && g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID))
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
@ -275,15 +327,14 @@ void ChatTriggers::OnSayCommand_Post(const CCommand &command)
|
|||||||
void ChatTriggers::OnSayCommand_Post()
|
void ChatTriggers::OnSayCommand_Post()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
m_bIsChatTrigger = false;
|
int client = g_ConCmds.GetCommandClient();
|
||||||
m_bWasFloodedMessage = false;
|
|
||||||
if (m_bWillProcessInPost)
|
if (m_bWillProcessInPost)
|
||||||
{
|
{
|
||||||
/* Reset this for re-entrancy */
|
/* Reset this for re-entrancy */
|
||||||
m_bWillProcessInPost = false;
|
m_bWillProcessInPost = false;
|
||||||
|
|
||||||
/* Execute the cached command */
|
/* Execute the cached command */
|
||||||
int client = g_ConCmds.GetCommandClient();
|
|
||||||
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
|
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
engine->ClientCommand(client, "%s", m_ToExecute);
|
engine->ClientCommand(client, "%s", m_ToExecute);
|
||||||
@ -292,6 +343,21 @@ void ChatTriggers::OnSayCommand_Post()
|
|||||||
#endif
|
#endif
|
||||||
SetReplyTo(old);
|
SetReplyTo(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_bPluginIgnored)
|
||||||
|
{
|
||||||
|
m_bPluginIgnored = false;
|
||||||
|
}
|
||||||
|
else if (!m_bWasFloodedMessage && m_pOnClientSayCmd_Post->GetFunctionCount() != 0)
|
||||||
|
{
|
||||||
|
m_pOnClientSayCmd_Post->PushCell(client);
|
||||||
|
m_pOnClientSayCmd_Post->PushString(command.Arg(0));
|
||||||
|
m_pOnClientSayCmd_Post->PushString(command.ArgS());
|
||||||
|
m_pOnClientSayCmd_Post->Execute(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bIsChatTrigger = false;
|
||||||
|
m_bWasFloodedMessage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted)
|
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted)
|
||||||
|
@ -75,6 +75,11 @@ private:
|
|||||||
private:
|
private:
|
||||||
ConCommand *m_pSayCmd;
|
ConCommand *m_pSayCmd;
|
||||||
ConCommand *m_pSayTeamCmd;
|
ConCommand *m_pSayTeamCmd;
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
ConCommand *m_pSay2Cmd;
|
||||||
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
|
ConCommand *m_pSaySquadCmd;
|
||||||
|
#endif
|
||||||
char *m_PubTrigger;
|
char *m_PubTrigger;
|
||||||
size_t m_PubTriggerSize;
|
size_t m_PubTriggerSize;
|
||||||
char *m_PrivTrigger;
|
char *m_PrivTrigger;
|
||||||
@ -83,10 +88,16 @@ private:
|
|||||||
bool m_bTriggerWasSilent;
|
bool m_bTriggerWasSilent;
|
||||||
bool m_bIsChatTrigger;
|
bool m_bIsChatTrigger;
|
||||||
bool m_bWasFloodedMessage;
|
bool m_bWasFloodedMessage;
|
||||||
|
bool m_bPluginIgnored;
|
||||||
unsigned int m_ReplyTo;
|
unsigned int m_ReplyTo;
|
||||||
char m_ToExecute[300];
|
char m_ToExecute[300];
|
||||||
IForward *m_pShouldFloodBlock;
|
IForward *m_pShouldFloodBlock;
|
||||||
IForward *m_pDidFloodBlock;
|
IForward *m_pDidFloodBlock;
|
||||||
|
IForward *m_pOnClientSayCmd;
|
||||||
|
IForward *m_pOnClientSayCmd_Post;
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
bool m_bIsINS;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ChatTriggers g_ChatTriggers;
|
extern ChatTriggers g_ChatTriggers;
|
||||||
|
@ -81,9 +81,6 @@ public OnPluginStart()
|
|||||||
g_Cvar_Deadtalk = CreateConVar("sm_deadtalk", "0", "Controls how dead communicate. 0 - Off. 1 - Dead players ignore teams. 2 - Dead players talk to living teammates.", 0, true, 0.0, true, 2.0);
|
g_Cvar_Deadtalk = CreateConVar("sm_deadtalk", "0", "Controls how dead communicate. 0 - Off. 1 - Dead players ignore teams. 2 - Dead players talk to living teammates.", 0, true, 0.0, true, 2.0);
|
||||||
g_Cvar_Alltalk = FindConVar("sv_alltalk");
|
g_Cvar_Alltalk = FindConVar("sv_alltalk");
|
||||||
|
|
||||||
AddCommandListener(Command_Say, "say");
|
|
||||||
AddCommandListener(Command_Say, "say_team");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_mute", Command_Mute, ADMFLAG_CHAT, "sm_mute <player> - Removes a player's ability to use voice.");
|
RegAdminCmd("sm_mute", Command_Mute, ADMFLAG_CHAT, "sm_mute <player> - Removes a player's ability to use voice.");
|
||||||
RegAdminCmd("sm_gag", Command_Gag, ADMFLAG_CHAT, "sm_gag <player> - Removes a player's ability to use chat.");
|
RegAdminCmd("sm_gag", Command_Gag, ADMFLAG_CHAT, "sm_gag <player> - Removes a player's ability to use chat.");
|
||||||
RegAdminCmd("sm_silence", Command_Silence, ADMFLAG_CHAT, "sm_silence <player> - Removes a player's ability to use voice or chat.");
|
RegAdminCmd("sm_silence", Command_Silence, ADMFLAG_CHAT, "sm_silence <player> - Removes a player's ability to use voice or chat.");
|
||||||
@ -154,13 +151,13 @@ public bool:OnClientConnect(client, String:rejectmsg[], maxlen)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action:Command_Say(client, const String:command[], args)
|
public Action:OnClientSayCommand(client, const String:command[], const String:sArgs[])
|
||||||
{
|
{
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
if (g_Gagged[client])
|
if (g_Gagged[client])
|
||||||
{
|
{
|
||||||
return Plugin_Handled;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,10 +75,6 @@ public OnPluginStart()
|
|||||||
g_Cvar_TimeleftInterval = CreateConVar("sm_timeleft_interval", "0.0", "Display timeleft every x seconds. Default 0.", 0, true, 0.0, true, 1800.0);
|
g_Cvar_TimeleftInterval = CreateConVar("sm_timeleft_interval", "0.0", "Display timeleft every x seconds. Default 0.", 0, true, 0.0, true, 1800.0);
|
||||||
g_Cvar_FriendlyFire = FindConVar("mp_friendlyfire");
|
g_Cvar_FriendlyFire = FindConVar("mp_friendlyfire");
|
||||||
|
|
||||||
AddCommandListener(Command_Say, "say");
|
|
||||||
AddCommandListener(Command_Say, "say2");
|
|
||||||
AddCommandListener(Command_Say, "say_team");
|
|
||||||
|
|
||||||
RegConsoleCmd("timeleft", Command_Timeleft);
|
RegConsoleCmd("timeleft", Command_Timeleft);
|
||||||
RegConsoleCmd("nextmap", Command_Nextmap);
|
RegConsoleCmd("nextmap", Command_Nextmap);
|
||||||
RegConsoleCmd("motd", Command_Motd);
|
RegConsoleCmd("motd", Command_Motd);
|
||||||
@ -236,22 +232,22 @@ public Action:Command_Motd(client, args)
|
|||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action:Command_Say(client, const String:command[], argc)
|
public OnClientSayCommand_Post(client, const String:command[], const String:sArgs[])
|
||||||
{
|
{
|
||||||
decl String:text[192];
|
decl String:text[192];
|
||||||
new startidx = 0;
|
new startidx = 0;
|
||||||
if (GetCmdArgString(text, sizeof(text)) < 1)
|
|
||||||
|
if (strcopy(text, sizeof(text), sArgs) < 1)
|
||||||
{
|
{
|
||||||
return Plugin_Continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text[strlen(text)-1] == '"')
|
if (text[0] == '"')
|
||||||
{
|
{
|
||||||
text[strlen(text)-1] = '\0';
|
|
||||||
startidx = 1;
|
startidx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(command, "say2", false) == 0)
|
if ((strcmp(command, "say2", false) == 0) && strlen(sArgs) >= 4)
|
||||||
startidx += 4;
|
startidx += 4;
|
||||||
|
|
||||||
if (strcmp(text[startidx], "timeleft", false) == 0)
|
if (strcmp(text[startidx], "timeleft", false) == 0)
|
||||||
@ -342,8 +338,6 @@ public Action:Command_Say(client, const String:command[], argc)
|
|||||||
{
|
{
|
||||||
ShowMOTDPanel(client, "Message Of The Day", "motd", MOTDPANEL_TYPE_INDEX);
|
ShowMOTDPanel(client, "Message Of The Day", "motd", MOTDPANEL_TYPE_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowTimeLeft(client, who)
|
ShowTimeLeft(client, who)
|
||||||
|
@ -938,3 +938,24 @@ native bool:AddCommandListener(CommandListener:callback, const String:command[]=
|
|||||||
*/
|
*/
|
||||||
native RemoveCommandListener(CommandListener:callback, const String:command[]="");
|
native RemoveCommandListener(CommandListener:callback, const String:command[]="");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global listener for the chat commands.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @param command Command name.
|
||||||
|
* @param sArgs Chat argument string.
|
||||||
|
*
|
||||||
|
* @return An Action value. Returning Plugin_Handled bypasses the game function call.
|
||||||
|
Returning Plugin_Stop bypasses the post hook as well as the game function.
|
||||||
|
*/
|
||||||
|
forward Action:OnClientSayCommand(client, const String:command[], const String:sArgs[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global post listener for the chat commands.
|
||||||
|
*
|
||||||
|
* @param client Client index.
|
||||||
|
* @param command Command name.
|
||||||
|
* @param sArgs Chat argument string.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
forward OnClientSayCommand_Post(client, const String:command[], const String:sArgs[]);
|
||||||
|
Loading…
Reference in New Issue
Block a user