Use GameHooks for ChatTriggers.
This commit is contained in:
parent
5757b729ac
commit
c54b54ded0
@ -37,27 +37,13 @@
|
|||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
|
#include "provider.h"
|
||||||
#include <amtl/am-string.h>
|
#include <amtl/am-string.h>
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
|
||||||
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
|
||||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
|
||||||
#else
|
|
||||||
# if SH_IMPL_VERSION >= 4
|
|
||||||
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
|
||||||
# else
|
|
||||||
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
|
||||||
# endif
|
|
||||||
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ChatTriggers g_ChatTriggers;
|
ChatTriggers g_ChatTriggers;
|
||||||
bool g_bSupressSilentFails = false;
|
bool g_bSupressSilentFails = false;
|
||||||
|
|
||||||
ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
|
ChatTriggers::ChatTriggers() : m_bWillProcessInPost(false),
|
||||||
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
||||||
{
|
{
|
||||||
m_PubTrigger = "!";
|
m_PubTrigger = "!";
|
||||||
@ -115,70 +101,43 @@ void ChatTriggers::OnSourceModAllInitialized_Post()
|
|||||||
|
|
||||||
void ChatTriggers::OnSourceModGameInitialized()
|
void ChatTriggers::OnSourceModGameInitialized()
|
||||||
{
|
{
|
||||||
m_pSayCmd = FindCommand("say");
|
ConCommand *say_team = FindCommand("say_team");
|
||||||
m_pSayTeamCmd = FindCommand("say_team");
|
|
||||||
|
|
||||||
if (m_pSayCmd)
|
CommandHook::Callback pre_hook = [this] (const ICommandArgs *args) -> bool {
|
||||||
{
|
return this->OnSayCommand_Pre(args);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
};
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
CommandHook::Callback post_hook = [this] (const ICommandArgs *args) -> bool {
|
||||||
|
return this->OnSayCommand_Post(args);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ConCommand *say = FindCommand("say")) {
|
||||||
|
hooks_.append(sCoreProviderImpl.AddCommandHook(say, pre_hook));
|
||||||
|
hooks_.append(sCoreProviderImpl.AddPostCommandHook(say, post_hook));
|
||||||
}
|
}
|
||||||
if (m_pSayTeamCmd)
|
if (ConCommand *say_team = FindCommand("say_team")) {
|
||||||
{
|
hooks_.append(sCoreProviderImpl.AddCommandHook(say_team, pre_hook));
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
hooks_.append(sCoreProviderImpl.AddPostCommandHook(say_team, post_hook));
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
m_bIsINS = (strcmp(g_SourceMod.GetGameFolderName(), "insurgency") == 0);
|
m_bIsINS = (strcmp(g_SourceMod.GetGameFolderName(), "insurgency") == 0);
|
||||||
|
if (m_bIsINS) {
|
||||||
if (m_bIsINS)
|
if (ConCommand *say2 = FindCommand("say2")) {
|
||||||
{
|
hooks_.append(sCoreProviderImpl.AddCommandHook(say2, pre_hook));
|
||||||
m_pSay2Cmd = FindCommand("say2");
|
hooks_.append(sCoreProviderImpl.AddPostCommandHook(say2, post_hook));
|
||||||
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
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
m_pSaySquadCmd = FindCommand("say_squad");
|
if (ConCommand *say_squad = FindCommand("say_squad")) {
|
||||||
|
hooks_.append(sCoreProviderImpl.AddCommandHook(say_squad, pre_hook));
|
||||||
if (m_pSaySquadCmd)
|
hooks_.append(sCoreProviderImpl.AddPostCommandHook(say_squad, post_hook));
|
||||||
{
|
|
||||||
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTriggers::OnSourceModShutdown()
|
void ChatTriggers::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
if (m_pSayCmd)
|
hooks_.clear();
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
forwardsys->ReleaseForward(m_pShouldFloodBlock);
|
forwardsys->ReleaseForward(m_pShouldFloodBlock);
|
||||||
forwardsys->ReleaseForward(m_pDidFloodBlock);
|
forwardsys->ReleaseForward(m_pDidFloodBlock);
|
||||||
@ -186,32 +145,21 @@ void ChatTriggers::OnSourceModShutdown()
|
|||||||
forwardsys->ReleaseForward(m_pOnClientSayCmd_Post);
|
forwardsys->ReleaseForward(m_pOnClientSayCmd_Post);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
bool ChatTriggers::OnSayCommand_Pre(const ICommandArgs *command)
|
||||||
void ChatTriggers::OnSayCommand_Pre(const CCommandContext &context, const CCommand &command)
|
|
||||||
{
|
{
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
|
|
||||||
{
|
|
||||||
#else
|
|
||||||
void ChatTriggers::OnSayCommand_Pre()
|
|
||||||
{
|
|
||||||
CCommand command;
|
|
||||||
#endif
|
|
||||||
int client = g_ConCmds.GetCommandClient();
|
int client = g_ConCmds.GetCommandClient();
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
m_bWasFloodedMessage = false;
|
m_bWasFloodedMessage = false;
|
||||||
m_bPluginIgnored = true;
|
m_bPluginIgnored = true;
|
||||||
|
|
||||||
const char *args = command.ArgS();
|
const char *args = command->ArgS();
|
||||||
|
|
||||||
if (!args)
|
if (!args)
|
||||||
{
|
return false;
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
||||||
* can be NULL, despite the data still being there and valid. */
|
* can be NULL, despite the data still being there and valid. */
|
||||||
m_Arg0Backup = command.Arg(0);
|
m_Arg0Backup = command->Arg(0);
|
||||||
size_t len = strlen(args);
|
size_t len = strlen(args);
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
@ -224,9 +172,7 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -244,9 +190,7 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
/* The server normally won't display empty say commands, but in this case it does.
|
/* The server normally won't display empty say commands, but in this case it does.
|
||||||
* I don't think it's desired so let's block it. */
|
* I don't think it's desired so let's block it. */
|
||||||
if (len <= 2)
|
if (len <= 2)
|
||||||
{
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
args++;
|
args++;
|
||||||
len--;
|
len--;
|
||||||
@ -275,20 +219,16 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
if (client == 0)
|
if (client == 0)
|
||||||
{
|
{
|
||||||
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
||||||
{
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||||
|
|
||||||
/* We guarantee the client is connected */
|
/* We guarantee the client is connected */
|
||||||
if (!pPlayer || !pPlayer->IsConnected())
|
if (!pPlayer || !pPlayer->IsConnected())
|
||||||
{
|
return false;
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if we need to block this message from being sent */
|
/* Check if we need to block this message from being sent */
|
||||||
if (ClientIsFlooding(client))
|
if (ClientIsFlooding(client))
|
||||||
@ -305,8 +245,7 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer);
|
g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer);
|
||||||
|
|
||||||
m_bWasFloodedMessage = true;
|
m_bWasFloodedMessage = true;
|
||||||
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_trigger = false;
|
bool is_trigger = false;
|
||||||
@ -339,26 +278,16 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
|
if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
|
||||||
{
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
||||||
{
|
return true;
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Otherwise, let the command continue */
|
/* Otherwise, let the command continue */
|
||||||
RETURN_META(MRES_IGNORED);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
bool ChatTriggers::OnSayCommand_Post(const ICommandArgs *command)
|
||||||
void ChatTriggers::OnSayCommand_Post(const CCommandContext &context, const CCommand &command)
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void ChatTriggers::OnSayCommand_Post(const CCommand &command)
|
|
||||||
#else
|
|
||||||
void ChatTriggers::OnSayCommand_Post()
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int client = g_ConCmds.GetCommandClient();
|
int client = g_ConCmds.GetCommandClient();
|
||||||
|
|
||||||
@ -387,11 +316,12 @@ void ChatTriggers::OnSayCommand_Post()
|
|||||||
|
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
m_bWasFloodedMessage = false;
|
m_bWasFloodedMessage = false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
||||||
{
|
{
|
||||||
/* Extract a command. This is kind of sloppy. */
|
/* Extract a command. This is kind of sloppy. */
|
||||||
char cmd_buf[64];
|
char cmd_buf[64];
|
||||||
size_t cmd_len = 0;
|
size_t cmd_len = 0;
|
||||||
const char *inptr = args;
|
const char *inptr = args;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
|
#include "GameHooks.h"
|
||||||
#include <IGameHelpers.h>
|
#include <IGameHelpers.h>
|
||||||
#include <compat_wrappers.h>
|
#include <compat_wrappers.h>
|
||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
@ -55,16 +56,8 @@ public: //SMGlobalClass
|
|||||||
char *error,
|
char *error,
|
||||||
size_t maxlength);
|
size_t maxlength);
|
||||||
private: //ConCommand
|
private: //ConCommand
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
bool OnSayCommand_Pre(const ICommandArgs *args);
|
||||||
void OnSayCommand_Pre(const CCommandContext &, const CCommand &command);
|
bool OnSayCommand_Post(const ICommandArgs *args);
|
||||||
void OnSayCommand_Post(const CCommandContext &, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void OnSayCommand_Pre(const CCommand &command);
|
|
||||||
void OnSayCommand_Post(const CCommand &command);
|
|
||||||
#else
|
|
||||||
void OnSayCommand_Pre();
|
|
||||||
void OnSayCommand_Post();
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
unsigned int GetReplyTo();
|
unsigned int GetReplyTo();
|
||||||
unsigned int SetReplyTo(unsigned int reply);
|
unsigned int SetReplyTo(unsigned int reply);
|
||||||
@ -75,13 +68,7 @@ private:
|
|||||||
bool ClientIsFlooding(int client);
|
bool ClientIsFlooding(int client);
|
||||||
cell_t CallOnClientSayCommand(int client);
|
cell_t CallOnClientSayCommand(int client);
|
||||||
private:
|
private:
|
||||||
ConCommand *m_pSayCmd;
|
ke::Vector<ke::Ref<CommandHook>> hooks_;
|
||||||
ConCommand *m_pSayTeamCmd;
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
|
||||||
ConCommand *m_pSay2Cmd;
|
|
||||||
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
|
||||||
ConCommand *m_pSaySquadCmd;
|
|
||||||
#endif
|
|
||||||
ke::AString m_PubTrigger;
|
ke::AString m_PubTrigger;
|
||||||
ke::AString m_PrivTrigger;
|
ke::AString m_PrivTrigger;
|
||||||
bool m_bWillProcessInPost;
|
bool m_bWillProcessInPost;
|
||||||
|
Loading…
Reference in New Issue
Block a user