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()
|
||||
{
|
||||
/* All commands should already be removed by the time we're done */
|
||||
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &CConCmdManager::SetCommandClient, false);
|
||||
g_RootMenu.RemoveRootConsoleCommand("cmds", this);
|
||||
g_PluginSys.RemovePluginsListener(this);
|
||||
@ -53,6 +54,7 @@ void CConCmdManager::OnPluginLoaded(IPlugin *plugin)
|
||||
void CConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
||||
{
|
||||
CmdList *pList;
|
||||
List<ConCmdInfo *> removed;
|
||||
if (plugin->GetProperty("CommandList", (void **)&pList, true))
|
||||
{
|
||||
CmdList::iterator iter;
|
||||
@ -65,14 +67,25 @@ void CConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
||||
|| cmd.type == Cmd_Console)
|
||||
{
|
||||
ConCmdInfo *pInfo = cmd.pInfo;
|
||||
/* See if this is being removed */
|
||||
if (removed.find(pInfo) != removed.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* See if there are still hooks */
|
||||
if (pInfo->srvhooks
|
||||
&& pInfo->srvhooks->GetFunctionCount())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pInfo->conhooks
|
||||
&& pInfo->conhooks->GetFunctionCount())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Remove the command */
|
||||
RemoveConCmd(pInfo);
|
||||
removed.push_back(pInfo);
|
||||
}
|
||||
}
|
||||
delete pList;
|
||||
@ -89,12 +102,39 @@ void CConCmdManager::SetCommandClient(int client)
|
||||
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()
|
||||
{
|
||||
if (m_CmdClient)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Note: Console commands will EITHER go through IServerGameDLL::ClientCommand,
|
||||
* 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);
|
||||
ConCmdInfo *pInfo;
|
||||
@ -104,11 +144,35 @@ void CConCmdManager::InternalDispatch()
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 (!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,
|
||||
const char *name,
|
||||
const char *description,
|
||||
@ -144,7 +236,7 @@ void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
||||
}
|
||||
PlCmdInfo info;
|
||||
info.pInfo = pInfo;
|
||||
info.type = Cmd_Console;
|
||||
info.type = Cmd_Server;
|
||||
pList->push_back(info);
|
||||
}
|
||||
|
||||
@ -311,7 +403,6 @@ void CConCmdManager::OnRootConsoleCommand(const char *command, unsigned int argc
|
||||
name = cmd.pInfo->pCmd->GetName();
|
||||
help = cmd.pInfo->pCmd->GetHelpText();
|
||||
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -38,10 +38,12 @@ struct ConCmdInfo
|
||||
sourceMod = false;
|
||||
pCmd = NULL;
|
||||
srvhooks = NULL;
|
||||
conhooks = NULL;
|
||||
}
|
||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||
ConCommand *pCmd; /**< Pointer to the command itself */
|
||||
IChangeableForward *srvhooks; /**< Hooks on this name as a server command */
|
||||
IChangeableForward *conhooks; /**< Hooks on this name as a console command */
|
||||
};
|
||||
|
||||
class CConCmdManager :
|
||||
@ -63,6 +65,8 @@ public: //IRootConsoleCommand
|
||||
void OnRootConsoleCommand(const char *command, unsigned int argcount);
|
||||
public:
|
||||
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:
|
||||
void InternalDispatch();
|
||||
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "ForwardSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "AdminCache.h"
|
||||
#include "CConCmdManager.h"
|
||||
|
||||
CPlayerManager g_Players;
|
||||
|
||||
@ -51,15 +52,14 @@ void CPlayerManager::OnSourceModAllInitialized()
|
||||
|
||||
ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
|
||||
ParamType p2[] = {Param_Cell};
|
||||
ParamType p3[] = {Param_Cell, Param_String};
|
||||
|
||||
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
|
||||
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", 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_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_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()
|
||||
@ -197,6 +197,7 @@ bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, cons
|
||||
g_SourceMod.SetAuthChecking(true);
|
||||
}
|
||||
|
||||
//:todo: this must meta return
|
||||
return (res) ? true : false;
|
||||
}
|
||||
|
||||
@ -328,10 +329,26 @@ void CPlayerManager::OnClientDisconnect_Post(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);
|
||||
|
||||
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)
|
||||
|
@ -342,6 +342,25 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
|
||||
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)
|
||||
{
|
||||
{"CreateConVar", sm_CreateConVar},
|
||||
@ -363,5 +382,6 @@ REGISTER_NATIVES(convarNatives)
|
||||
{"GetConVarMax", sm_GetConVarMax},
|
||||
{"ResetConVar", sm_ResetConVar},
|
||||
{"RegServerCmd", sm_RegServerCmd},
|
||||
{"RegConsoleCmd", sm_RegConsoleCmd},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ native PrintToConsole(client, const String:format[], {Handle,Float,String,_}:...
|
||||
* @return A Result value. Not handling the command
|
||||
* 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.
|
||||
@ -92,7 +92,6 @@ functag SrvCmd Action:public();
|
||||
*/
|
||||
native RegServerCmd(const String:cmd[], SrvCmd:callback, const String:description[]="", flags=0);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
@ -113,6 +112,7 @@ functag ConCmd Action:public(client);
|
||||
*/
|
||||
native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:description[]="", flags=0);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Hooks a specific client-only command.
|
||||
*
|
||||
|
@ -128,7 +128,7 @@ forward OnClientDisconnect_Post(client);
|
||||
* @param client Player index.
|
||||
* @noreturn
|
||||
*/
|
||||
forward OnClientCommand(client);
|
||||
forward OnClientCommand(client, argCount);
|
||||
|
||||
/**
|
||||
* Called whenever the client's settings are changed.
|
||||
|
Loading…
Reference in New Issue
Block a user