added client-based console commands
extended console command functions to have an argument number renamed Result to Action --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40506
This commit is contained in:
parent
dcb10ee3a2
commit
76903cd919
@ -40,6 +40,7 @@ void CConCmdManager::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
void CConCmdManager::OnSourceModShutdown()
|
void CConCmdManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
|
/* All commands should already be removed by the time we're done */
|
||||||
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &CConCmdManager::SetCommandClient, false);
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &CConCmdManager::SetCommandClient, false);
|
||||||
g_RootMenu.RemoveRootConsoleCommand("cmds", this);
|
g_RootMenu.RemoveRootConsoleCommand("cmds", this);
|
||||||
g_PluginSys.RemovePluginsListener(this);
|
g_PluginSys.RemovePluginsListener(this);
|
||||||
@ -53,6 +54,7 @@ void CConCmdManager::OnPluginLoaded(IPlugin *plugin)
|
|||||||
void CConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
void CConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
||||||
{
|
{
|
||||||
CmdList *pList;
|
CmdList *pList;
|
||||||
|
List<ConCmdInfo *> removed;
|
||||||
if (plugin->GetProperty("CommandList", (void **)&pList, true))
|
if (plugin->GetProperty("CommandList", (void **)&pList, true))
|
||||||
{
|
{
|
||||||
CmdList::iterator iter;
|
CmdList::iterator iter;
|
||||||
@ -65,14 +67,25 @@ void CConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
|||||||
|| cmd.type == Cmd_Console)
|
|| cmd.type == Cmd_Console)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo = cmd.pInfo;
|
ConCmdInfo *pInfo = cmd.pInfo;
|
||||||
|
/* See if this is being removed */
|
||||||
|
if (removed.find(pInfo) != removed.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/* See if there are still hooks */
|
/* See if there are still hooks */
|
||||||
if (pInfo->srvhooks
|
if (pInfo->srvhooks
|
||||||
&& pInfo->srvhooks->GetFunctionCount())
|
&& pInfo->srvhooks->GetFunctionCount())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (pInfo->conhooks
|
||||||
|
&& pInfo->conhooks->GetFunctionCount())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/* Remove the command */
|
/* Remove the command */
|
||||||
RemoveConCmd(pInfo);
|
RemoveConCmd(pInfo);
|
||||||
|
removed.push_back(pInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete pList;
|
delete pList;
|
||||||
@ -89,12 +102,39 @@ void CConCmdManager::SetCommandClient(int client)
|
|||||||
m_CmdClient = client + 1;
|
m_CmdClient = client + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type)
|
||||||
|
{
|
||||||
|
const char *cmd = engine->Cmd_Argv(0);
|
||||||
|
int args = engine->Cmd_Argc() - 1;
|
||||||
|
|
||||||
|
ConCmdInfo *pInfo;
|
||||||
|
if (sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
||||||
|
{
|
||||||
|
cell_t result = type;
|
||||||
|
if (pInfo->conhooks && pInfo->conhooks->GetFunctionCount())
|
||||||
|
{
|
||||||
|
pInfo->conhooks->PushCell(client);
|
||||||
|
pInfo->conhooks->PushCell(args);
|
||||||
|
pInfo->conhooks->Execute(&result);
|
||||||
|
}
|
||||||
|
if (result >= Pl_Stop)
|
||||||
|
{
|
||||||
|
return Pl_Stop;
|
||||||
|
}
|
||||||
|
type = (ResultType)result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
void CConCmdManager::InternalDispatch()
|
void CConCmdManager::InternalDispatch()
|
||||||
{
|
{
|
||||||
if (m_CmdClient)
|
/**
|
||||||
{
|
* Note: Console commands will EITHER go through IServerGameDLL::ClientCommand,
|
||||||
return;
|
* OR this dispatch. They will NEVER go through both.
|
||||||
}
|
* --
|
||||||
|
* Whether or not it goes through the callback is determined by FCVAR_GAMEDLL
|
||||||
|
*/
|
||||||
|
|
||||||
const char *cmd = engine->Cmd_Argv(0);
|
const char *cmd = engine->Cmd_Argv(0);
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
@ -104,11 +144,35 @@ void CConCmdManager::InternalDispatch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell_t result = Pl_Continue;
|
cell_t result = Pl_Continue;
|
||||||
if (pInfo->srvhooks)
|
int args = engine->Cmd_Argc() - 1;
|
||||||
|
|
||||||
|
if (m_CmdClient == 0)
|
||||||
{
|
{
|
||||||
|
if (pInfo->srvhooks && pInfo->srvhooks->GetFunctionCount())
|
||||||
|
{
|
||||||
|
pInfo->srvhooks->PushCell(args);
|
||||||
pInfo->srvhooks->Execute(&result);
|
pInfo->srvhooks->Execute(&result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if there's an early stop */
|
||||||
|
if (result >= Pl_Stop)
|
||||||
|
{
|
||||||
|
if (!pInfo->sourceMod)
|
||||||
|
{
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute console command hooks */
|
||||||
|
if (pInfo->conhooks && pInfo->conhooks->GetFunctionCount())
|
||||||
|
{
|
||||||
|
pInfo->conhooks->PushCell(m_CmdClient);
|
||||||
|
pInfo->conhooks->PushCell(args);
|
||||||
|
pInfo->conhooks->Execute(&result);
|
||||||
|
}
|
||||||
|
|
||||||
if (result >= Pl_Handled)
|
if (result >= Pl_Handled)
|
||||||
{
|
{
|
||||||
if (!pInfo->sourceMod)
|
if (!pInfo->sourceMod)
|
||||||
@ -119,6 +183,34 @@ void CConCmdManager::InternalDispatch()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction,
|
||||||
|
const char *name,
|
||||||
|
const char *description,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||||
|
|
||||||
|
if (!pInfo->conhooks)
|
||||||
|
{
|
||||||
|
pInfo->conhooks = g_Forwards.CreateForwardEx(NULL, ET_Hook, 2, NULL, Param_Cell, Param_Cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->conhooks->AddFunction(pFunction);
|
||||||
|
|
||||||
|
/* Add to the plugin */
|
||||||
|
CmdList *pList;
|
||||||
|
IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||||
|
{
|
||||||
|
pList = new CmdList();
|
||||||
|
pPlugin->SetProperty("CommandList", pList);
|
||||||
|
}
|
||||||
|
PlCmdInfo info;
|
||||||
|
info.pInfo = pInfo;
|
||||||
|
info.type = Cmd_Console;
|
||||||
|
pList->push_back(info);
|
||||||
|
}
|
||||||
|
|
||||||
void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *description,
|
const char *description,
|
||||||
@ -144,7 +236,7 @@ void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
|||||||
}
|
}
|
||||||
PlCmdInfo info;
|
PlCmdInfo info;
|
||||||
info.pInfo = pInfo;
|
info.pInfo = pInfo;
|
||||||
info.type = Cmd_Console;
|
info.type = Cmd_Server;
|
||||||
pList->push_back(info);
|
pList->push_back(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +403,6 @@ void CConCmdManager::OnRootConsoleCommand(const char *command, unsigned int argc
|
|||||||
name = cmd.pInfo->pCmd->GetName();
|
name = cmd.pInfo->pCmd->GetName();
|
||||||
help = cmd.pInfo->pCmd->GetHelpText();
|
help = cmd.pInfo->pCmd->GetHelpText();
|
||||||
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -38,10 +38,12 @@ struct ConCmdInfo
|
|||||||
sourceMod = false;
|
sourceMod = false;
|
||||||
pCmd = NULL;
|
pCmd = NULL;
|
||||||
srvhooks = NULL;
|
srvhooks = NULL;
|
||||||
|
conhooks = NULL;
|
||||||
}
|
}
|
||||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||||
ConCommand *pCmd; /**< Pointer to the command itself */
|
ConCommand *pCmd; /**< Pointer to the command itself */
|
||||||
IChangeableForward *srvhooks; /**< Hooks on this name as a server command */
|
IChangeableForward *srvhooks; /**< Hooks on this name as a server command */
|
||||||
|
IChangeableForward *conhooks; /**< Hooks on this name as a console command */
|
||||||
};
|
};
|
||||||
|
|
||||||
class CConCmdManager :
|
class CConCmdManager :
|
||||||
@ -63,6 +65,8 @@ public: //IRootConsoleCommand
|
|||||||
void OnRootConsoleCommand(const char *command, unsigned int argcount);
|
void OnRootConsoleCommand(const char *command, unsigned int argcount);
|
||||||
public:
|
public:
|
||||||
void AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
|
void AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
|
||||||
|
void AddConsoleCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
|
||||||
|
ResultType DispatchClientCommand(int client, ResultType type);
|
||||||
private:
|
private:
|
||||||
void InternalDispatch();
|
void InternalDispatch();
|
||||||
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
|
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "ForwardSys.h"
|
#include "ForwardSys.h"
|
||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
#include "AdminCache.h"
|
#include "AdminCache.h"
|
||||||
|
#include "CConCmdManager.h"
|
||||||
|
|
||||||
CPlayerManager g_Players;
|
CPlayerManager g_Players;
|
||||||
|
|
||||||
@ -51,15 +52,14 @@ void CPlayerManager::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
|
ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
|
||||||
ParamType p2[] = {Param_Cell};
|
ParamType p2[] = {Param_Cell};
|
||||||
ParamType p3[] = {Param_Cell, Param_String};
|
|
||||||
|
|
||||||
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
|
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
|
||||||
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
|
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
|
||||||
m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
|
m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
|
||||||
m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
|
m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
|
||||||
m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 1, p2);
|
m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 2, NULL, Param_Cell, Param_Cell);
|
||||||
m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
|
m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
|
||||||
m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, p3);
|
m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerManager::OnSourceModShutdown()
|
void CPlayerManager::OnSourceModShutdown()
|
||||||
@ -197,6 +197,7 @@ bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, cons
|
|||||||
g_SourceMod.SetAuthChecking(true);
|
g_SourceMod.SetAuthChecking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//:todo: this must meta return
|
||||||
return (res) ? true : false;
|
return (res) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,10 +329,26 @@ void CPlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
|
|||||||
|
|
||||||
void CPlayerManager::OnClientCommand(edict_t *pEntity)
|
void CPlayerManager::OnClientCommand(edict_t *pEntity)
|
||||||
{
|
{
|
||||||
cell_t res;
|
cell_t res = Pl_Continue;
|
||||||
|
int client = engine->IndexOfEdict(pEntity);
|
||||||
|
|
||||||
m_clcommand->PushCell(engine->IndexOfEdict(pEntity));
|
int args = engine->Cmd_Argc() - 1;
|
||||||
|
|
||||||
|
m_clcommand->PushCell(client);
|
||||||
|
m_clcommand->PushCell(args);
|
||||||
m_clcommand->Execute(&res, NULL);
|
m_clcommand->Execute(&res, NULL);
|
||||||
|
|
||||||
|
if (res >= Pl_Stop)
|
||||||
|
{
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = g_ConCmds.DispatchClientCommand(client, (ResultType)res);
|
||||||
|
|
||||||
|
if (res >= Pl_Handled)
|
||||||
|
{
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerManager::OnClientSettingsChanged(edict_t *pEntity)
|
void CPlayerManager::OnClientSettingsChanged(edict_t *pEntity)
|
||||||
|
@ -342,6 +342,25 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
char *name,*help;
|
||||||
|
IPluginFunction *pFunction;
|
||||||
|
|
||||||
|
pContext->LocalToString(params[1], &name);
|
||||||
|
pContext->LocalToString(params[3], &help);
|
||||||
|
pFunction = pContext->GetFunctionById(params[2]);
|
||||||
|
|
||||||
|
if (!pFunction)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ConCmds.AddConsoleCommand(pFunction, name, help, params[4]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
REGISTER_NATIVES(convarNatives)
|
REGISTER_NATIVES(convarNatives)
|
||||||
{
|
{
|
||||||
{"CreateConVar", sm_CreateConVar},
|
{"CreateConVar", sm_CreateConVar},
|
||||||
@ -363,5 +382,6 @@ REGISTER_NATIVES(convarNatives)
|
|||||||
{"GetConVarMax", sm_GetConVarMax},
|
{"GetConVarMax", sm_GetConVarMax},
|
||||||
{"ResetConVar", sm_ResetConVar},
|
{"ResetConVar", sm_ResetConVar},
|
||||||
{"RegServerCmd", sm_RegServerCmd},
|
{"RegServerCmd", sm_RegServerCmd},
|
||||||
|
{"RegConsoleCmd", sm_RegConsoleCmd},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -79,7 +79,7 @@ native PrintToConsole(client, const String:format[], {Handle,Float,String,_}:...
|
|||||||
* @return A Result value. Not handling the command
|
* @return A Result value. Not handling the command
|
||||||
* means that Source will report it as "not found."
|
* means that Source will report it as "not found."
|
||||||
*/
|
*/
|
||||||
functag SrvCmd Action:public();
|
functag SrvCmd Action:public(argCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a server-only console command, or hooks an already existing one.
|
* Creates a server-only console command, or hooks an already existing one.
|
||||||
@ -92,7 +92,6 @@ functag SrvCmd Action:public();
|
|||||||
*/
|
*/
|
||||||
native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0);
|
native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0);
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
/**
|
||||||
* Called when a generic console command is invoked.
|
* Called when a generic console command is invoked.
|
||||||
*
|
*
|
||||||
@ -100,7 +99,7 @@ native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:descriptio
|
|||||||
* @return A Result value. Not handling the command
|
* @return A Result value. Not handling the command
|
||||||
* means that Source will report it as "not found."
|
* means that Source will report it as "not found."
|
||||||
*/
|
*/
|
||||||
functag ConCmd Action:public(client);
|
functag ConCmd Action:public(client, argCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a console command, or hooks an already existing one.
|
* Creates a console command, or hooks an already existing one.
|
||||||
@ -113,6 +112,7 @@ functag ConCmd Action:public(client);
|
|||||||
*/
|
*/
|
||||||
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
|
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* Hooks a specific client-only command.
|
* Hooks a specific client-only command.
|
||||||
*
|
*
|
||||||
|
@ -128,7 +128,7 @@ forward OnClientDisconnect_Post(client);
|
|||||||
* @param client Player index.
|
* @param client Player index.
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
forward OnClientCommand(client);
|
forward OnClientCommand(client, argCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever the client's settings are changed.
|
* Called whenever the client's settings are changed.
|
||||||
|
Loading…
Reference in New Issue
Block a user