Move the SetCommandClient hook into GameHooks.

This commit is contained in:
David Anderson 2015-09-06 14:55:51 -07:00
parent c54b54ded0
commit fe16e8e47c
8 changed files with 40 additions and 39 deletions

View File

@ -103,11 +103,11 @@ void ChatTriggers::OnSourceModGameInitialized()
{ {
ConCommand *say_team = FindCommand("say_team"); ConCommand *say_team = FindCommand("say_team");
CommandHook::Callback pre_hook = [this] (const ICommandArgs *args) -> bool { CommandHook::Callback pre_hook = [this] (int client, const ICommandArgs *args) -> bool {
return this->OnSayCommand_Pre(args); return this->OnSayCommand_Pre(client, args);
}; };
CommandHook::Callback post_hook = [this] (const ICommandArgs *args) -> bool { CommandHook::Callback post_hook = [this] (int client, const ICommandArgs *args) -> bool {
return this->OnSayCommand_Post(args); return this->OnSayCommand_Post(client, args);
}; };
if (ConCommand *say = FindCommand("say")) { if (ConCommand *say = FindCommand("say")) {
@ -145,9 +145,8 @@ void ChatTriggers::OnSourceModShutdown()
forwardsys->ReleaseForward(m_pOnClientSayCmd_Post); forwardsys->ReleaseForward(m_pOnClientSayCmd_Post);
} }
bool ChatTriggers::OnSayCommand_Pre(const ICommandArgs *command) bool ChatTriggers::OnSayCommand_Pre(int client, const ICommandArgs *command)
{ {
int client = g_ConCmds.GetCommandClient();
m_bIsChatTrigger = false; m_bIsChatTrigger = false;
m_bWasFloodedMessage = false; m_bWasFloodedMessage = false;
m_bPluginIgnored = true; m_bPluginIgnored = true;
@ -287,10 +286,8 @@ bool ChatTriggers::OnSayCommand_Pre(const ICommandArgs *command)
return false; return false;
} }
bool ChatTriggers::OnSayCommand_Post(const ICommandArgs *command) bool ChatTriggers::OnSayCommand_Post(int client, const ICommandArgs *command)
{ {
int client = g_ConCmds.GetCommandClient();
if (m_bWillProcessInPost) if (m_bWillProcessInPost)
{ {
/* Reset this for re-entrancy */ /* Reset this for re-entrancy */

View File

@ -56,8 +56,8 @@ public: //SMGlobalClass
char *error, char *error,
size_t maxlength); size_t maxlength);
private: //ConCommand private: //ConCommand
bool OnSayCommand_Pre(const ICommandArgs *args); bool OnSayCommand_Pre(int client, const ICommandArgs *args);
bool OnSayCommand_Post(const ICommandArgs *args); bool OnSayCommand_Post(int client, const ICommandArgs *args);
public: public:
unsigned int GetReplyTo(); unsigned int GetReplyTo();
unsigned int SetReplyTo(unsigned int reply); unsigned int SetReplyTo(unsigned int reply);

View File

@ -44,14 +44,11 @@ using namespace ke;
ConCmdManager g_ConCmds; ConCmdManager g_ConCmds;
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
typedef ke::LinkedList<CmdHook *> PluginHookList; typedef ke::LinkedList<CmdHook *> PluginHookList;
void RegisterInPlugin(CmdHook *hook); void RegisterInPlugin(CmdHook *hook);
ConCmdManager::ConCmdManager() ConCmdManager::ConCmdManager()
{ {
m_CmdClient = 0;
} }
ConCmdManager::~ConCmdManager() ConCmdManager::~ConCmdManager()
@ -62,14 +59,11 @@ void ConCmdManager::OnSourceModAllInitialized()
{ {
scripts->AddPluginsListener(this); scripts->AddPluginsListener(this);
rootmenu->AddRootConsoleCommand3("cmds", "List console commands", this); rootmenu->AddRootConsoleCommand3("cmds", "List console commands", this);
SH_ADD_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
} }
void ConCmdManager::OnSourceModShutdown() void ConCmdManager::OnSourceModShutdown()
{ {
scripts->RemovePluginsListener(this); scripts->RemovePluginsListener(this);
/* All commands should already be removed by the time we're done */
SH_REMOVE_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
rootmenu->RemoveRootConsoleCommand("cmds", this); rootmenu->RemoveRootConsoleCommand("cmds", this);
} }
@ -142,16 +136,11 @@ void CommandCallback(DISPATCH_ARGS)
EngineArgs args(command); EngineArgs args(command);
AutoEnterCommand autoEnterCommand(&args); AutoEnterCommand autoEnterCommand(&args);
if (g_ConCmds.InternalDispatch(&args)) if (g_ConCmds.InternalDispatch(sCoreProviderImpl.CommandClient(), &args))
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void ConCmdManager::SetCommandClient(int client)
{
m_CmdClient = client + 1;
}
ConCmdInfo *ConCmdManager::FindInTrie(const char *name) ConCmdInfo *ConCmdManager::FindInTrie(const char *name)
{ {
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
@ -218,10 +207,8 @@ ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int
return (ResultType)result; return (ResultType)result;
} }
bool ConCmdManager::InternalDispatch(const ICommandArgs *args) bool ConCmdManager::InternalDispatch(int client, const ICommandArgs *args)
{ {
int client = m_CmdClient;
if (client) if (client)
{ {
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client); CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
@ -604,9 +591,9 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
else else
{ {
TrackConCommandBase(pCmd, this); TrackConCommandBase(pCmd, this);
CommandHook::Callback callback = [this] (const ICommandArgs *args) -> bool { CommandHook::Callback callback = [this] (int client, const ICommandArgs *args) -> bool {
AutoEnterCommand autoEnterCommand(args); AutoEnterCommand autoEnterCommand(args);
return this->InternalDispatch(args); return this->InternalDispatch(client, args);
}; };
pInfo->sh_hook = sCoreProviderImpl.AddCommandHook(pCmd, callback); pInfo->sh_hook = sCoreProviderImpl.AddCommandHook(pCmd, callback);
} }

View File

@ -143,10 +143,9 @@ public:
bool LookForSourceModCommand(const char *cmd); bool LookForSourceModCommand(const char *cmd);
bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags); bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags);
private: private:
bool InternalDispatch(const ICommandArgs *args); bool InternalDispatch(int client, const ICommandArgs *args);
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags); ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
void SetCommandClient(int client);
void AddToCmdList(ConCmdInfo *info); void AddToCmdList(ConCmdInfo *info);
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack); void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack);
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin); bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
@ -157,10 +156,6 @@ private:
// Case sensitive // Case sensitive
ConCmdInfo *FindInTrie(const char *name); ConCmdInfo *FindInTrie(const char *name);
public: public:
inline int GetCommandClient()
{
return m_CmdClient;
}
inline const List<ConCmdInfo *> & GetCommandList() inline const List<ConCmdInfo *> & GetCommandList()
{ {
return m_CmdList; return m_CmdList;
@ -171,7 +166,6 @@ private:
StringHashMap<ConCmdInfo *> m_Cmds; /* command lookup */ StringHashMap<ConCmdInfo *> m_Cmds; /* command lookup */
GroupMap m_CmdGrps; /* command group map */ GroupMap m_CmdGrps; /* command group map */
ConCmdList m_CmdList; /* command list */ ConCmdList m_CmdList; /* command list */
int m_CmdClient; /* current client */
}; };
extern ConCmdManager g_ConCmds; extern ConCmdManager g_ConCmds;

View File

@ -51,6 +51,7 @@
#include "ConCommandBaseIterator.h" #include "ConCommandBaseIterator.h"
#include "logic_bridge.h" #include "logic_bridge.h"
#include "command_args.h" #include "command_args.h"
#include "provider.h"
#include <am-utility.h> #include <am-utility.h>
#include <bridge/include/ILogger.h> #include <bridge/include/ILogger.h>
@ -719,7 +720,7 @@ cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
cell_t res; cell_t res;
{ {
AutoEnterCommand autoEnterCommand(&cargs); AutoEnterCommand autoEnterCommand(&cargs);
res = g_ConsoleDetours.InternalDispatch(g_ConCmds.GetCommandClient(), &cargs); res = g_ConsoleDetours.InternalDispatch(sCoreProviderImpl.CommandClient(), &cargs);
} }
#if SH_IMPL_VERSION < 4 #if SH_IMPL_VERSION < 4

View File

@ -28,6 +28,7 @@
#include "sourcemod.h" #include "sourcemod.h"
#include "ConVarManager.h" #include "ConVarManager.h"
#include "command_args.h" #include "command_args.h"
#include "provider.h"
#if SOURCE_ENGINE >= SE_ORANGEBOX #if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float); SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
@ -51,8 +52,11 @@ SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#endif #endif
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
GameHooks::GameHooks() GameHooks::GameHooks()
: client_cvar_query_mode_(ClientCvarQueryMode::Unavailable) : client_cvar_query_mode_(ClientCvarQueryMode::Unavailable),
last_command_client_(-1)
{ {
} }
@ -72,6 +76,8 @@ void GameHooks::Start()
client_cvar_query_mode_ = ClientCvarQueryMode::DLL; client_cvar_query_mode_ = ClientCvarQueryMode::DLL;
} }
#endif #endif
hooks_ += SH_ADD_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &GameHooks::SetCommandClient), false);
} }
void GameHooks::OnVSPReceived() void GameHooks::OnVSPReceived()
@ -150,6 +156,11 @@ GameHooks::AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &call
return new CommandHook(cmd, callback, true); return new CommandHook(cmd, callback, true);
} }
void GameHooks::SetCommandClient(int client)
{
last_command_client_ = client + 1;
}
CommandHook::CommandHook(ConCommand *cmd, const Callback &callback, bool post) CommandHook::CommandHook(ConCommand *cmd, const Callback &callback, bool post)
: hook_id_(0), : hook_id_(0),
callback_(callback) callback_(callback)
@ -169,7 +180,7 @@ void CommandHook::Dispatch(DISPATCH_ARGS)
EngineArgs args(command); EngineArgs args(command);
AddRef(); AddRef();
bool rval = callback_(&args); bool rval = callback_(sCoreProviderImpl.CommandClient(), &args);
Release(); Release();
if (rval) if (rval)
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);

