Move ConCommand hooks into GameHooks and switch callbacks to ICommandArgs.
This commit is contained in:
parent
b63bfdc72a
commit
b048dc7b10
@ -36,20 +36,14 @@
|
|||||||
#include "ChatTriggers.h"
|
#include "ChatTriggers.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
|
#include "provider.h"
|
||||||
|
#include "command_args.h"
|
||||||
#include <bridge/include/IScriptManager.h>
|
#include <bridge/include/IScriptManager.h>
|
||||||
|
|
||||||
using namespace ke;
|
using namespace ke;
|
||||||
|
|
||||||
ConCmdManager g_ConCmds;
|
ConCmdManager g_ConCmds;
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
SH_DECL_HOOK2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
|
||||||
#else
|
|
||||||
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
|
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
|
||||||
|
|
||||||
typedef ke::LinkedList<CmdHook *> PluginHookList;
|
typedef ke::LinkedList<CmdHook *> PluginHookList;
|
||||||
@ -142,23 +136,13 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
|||||||
delete pList;
|
delete pList;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
void CommandCallback(DISPATCH_ARGS)
|
||||||
void CommandCallback(const CCommandContext &context, const CCommand &command)
|
|
||||||
{
|
{
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
DISPATCH_PROLOGUE;
|
||||||
void CommandCallback(const CCommand &command)
|
EngineArgs args(command);
|
||||||
{
|
|
||||||
#else
|
|
||||||
void CommandCallback()
|
|
||||||
{
|
|
||||||
CCommand command;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_HL2.PushCommandStack(&command);
|
AutoEnterCommand autoEnterCommand(&args);
|
||||||
|
g_ConCmds.InternalDispatch(&args);
|
||||||
g_ConCmds.InternalDispatch(command);
|
|
||||||
|
|
||||||
g_HL2.PopCommandStack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::SetCommandClient(int client)
|
void ConCmdManager::SetCommandClient(int client)
|
||||||
@ -232,7 +216,7 @@ ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int
|
|||||||
return (ResultType)result;
|
return (ResultType)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::InternalDispatch(const CCommand &command)
|
void ConCmdManager::InternalDispatch(const ICommandArgs *args)
|
||||||
{
|
{
|
||||||
int client = m_CmdClient;
|
int client = m_CmdClient;
|
||||||
|
|
||||||
@ -275,7 +259,7 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
cell_t result = Pl_Continue;
|
cell_t result = Pl_Continue;
|
||||||
int args = command.ArgC() - 1;
|
int argc = args->ArgC() - 1;
|
||||||
|
|
||||||
// On a listen server, sometimes the server host's client index can be set
|
// On a listen server, sometimes the server host's client index can be set
|
||||||
// as 0. So index 1 is passed to the command callback to correct this
|
// as 0. So index 1 is passed to the command callback to correct this
|
||||||
@ -311,7 +295,7 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
|||||||
hook->pf->PushCell(realClient);
|
hook->pf->PushCell(realClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->pf->PushCell(args);
|
hook->pf->PushCell(argc);
|
||||||
|
|
||||||
cell_t tempres = result;
|
cell_t tempres = result;
|
||||||
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||||
@ -556,17 +540,14 @@ void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_rea
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (is_read_safe)
|
// If it's not safe to read the pointer, we zap the SourceHook hook so it
|
||||||
{
|
// doesn't attempt to access the pointer's vtable.
|
||||||
/* Remove the external hook */
|
if (!is_read_safe)
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, info->pCmd, SH_STATIC(CommandCallback), false);
|
info->sh_hook->Zap();
|
||||||
}
|
|
||||||
if (untrack)
|
if (untrack)
|
||||||
{
|
|
||||||
UntrackConCommandBase(info->pCmd, this);
|
UntrackConCommandBase(info->pCmd, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove from list */
|
/* Remove from list */
|
||||||
m_CmdList.remove(info);
|
m_CmdList.remove(info);
|
||||||
@ -623,7 +604,11 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
TrackConCommandBase(pCmd, this);
|
TrackConCommandBase(pCmd, this);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, pCmd, SH_STATIC(CommandCallback), false);
|
CommandHook::Callback callback = [this] (const ICommandArgs *args) {
|
||||||
|
AutoEnterCommand autoEnterCommand(args);
|
||||||
|
this->InternalDispatch(args);
|
||||||
|
};
|
||||||
|
pInfo->sh_hook = sCoreProviderImpl.AddCommandHook(pCmd, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->pCmd = pCmd;
|
pInfo->pCmd = pCmd;
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
#include <IAdminSystem.h>
|
#include <IAdminSystem.h>
|
||||||
#include "concmd_cleaner.h"
|
#include "concmd_cleaner.h"
|
||||||
|
#include "GameHooks.h"
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_stringhashmap.h>
|
||||||
#include <am-utility.h>
|
#include <am-utility.h>
|
||||||
#include <am-inlinelist.h>
|
#include <am-inlinelist.h>
|
||||||
@ -105,6 +106,7 @@ struct ConCmdInfo
|
|||||||
ConCommand *pCmd; /**< Pointer to the command itself */
|
ConCommand *pCmd; /**< Pointer to the command itself */
|
||||||
CmdHookList hooks; /**< Hook list */
|
CmdHookList hooks; /**< Hook list */
|
||||||
FlagBits eflags; /**< Effective admin flags */
|
FlagBits eflags; /**< Effective admin flags */
|
||||||
|
ke::Ref<CommandHook> sh_hook; /**< SourceHook hook, if any. */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef List<ConCmdInfo *> ConCmdList;
|
typedef List<ConCmdInfo *> ConCmdList;
|
||||||
@ -115,13 +117,7 @@ class ConCmdManager :
|
|||||||
public IPluginsListener,
|
public IPluginsListener,
|
||||||
public IConCommandTracker
|
public IConCommandTracker
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
friend void CommandCallback(DISPATCH_ARGS);
|
||||||
friend void CommandCallback(const CCommandContext &context, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
friend void CommandCallback(const CCommand &command);
|
|
||||||
#else
|
|
||||||
friend void CommandCallback();
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
ConCmdManager();
|
ConCmdManager();
|
||||||
~ConCmdManager();
|
~ConCmdManager();
|
||||||
@ -147,7 +143,7 @@ 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:
|
||||||
void InternalDispatch(const CCommand &command);
|
void InternalDispatch(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 SetCommandClient(int client);
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "ConCommandBaseIterator.h"
|
#include "ConCommandBaseIterator.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
|
#include "command_args.h"
|
||||||
#include <am-utility.h>
|
#include <am-utility.h>
|
||||||
#include <bridge/include/ILogger.h>
|
#include <bridge/include/ILogger.h>
|
||||||
|
|
||||||
@ -653,10 +654,10 @@ bool ConsoleDetours::RemoveListener(IPluginFunction *fun, const char *command)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
|
cell_t ConsoleDetours::InternalDispatch(int client, const ICommandArgs *args)
|
||||||
{
|
{
|
||||||
char name[255];
|
char name[255];
|
||||||
const char *realname = args.Arg(0);
|
const char *realname = args->Arg(0);
|
||||||
size_t len = strlen(realname);
|
size_t len = strlen(realname);
|
||||||
|
|
||||||
// Disallow command strings that are too long, for now.
|
// Disallow command strings that are too long, for now.
|
||||||
@ -675,7 +676,7 @@ cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
|
|||||||
cell_t result = Pl_Continue;
|
cell_t result = Pl_Continue;
|
||||||
m_pForward->PushCell(client);
|
m_pForward->PushCell(client);
|
||||||
m_pForward->PushString(name);
|
m_pForward->PushString(name);
|
||||||
m_pForward->PushCell(args.ArgC() - 1);
|
m_pForward->PushCell(args->ArgC() - 1);
|
||||||
m_pForward->Execute(&result, NULL);
|
m_pForward->Execute(&result, NULL);
|
||||||
|
|
||||||
/* Don't let plugins block this. */
|
/* Don't let plugins block this. */
|
||||||
@ -694,7 +695,7 @@ cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
|
|||||||
cell_t result2 = Pl_Continue;
|
cell_t result2 = Pl_Continue;
|
||||||
forward->PushCell(client);
|
forward->PushCell(client);
|
||||||
forward->PushString(name);
|
forward->PushString(name);
|
||||||
forward->PushCell(args.ArgC() - 1);
|
forward->PushCell(args->ArgC() - 1);
|
||||||
forward->Execute(&result2, NULL);
|
forward->Execute(&result2, NULL);
|
||||||
|
|
||||||
if (result2 > result)
|
if (result2 > result)
|
||||||
@ -714,9 +715,12 @@ cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
|
|||||||
{
|
{
|
||||||
CCommand args;
|
CCommand args;
|
||||||
#endif
|
#endif
|
||||||
g_HL2.PushCommandStack(&args);
|
EngineArgs cargs(args);
|
||||||
cell_t res = g_ConsoleDetours.InternalDispatch(g_ConCmds.GetCommandClient(), args);
|
cell_t res;
|
||||||
g_HL2.PopCommandStack();
|
{
|
||||||
|
AutoEnterCommand autoEnterCommand(&cargs);
|
||||||
|
res = g_ConsoleDetours.InternalDispatch(g_ConCmds.GetCommandClient(), &cargs);
|
||||||
|
}
|
||||||
|
|
||||||
#if SH_IMPL_VERSION < 4
|
#if SH_IMPL_VERSION < 4
|
||||||
if (res >= Pl_Handled)
|
if (res >= Pl_Handled)
|
||||||
|
@ -36,6 +36,10 @@
|
|||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_stringhashmap.h>
|
||||||
|
|
||||||
|
namespace SourceMod {
|
||||||
|
class ICommandArgs;
|
||||||
|
} // namespace SourceMod
|
||||||
|
|
||||||
class ConsoleDetours :
|
class ConsoleDetours :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IFeatureProvider
|
public IFeatureProvider
|
||||||
@ -54,7 +58,7 @@ public:
|
|||||||
bool AddListener(IPluginFunction *fun, const char *command);
|
bool AddListener(IPluginFunction *fun, const char *command);
|
||||||
bool RemoveListener(IPluginFunction *fun, const char *command);
|
bool RemoveListener(IPluginFunction *fun, const char *command);
|
||||||
private:
|
private:
|
||||||
cell_t InternalDispatch(int client, const CCommand& args);
|
cell_t InternalDispatch(int client, const SourceMod::ICommandArgs *args);
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
static cell_t Dispatch(ConCommand *pBase, const CCommand& args);
|
static cell_t Dispatch(ConCommand *pBase, const CCommand& args);
|
||||||
#else
|
#else
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "GameHooks.h"
|
#include "GameHooks.h"
|
||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
#include "ConVarManager.h"
|
#include "ConVarManager.h"
|
||||||
|
#include "command_args.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);
|
||||||
@ -42,6 +43,14 @@ SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, Que
|
|||||||
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
|
SH_DECL_HOOK2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
||||||
|
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
|
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
|
#else
|
||||||
|
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
GameHooks::GameHooks()
|
GameHooks::GameHooks()
|
||||||
: client_cvar_query_mode_(ClientCvarQueryMode::Unavailable)
|
: client_cvar_query_mode_(ClientCvarQueryMode::Unavailable)
|
||||||
{
|
{
|
||||||
@ -128,3 +137,43 @@ void GameHooks::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPla
|
|||||||
g_ConVarManager.OnClientQueryFinished(cookie, client, result, cvarName, cvarValue);
|
g_ConVarManager.OnClientQueryFinished(cookie, client, result, cvarName, cvarValue);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ke::PassRef<CommandHook>
|
||||||
|
GameHooks::AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback)
|
||||||
|
{
|
||||||
|
return new CommandHook(cmd, callback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ke::PassRef<CommandHook>
|
||||||
|
GameHooks::AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback)
|
||||||
|
{
|
||||||
|
return new CommandHook(cmd, callback, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandHook::CommandHook(ConCommand *cmd, const Callback &callback, bool post)
|
||||||
|
: hook_id_(0),
|
||||||
|
callback_(callback)
|
||||||
|
{
|
||||||
|
hook_id_ = SH_ADD_HOOK(ConCommand, Dispatch, cmd, SH_MEMBER(this, &CommandHook::Dispatch), post);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandHook::~CommandHook()
|
||||||
|
{
|
||||||
|
if (hook_id_)
|
||||||
|
SH_REMOVE_HOOK_ID(hook_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandHook::Dispatch(DISPATCH_ARGS)
|
||||||
|
{
|
||||||
|
DISPATCH_PROLOGUE;
|
||||||
|
EngineArgs args(command);
|
||||||
|
|
||||||
|
AddRef();
|
||||||
|
callback_(&args);
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommandHook::Zap()
|
||||||
|
{
|
||||||
|
hook_id_ = 0;
|
||||||
|
}
|
||||||
|
@ -32,18 +32,52 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <eiface.h>
|
#include <eiface.h>
|
||||||
#include <iserverplugin.h>
|
#include <iserverplugin.h>
|
||||||
|
#include <amtl/am-refcounting.h>
|
||||||
#include <amtl/am-vector.h>
|
#include <amtl/am-vector.h>
|
||||||
|
#include <amtl/am-function.h>
|
||||||
|
|
||||||
class ConVar;
|
class ConVar;
|
||||||
|
class CCommand;
|
||||||
|
struct CCommandContext;
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_DOTA
|
||||||
|
# define DISPATCH_ARGS const CCommandContext &context, const CCommand &command
|
||||||
|
# define DISPATCH_PROLOGUE
|
||||||
|
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
|
# define DISPATCH_ARGS const CCommand &command
|
||||||
|
# define DISPATCH_PROLOGUE
|
||||||
|
#else
|
||||||
|
# define DISPATCH_ARGS
|
||||||
|
# define DISPATCH_PROLOGUE CCommand command
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace SourceMod {
|
namespace SourceMod {
|
||||||
|
|
||||||
|
// Describes the mechanism in which client cvar queries are implemented.
|
||||||
enum class ClientCvarQueryMode {
|
enum class ClientCvarQueryMode {
|
||||||
Unavailable,
|
Unavailable,
|
||||||
DLL,
|
DLL,
|
||||||
VSP
|
VSP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ICommandArgs;
|
||||||
|
|
||||||
|
class CommandHook : public ke::Refcounted<CommandHook>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef ke::Lambda<void(const ICommandArgs *)> Callback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CommandHook(ConCommand *cmd, const Callback &callback, bool post);
|
||||||
|
~CommandHook();
|
||||||
|
void Dispatch(DISPATCH_ARGS);
|
||||||
|
void Zap();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int hook_id_;
|
||||||
|
Callback callback_;
|
||||||
|
};
|
||||||
|
|
||||||
class GameHooks
|
class GameHooks
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -57,6 +91,10 @@ public:
|
|||||||
return client_cvar_query_mode_;
|
return client_cvar_query_mode_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
|
||||||
|
ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
|
||||||
|
|
||||||
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
|
||||||
|
@ -825,7 +825,7 @@ bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHalfLife2::PushCommandStack(const CCommand *cmd)
|
void CHalfLife2::PushCommandStack(const ICommandArgs *cmd)
|
||||||
{
|
{
|
||||||
CachedCommandInfo info;
|
CachedCommandInfo info;
|
||||||
|
|
||||||
@ -837,7 +837,7 @@ void CHalfLife2::PushCommandStack(const CCommand *cmd)
|
|||||||
m_CommandStack.push(info);
|
m_CommandStack.push(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CCommand *CHalfLife2::PeekCommandStack()
|
const ICommandArgs *CHalfLife2::PeekCommandStack()
|
||||||
{
|
{
|
||||||
if (m_CommandStack.empty())
|
if (m_CommandStack.empty())
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,9 @@
|
|||||||
#include <tier0/icommandline.h>
|
#include <tier0/icommandline.h>
|
||||||
#include <string_t.h>
|
#include <string_t.h>
|
||||||
|
|
||||||
class CCommand;
|
namespace SourceMod {
|
||||||
|
class ICommandArgs;
|
||||||
|
} // namespace SourceMod
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
@ -100,7 +102,7 @@ struct DelayedFakeCliCmd
|
|||||||
|
|
||||||
struct CachedCommandInfo
|
struct CachedCommandInfo
|
||||||
{
|
{
|
||||||
const CCommand *args;
|
const ICommandArgs *args;
|
||||||
#if SOURCE_ENGINE <= SE_DARKMESSIAH
|
#if SOURCE_ENGINE <= SE_DARKMESSIAH
|
||||||
char cmd[300];
|
char cmd[300];
|
||||||
#endif
|
#endif
|
||||||
@ -141,6 +143,7 @@ class CHalfLife2 :
|
|||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IGameHelpers
|
public IGameHelpers
|
||||||
{
|
{
|
||||||
|
friend class AutoEnterCommand;
|
||||||
public:
|
public:
|
||||||
CHalfLife2();
|
CHalfLife2();
|
||||||
~CHalfLife2();
|
~CHalfLife2();
|
||||||
@ -190,9 +193,7 @@ public:
|
|||||||
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
|
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
|
||||||
void ProcessFakeCliCmdQueue();
|
void ProcessFakeCliCmdQueue();
|
||||||
public:
|
public:
|
||||||
void PushCommandStack(const CCommand *cmd);
|
const ICommandArgs *PeekCommandStack();
|
||||||
void PopCommandStack();
|
|
||||||
const CCommand *PeekCommandStack();
|
|
||||||
const char *CurrentCommandName();
|
const char *CurrentCommandName();
|
||||||
void AddDelayedKick(int client, int userid, const char *msg);
|
void AddDelayedKick(int client, int userid, const char *msg);
|
||||||
void ProcessDelayedKicks();
|
void ProcessDelayedKicks();
|
||||||
@ -200,6 +201,8 @@ public:
|
|||||||
bool IsOriginalEngine();
|
bool IsOriginalEngine();
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
|
void PushCommandStack(const ICommandArgs *cmd);
|
||||||
|
void PopCommandStack();
|
||||||
DataTableInfo *_FindServerClass(const char *classname);
|
DataTableInfo *_FindServerClass(const char *classname);
|
||||||
private:
|
private:
|
||||||
void InitLogicalEntData();
|
void InitLogicalEntData();
|
||||||
@ -224,4 +227,15 @@ extern CHalfLife2 g_HL2;
|
|||||||
|
|
||||||
bool IndexToAThings(cell_t, CBaseEntity **pEntData, edict_t **pEdictData);
|
bool IndexToAThings(cell_t, CBaseEntity **pEntData, edict_t **pEdictData);
|
||||||
|
|
||||||
|
class AutoEnterCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoEnterCommand(const ICommandArgs *args) {
|
||||||
|
g_HL2.PushCommandStack(args);
|
||||||
|
}
|
||||||
|
~AutoEnterCommand() {
|
||||||
|
g_HL2.PopCommandStack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_
|
#endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include <sourcemod_version.h>
|
#include <sourcemod_version.h>
|
||||||
#include "smn_keyvalues.h"
|
#include "smn_keyvalues.h"
|
||||||
|
#include "command_args.h"
|
||||||
#include <ITranslator.h>
|
#include <ITranslator.h>
|
||||||
#include <bridge/include/IExtensionBridge.h>
|
#include <bridge/include/IExtensionBridge.h>
|
||||||
#include <bridge/include/IScriptManager.h>
|
#include <bridge/include/IScriptManager.h>
|
||||||
@ -1180,7 +1181,8 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
|
|||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_HL2.PushCommandStack(&args);
|
EngineArgs cargs(args);
|
||||||
|
AutoEnterCommand autoEnterCommand(&cargs);
|
||||||
|
|
||||||
int argcount = args.ArgC() - 1;
|
int argcount = args.ArgC() - 1;
|
||||||
const char *cmd = g_HL2.CurrentCommandName();
|
const char *cmd = g_HL2.CurrentCommandName();
|
||||||
@ -1199,10 +1201,9 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
|
|||||||
|
|
||||||
if (g_ConsoleDetours.IsEnabled())
|
if (g_ConsoleDetours.IsEnabled())
|
||||||
{
|
{
|
||||||
cell_t res2 = g_ConsoleDetours.InternalDispatch(client, args);
|
cell_t res2 = g_ConsoleDetours.InternalDispatch(client, &cargs);
|
||||||
if (res2 >= Pl_Stop)
|
if (res2 >= Pl_Stop)
|
||||||
{
|
{
|
||||||
g_HL2.PopCommandStack();
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
else if (res2 > res)
|
else if (res2 > res)
|
||||||
@ -1226,14 +1227,11 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
|
|||||||
|
|
||||||
if (res >= Pl_Stop)
|
if (res >= Pl_Stop)
|
||||||
{
|
{
|
||||||
g_HL2.PopCommandStack();
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = g_ConCmds.DispatchClientCommand(client, cmd, argcount, (ResultType)res);
|
res = g_ConCmds.DispatchClientCommand(client, cmd, argcount, (ResultType)res);
|
||||||
|
|
||||||
g_HL2.PopCommandStack();
|
|
||||||
|
|
||||||
if (res >= Pl_Handled)
|
if (res >= Pl_Handled)
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
@ -742,6 +742,18 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ke::PassRef<CommandHook>
|
||||||
|
CoreProviderImpl::AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback)
|
||||||
|
{
|
||||||
|
return hooks_.AddCommandHook(cmd, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
ke::PassRef<CommandHook>
|
||||||
|
CoreProviderImpl::AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback)
|
||||||
|
{
|
||||||
|
return hooks_.AddPostCommandHook(cmd, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void CoreProviderImpl::InitializeHooks()
|
void CoreProviderImpl::InitializeHooks()
|
||||||
{
|
{
|
||||||
hooks_.Start();
|
hooks_.Start();
|
||||||
|
@ -65,6 +65,9 @@ public:
|
|||||||
int QueryClientConVar(int client, const char *cvar) override;
|
int QueryClientConVar(int client, const char *cvar) override;
|
||||||
bool IsClientConVarQueryingSupported() override;
|
bool IsClientConVarQueryingSupported() override;
|
||||||
|
|
||||||
|
ke::PassRef<CommandHook> AddCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
|
||||||
|
ke::PassRef<CommandHook> AddPostCommandHook(ConCommand *cmd, const CommandHook::Callback &callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ke::Ref<ke::SharedLib> logic_;
|
ke::Ref<ke::SharedLib> logic_;
|
||||||
LogicInitFunction logic_init_;
|
LogicInitFunction logic_init_;
|
||||||
|
@ -784,7 +784,7 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
const CCommand *pCmd = g_HL2.PeekCommandStack();
|
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||||
|
|
||||||
if (!pCmd)
|
if (!pCmd)
|
||||||
{
|
{
|
||||||
@ -796,7 +796,7 @@ static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
const CCommand *pCmd = g_HL2.PeekCommandStack();
|
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||||
|
|
||||||
if (!pCmd)
|
if (!pCmd)
|
||||||
{
|
{
|
||||||
@ -814,7 +814,7 @@ static cell_t sm_GetCmdArg(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
|
static cell_t sm_GetCmdArgString(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
const CCommand *pCmd = g_HL2.PeekCommandStack();
|
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
|
||||||
|
|
||||||
if (!pCmd)
|
if (!pCmd)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user