From c54b54ded08244ef2e15954ebb9bbb9c14dbd0ff Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 6 Sep 2015 12:54:12 -0700 Subject: [PATCH] Use GameHooks for ChatTriggers. --- core/ChatTriggers.cpp | 150 +++++++++++------------------------------- core/ChatTriggers.h | 21 ++---- 2 files changed, 44 insertions(+), 127 deletions(-) diff --git a/core/ChatTriggers.cpp b/core/ChatTriggers.cpp index 2e21a8e9..02dbb448 100644 --- a/core/ChatTriggers.cpp +++ b/core/ChatTriggers.cpp @@ -37,27 +37,13 @@ #include "HalfLife2.h" #include "logic_bridge.h" #include "sourcemod.h" +#include "provider.h" #include -#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); -# else - extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); -# endif -extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0); -#endif - ChatTriggers g_ChatTriggers; 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_PubTrigger = "!"; @@ -115,70 +101,43 @@ void ChatTriggers::OnSourceModAllInitialized_Post() void ChatTriggers::OnSourceModGameInitialized() { - m_pSayCmd = FindCommand("say"); - m_pSayTeamCmd = FindCommand("say_team"); + ConCommand *say_team = FindCommand("say_team"); - if (m_pSayCmd) - { - 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 pre_hook = [this] (const ICommandArgs *args) -> bool { + return this->OnSayCommand_Pre(args); + }; + 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) - { - 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); + if (ConCommand *say_team = FindCommand("say_team")) { + hooks_.append(sCoreProviderImpl.AddCommandHook(say_team, pre_hook)); + hooks_.append(sCoreProviderImpl.AddPostCommandHook(say_team, post_hook)); } #if SOURCE_ENGINE == SE_EPISODEONE m_bIsINS = (strcmp(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); + if (m_bIsINS) { + if (ConCommand *say2 = FindCommand("say2")) { + hooks_.append(sCoreProviderImpl.AddCommandHook(say2, pre_hook)); + hooks_.append(sCoreProviderImpl.AddPostCommandHook(say2, post_hook)); } } #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); + if (ConCommand *say_squad = FindCommand("say_squad")) { + hooks_.append(sCoreProviderImpl.AddCommandHook(say_squad, pre_hook)); + hooks_.append(sCoreProviderImpl.AddPostCommandHook(say_squad, post_hook)); } #endif } void ChatTriggers::OnSourceModShutdown() { - 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_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 + hooks_.clear(); forwardsys->ReleaseForward(m_pShouldFloodBlock); forwardsys->ReleaseForward(m_pDidFloodBlock); @@ -186,32 +145,21 @@ void ChatTriggers::OnSourceModShutdown() forwardsys->ReleaseForward(m_pOnClientSayCmd_Post); } -#if SOURCE_ENGINE == SE_DOTA -void ChatTriggers::OnSayCommand_Pre(const CCommandContext &context, const CCommand &command) +bool ChatTriggers::OnSayCommand_Pre(const ICommandArgs *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(); m_bIsChatTrigger = false; m_bWasFloodedMessage = false; m_bPluginIgnored = true; - const char *args = command.ArgS(); + const char *args = command->ArgS(); if (!args) - { - RETURN_META(MRES_IGNORED); - } + return false; /* 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. */ - m_Arg0Backup = command.Arg(0); + m_Arg0Backup = command->Arg(0); size_t len = strlen(args); #if SOURCE_ENGINE == SE_EPISODEONE @@ -224,9 +172,7 @@ void ChatTriggers::OnSayCommand_Pre() } if (len == 0) - { - RETURN_META(MRES_SUPERCEDE); - } + return true; } #endif @@ -244,9 +190,7 @@ void ChatTriggers::OnSayCommand_Pre() /* 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. */ if (len <= 2) - { - RETURN_META(MRES_SUPERCEDE); - } + return true; args++; len--; @@ -275,20 +219,16 @@ void ChatTriggers::OnSayCommand_Pre() if (client == 0) { if (CallOnClientSayCommand(client) >= Pl_Handled) - { - RETURN_META(MRES_SUPERCEDE); - } + return true; - RETURN_META(MRES_IGNORED); + return false; } CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); /* We guarantee the client is connected */ if (!pPlayer || !pPlayer->IsConnected()) - { - RETURN_META(MRES_IGNORED); - } + return false; /* Check if we need to block this message from being sent */ if (ClientIsFlooding(client)) @@ -305,8 +245,7 @@ void ChatTriggers::OnSayCommand_Pre() g_HL2.TextMsg(client, HUD_PRINTTALK, fullbuffer); m_bWasFloodedMessage = true; - - RETURN_META(MRES_SUPERCEDE); + return true; } bool is_trigger = false; @@ -339,26 +278,16 @@ void ChatTriggers::OnSayCommand_Pre() } if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID))) - { - RETURN_META(MRES_SUPERCEDE); - } + return true; if (CallOnClientSayCommand(client) >= Pl_Handled) - { - RETURN_META(MRES_SUPERCEDE); - } + return true; /* Otherwise, let the command continue */ - RETURN_META(MRES_IGNORED); + return false; } -#if SOURCE_ENGINE == SE_DOTA -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 +bool ChatTriggers::OnSayCommand_Post(const ICommandArgs *command) { int client = g_ConCmds.GetCommandClient(); @@ -387,11 +316,12 @@ void ChatTriggers::OnSayCommand_Post() m_bIsChatTrigger = false; m_bWasFloodedMessage = false; + return false; } 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]; size_t cmd_len = 0; const char *inptr = args; diff --git a/core/ChatTriggers.h b/core/ChatTriggers.h index ee8eb49c..1661c2a8 100644 --- a/core/ChatTriggers.h +++ b/core/ChatTriggers.h @@ -34,6 +34,7 @@ #include "sm_globals.h" #include "sourcemm_api.h" +#include "GameHooks.h" #include #include #include @@ -55,16 +56,8 @@ public: //SMGlobalClass char *error, size_t maxlength); private: //ConCommand -#if SOURCE_ENGINE == SE_DOTA - void OnSayCommand_Pre(const CCommandContext &, const CCommand &command); - 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 + bool OnSayCommand_Pre(const ICommandArgs *args); + bool OnSayCommand_Post(const ICommandArgs *args); public: unsigned int GetReplyTo(); unsigned int SetReplyTo(unsigned int reply); @@ -75,13 +68,7 @@ private: bool ClientIsFlooding(int client); cell_t CallOnClientSayCommand(int client); private: - ConCommand *m_pSayCmd; - ConCommand *m_pSayTeamCmd; -#if SOURCE_ENGINE == SE_EPISODEONE - ConCommand *m_pSay2Cmd; -#elif SOURCE_ENGINE == SE_NUCLEARDAWN - ConCommand *m_pSaySquadCmd; -#endif + ke::Vector> hooks_; ke::AString m_PubTrigger; ke::AString m_PrivTrigger; bool m_bWillProcessInPost;