View File

@ -66,7 +66,7 @@ class CommandHook : public ke::Refcounted<CommandHook>
{ {
public: public:
// return false to RETURN_META(MRES_IGNORED), or true to SUPERCEDE. // return false to RETURN_META(MRES_IGNORED), or true to SUPERCEDE.
typedef ke::Lambda<bool(const ICommandArgs *)> Callback; typedef ke::Lambda<bool(int, const ICommandArgs *)> Callback;
public: public:
CommandHook(ConCommand *cmd, const Callback &callback, bool post); CommandHook(ConCommand *cmd, const Callback &callback, bool post);
@ -96,6 +96,10 @@ public:
ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback); ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback); ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
int CommandClient() const {
return last_command_client_;
}
private: private:
// Static callback that Valve's ConVar object executes when the convar's value changes. // Static callback that Valve's ConVar object executes when the convar's value changes.
#if SOURCE_ENGINE >= SE_ORANGEBOX #if SOURCE_ENGINE >= SE_ORANGEBOX
@ -113,6 +117,8 @@ private:
const char *cvarName, const char *cvarValue); const char *cvarName, const char *cvarValue);
#endif #endif
void SetCommandClient(int client);
private: private:
class HookList : public ke::Vector<int> class HookList : public ke::Vector<int>
{ {
@ -125,6 +131,7 @@ private:
HookList hooks_; HookList hooks_;
ClientCvarQueryMode client_cvar_query_mode_; ClientCvarQueryMode client_cvar_query_mode_;
int last_command_client_;
}; };
} // namespace SourceMod } // namespace SourceMod

View File

@ -68,6 +68,10 @@ public:
ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback); ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback); ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
int CommandClient() const {
return hooks_.CommandClient();
}
private: private:
ke::Ref<ke::SharedLib> logic_; ke::Ref<ke::SharedLib> logic_;
LogicInitFunction logic_init_; LogicInitFunction logic_init_;