rewrote console command implementation internally
admin commands on the way but still not done removed weird restriction --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40519
This commit is contained in:
		
							parent
							
								
									49d96d4322
								
							
						
					
					
						commit
						6b28bec27f
					
				| @ -13,6 +13,7 @@ | ||||
| 
 | ||||
| #include "CConCmdManager.h" | ||||
| #include "sm_srvcmds.h" | ||||
| #include "AdminCache.h" | ||||
| #include "sm_stringutil.h" | ||||
| 
 | ||||
| CConCmdManager g_ConCmds; | ||||
| @ -23,19 +24,22 @@ SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int | ||||
| struct PlCmdInfo | ||||
| { | ||||
| 	ConCmdInfo *pInfo; | ||||
| 	CmdHook *pHook; | ||||
| 	CmdType type; | ||||
| }; | ||||
| 
 | ||||
| typedef List<PlCmdInfo> CmdList; | ||||
| void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info); | ||||
| 
 | ||||
| CConCmdManager::CConCmdManager() | ||||
| CConCmdManager::CConCmdManager() : m_Strings(1024) | ||||
| { | ||||
| 	m_pCmds = sm_trie_create(); | ||||
| 	m_pCmdGrps = sm_trie_create(); | ||||
| } | ||||
| 
 | ||||
| CConCmdManager::~CConCmdManager() | ||||
| { | ||||
| 	sm_trie_destroy(m_pCmds); | ||||
| 	sm_trie_destroy(m_pCmdGrps); | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::OnSourceModAllInitialized() | ||||
| @ -53,9 +57,23 @@ void CConCmdManager::OnSourceModShutdown() | ||||
| 	g_PluginSys.RemovePluginsListener(this); | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::OnPluginLoaded(IPlugin *plugin) | ||||
| void CConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext) | ||||
| { | ||||
| 	/* Nothing yet... */ | ||||
| 	List<CmdHook *>::iterator iter = cmdlist.begin(); | ||||
| 	CmdHook *pHook; | ||||
| 
 | ||||
| 	while (iter != cmdlist.end()) | ||||
| 	{ | ||||
| 		pHook = (*iter); | ||||
| 		if (pHook->pf->GetParentContext() == pContext) | ||||
| 		{ | ||||
| 			delete pHook->pAdmin; | ||||
| 			delete pHook; | ||||
| 			iter = cmdlist.erase(iter); | ||||
| 		} else { | ||||
| 			iter++; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::OnPluginDestroyed(IPlugin *plugin) | ||||
| @ -64,37 +82,42 @@ void CConCmdManager::OnPluginDestroyed(IPlugin *plugin) | ||||
| 	List<ConCmdInfo *> removed; | ||||
| 	if (plugin->GetProperty("CommandList", (void **)&pList, true)) | ||||
| 	{ | ||||
| 		IPluginContext *pContext = plugin->GetBaseContext(); | ||||
| 		CmdList::iterator iter; | ||||
| 		/* First pass!
 | ||||
| 	 	 * Only bother if there's an actual command list on this plugin...  | ||||
| 	 	 */ | ||||
| 		for (iter=pList->begin(); | ||||
| 			iter!=pList->end(); | ||||
| 			iter++) | ||||
| 		{ | ||||
| 			PlCmdInfo &cmd = (*iter); | ||||
| 			if (cmd.type == Cmd_Server | ||||
| 				|| cmd.type == Cmd_Console) | ||||
| 			{ | ||||
| 			ConCmdInfo *pInfo = cmd.pInfo; | ||||
| 				/* See if this is being removed */ | ||||
| 
 | ||||
| 			/* Has this chain already been fully cleaned/removed? */ | ||||
| 			if (removed.find(pInfo) != removed.end()) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			/* Remove any hooks from us on this command */ | ||||
| 			RemoveConCmds(pInfo->conhooks, pContext); | ||||
| 			RemoveConCmds(pInfo->srvhooks, pContext); | ||||
| 
 | ||||
| 			/* See if there are still hooks */ | ||||
| 				if (pInfo->srvhooks | ||||
| 					&& pInfo->srvhooks->GetFunctionCount()) | ||||
| 			if (pInfo->srvhooks.size()) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 				if (pInfo->conhooks | ||||
| 					&& pInfo->conhooks->GetFunctionCount()) | ||||
| 			if (pInfo->conhooks.size()) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 				/* Remove the command */ | ||||
| 
 | ||||
| 			/* Remove the command, it should be safe now */ | ||||
| 			RemoveConCmd(pInfo); | ||||
| 			removed.push_back(pInfo); | ||||
| 		} | ||||
| 		} | ||||
| 		delete pList; | ||||
| 	} | ||||
| } | ||||
| @ -118,15 +141,32 @@ ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type) | ||||
| 	if (sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) | ||||
| 	{ | ||||
| 		cell_t result = type; | ||||
| 		if (pInfo->conhooks && pInfo->conhooks->GetFunctionCount()) | ||||
| 		cell_t tempres = result; | ||||
| 		List<CmdHook *>::iterator iter; | ||||
| 		CmdHook *pHook; | ||||
| 		for (iter=pInfo->conhooks.begin(); | ||||
| 			 iter!=pInfo->conhooks.end(); | ||||
| 			 iter++) | ||||
| 		{ | ||||
| 			pInfo->conhooks->PushCell(client); | ||||
| 			pInfo->conhooks->PushCell(args); | ||||
| 			pInfo->conhooks->Execute(&result); | ||||
| 			pHook = (*iter); | ||||
| 			if (pHook->pAdmin | ||||
| 				&& pHook->pAdmin->eflags) | ||||
| 			{ | ||||
| 				/* :TODO: admin calculations */ | ||||
| 			} | ||||
| 		if (result >= Pl_Stop) | ||||
| 			pHook->pf->PushCell(client); | ||||
| 			pHook->pf->PushCell(args); | ||||
| 			if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) | ||||
| 			{ | ||||
| 			return Pl_Stop; | ||||
| 				if (tempres > result) | ||||
| 				{ | ||||
| 					result = tempres; | ||||
| 				} | ||||
| 				if (result == Pl_Stop) | ||||
| 				{ | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		type = (ResultType)result; | ||||
| 	} | ||||
| @ -153,12 +193,30 @@ void CConCmdManager::InternalDispatch() | ||||
| 	cell_t result = Pl_Continue; | ||||
| 	int args = engine->Cmd_Argc() - 1; | ||||
| 
 | ||||
| 	if (m_CmdClient == 0) | ||||
| 	List<CmdHook *>::iterator iter; | ||||
| 	CmdHook *pHook; | ||||
| 
 | ||||
| 	/* Execute server-only commands if viable */ | ||||
| 	if (m_CmdClient == 0 && pInfo->srvhooks.size()) | ||||
| 	{ | ||||
| 		if (pInfo->srvhooks && pInfo->srvhooks->GetFunctionCount()) | ||||
| 		cell_t tempres = result; | ||||
| 		for (iter=pInfo->srvhooks.begin(); | ||||
| 			 iter!=pInfo->srvhooks.end(); | ||||
| 			 iter++) | ||||
| 		{ | ||||
| 			pInfo->srvhooks->PushCell(args); | ||||
| 			pInfo->srvhooks->Execute(&result); | ||||
| 			pHook = (*iter); | ||||
| 			pHook->pf->PushCell(args); | ||||
| 			if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) | ||||
| 			{ | ||||
| 				if (tempres > result) | ||||
| 				{ | ||||
| 					result = tempres; | ||||
| 				} | ||||
| 				if (result == Pl_Stop) | ||||
| 				{ | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	 | ||||
| 		/* Check if there's an early stop */ | ||||
| @ -172,12 +230,35 @@ void CConCmdManager::InternalDispatch() | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Execute console command hooks */ | ||||
| 	if (pInfo->conhooks && pInfo->conhooks->GetFunctionCount()) | ||||
| 	/* Execute console commands */ | ||||
| 	if (pInfo->conhooks.size()) | ||||
| 	{ | ||||
| 		pInfo->conhooks->PushCell(m_CmdClient); | ||||
| 		pInfo->conhooks->PushCell(args); | ||||
| 		pInfo->conhooks->Execute(&result); | ||||
| 		cell_t tempres = result; | ||||
| 		for (iter=pInfo->conhooks.begin(); | ||||
| 			iter!=pInfo->conhooks.end(); | ||||
| 			iter++) | ||||
| 		{ | ||||
| 			pHook = (*iter); | ||||
| 			if (m_CmdClient  | ||||
| 				&& pHook->pAdmin | ||||
| 				&& pHook->pAdmin->eflags) | ||||
| 			{ | ||||
| 				/* :TODO: check admin stuff */ | ||||
| 			} | ||||
| 			pHook->pf->PushCell(m_CmdClient); | ||||
| 			pHook->pf->PushCell(args); | ||||
| 			if (pHook->pf->Execute(&tempres) != SP_ERROR_NONE) | ||||
| 			{ | ||||
| 				if (tempres > result) | ||||
| 				{ | ||||
| 					result = tempres; | ||||
| 				} | ||||
| 				if (result == Pl_Stop) | ||||
| 				{ | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (result >= Pl_Handled) | ||||
| @ -190,19 +271,25 @@ void CConCmdManager::InternalDispatch() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args) | ||||
| { | ||||
| 	return Pl_Continue; | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction,  | ||||
| 									   const char *name,  | ||||
| 									   const char *description,  | ||||
| 									   int flags) | ||||
| { | ||||
| 	ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); | ||||
| 	CmdHook *pHook = new CmdHook(); | ||||
| 
 | ||||
| 	if (!pInfo->conhooks) | ||||
| 	pHook->pf = pFunction; | ||||
| 	if (description && description[0]) | ||||
| 	{ | ||||
| 		pInfo->conhooks = g_Forwards.CreateForwardEx(NULL, ET_Hook, 2, NULL, Param_Cell, Param_Cell); | ||||
| 		pHook->helptext.assign(description); | ||||
| 	} | ||||
| 
 | ||||
| 	pInfo->conhooks->AddFunction(pFunction); | ||||
| 	pInfo->conhooks.push_back(pHook); | ||||
| 
 | ||||
| 	/* Add to the plugin */ | ||||
| 	CmdList *pList; | ||||
| @ -215,7 +302,79 @@ void CConCmdManager::AddConsoleCommand(IPluginFunction *pFunction, | ||||
| 	PlCmdInfo info; | ||||
| 	info.pInfo = pInfo; | ||||
| 	info.type = Cmd_Console; | ||||
| 	pList->push_back(info); | ||||
| 	info.pHook = pHook; | ||||
| 	AddToPlCmdList(pList, info); | ||||
| } | ||||
| 
 | ||||
| bool CConCmdManager::AddAdminCommand(IPluginFunction *pFunction,  | ||||
| 									 const char *name,  | ||||
| 									 const char *group, | ||||
| 									 int adminflags, | ||||
| 									 const char *description,  | ||||
| 									 int flags) | ||||
| { | ||||
| 	ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); | ||||
| 
 | ||||
| 	CmdHook *pHook = new CmdHook(); | ||||
| 	AdminCmdInfo *pAdmin = new AdminCmdInfo(); | ||||
| 
 | ||||
| 	pHook->pf = pFunction; | ||||
| 	if (description && description[0]) | ||||
| 	{ | ||||
| 		pHook->helptext.assign(description); | ||||
| 	} | ||||
| 	pHook->pAdmin = pAdmin; | ||||
| 
 | ||||
| 	void *object; | ||||
| 	int grpid; | ||||
| 	if (!sm_trie_retrieve(m_pCmdGrps, group, (void **)&object)) | ||||
| 	{ | ||||
| 		grpid = m_Strings.AddString(group); | ||||
| 		sm_trie_insert(m_pCmdGrps, group, (void *)grpid); | ||||
| 	} else { | ||||
| 		grpid = (int)object; | ||||
| 	} | ||||
| 
 | ||||
| 	pAdmin->cmdGrpId = grpid; | ||||
| 	pAdmin->flags = flags; | ||||
| 
 | ||||
| 	/* First get the command group override, if any */ | ||||
| 	bool override = g_Admins.GetCommandOverride(group,  | ||||
| 		Override_CommandGroup, | ||||
| 		&(pAdmin->eflags)); | ||||
| 
 | ||||
| 	/* Next get the command override, if any */ | ||||
| 	if (g_Admins.GetCommandOverride(name, | ||||
| 		Override_Command, | ||||
| 		&(pAdmin->eflags))) | ||||
| 	{ | ||||
| 		override = true; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Assign normal flags if there were no overrides */ | ||||
| 	if (!override) | ||||
| 	{ | ||||
| 		pAdmin->eflags = pAdmin->flags; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Finally, add the hook */ | ||||
| 	pInfo->conhooks.push_back(pHook); | ||||
| 
 | ||||
| 	/* Now 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_Admin; | ||||
| 	info.pHook = pHook; | ||||
| 	AddToPlCmdList(pList, info); | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::AddServerCommand(IPluginFunction *pFunction,  | ||||
| @ -225,13 +384,15 @@ void CConCmdManager::AddServerCommand(IPluginFunction *pFunction, | ||||
| 
 | ||||
| { | ||||
| 	ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags); | ||||
| 	CmdHook *pHook = new CmdHook(); | ||||
| 
 | ||||
| 	if (!pInfo->srvhooks) | ||||
| 	pHook->pf = pFunction; | ||||
| 	if (description && description[0]) | ||||
| 	{ | ||||
| 		pInfo->srvhooks = g_Forwards.CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_Cell); | ||||
| 		pHook->helptext.assign(description); | ||||
| 	} | ||||
| 
 | ||||
| 	pInfo->srvhooks->AddFunction(pFunction); | ||||
| 	pInfo->srvhooks.push_back(pHook); | ||||
| 
 | ||||
| 	/* Add to the plugin */ | ||||
| 	CmdList *pList; | ||||
| @ -244,8 +405,37 @@ void CConCmdManager::AddServerCommand(IPluginFunction *pFunction, | ||||
| 	PlCmdInfo info; | ||||
| 	info.pInfo = pInfo; | ||||
| 	info.type = Cmd_Server; | ||||
| 	info.pHook = pHook; | ||||
| 	AddToPlCmdList(pList, info); | ||||
| } | ||||
| 
 | ||||
| void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info) | ||||
| { | ||||
| 	CmdList::iterator iter = pList->begin(); | ||||
| 	bool inserted = false; | ||||
| 	const char *orig = NULL; | ||||
| 
 | ||||
| 	orig = info.pInfo->pCmd->GetName(); | ||||
| 
 | ||||
| 	/* Insert this into the help list, SORTED alphabetically. */ | ||||
| 	while (iter != pList->end()) | ||||
| 	{ | ||||
| 		PlCmdInfo &obj = (*iter); | ||||
| 		const char *cmd = obj.pInfo->pCmd->GetName(); | ||||
| 		if (strcmp(orig, cmd) < 0) | ||||
| 		{ | ||||
| 			pList->insert(iter, info); | ||||
| 			inserted = true; | ||||
| 			break; | ||||
| 		} | ||||
| 		iter++; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!inserted) | ||||
| 	{ | ||||
| 		pList->push_back(info); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CConCmdManager::AddToCmdList(ConCmdInfo *info) | ||||
| { | ||||
| @ -306,11 +496,7 @@ void CConCmdManager::RemoveConCmd(ConCmdInfo *info) | ||||
| 	/* Remove from list */ | ||||
| 	m_CmdList.remove(info); | ||||
| 
 | ||||
| 	/* Free forwards */ | ||||
| 	if (info->srvhooks) | ||||
| 	{ | ||||
| 		g_Forwards.ReleaseForward(info->srvhooks); | ||||
| 	} | ||||
| 	delete info; | ||||
| } | ||||
| 
 | ||||
| ConCmdInfo *CConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags) | ||||
| @ -400,11 +586,16 @@ void CConCmdManager::OnRootConsoleCommand(const char *command, unsigned int argc | ||||
| 				type = "server"; | ||||
| 			} else if (cmd.type == Cmd_Console) { | ||||
| 				type = "console"; | ||||
| 			} else if (cmd.type == Cmd_Client) { | ||||
| 				type = "client"; | ||||
| 			} else if (cmd.type == Cmd_Admin) { | ||||
| 				type = "admin"; | ||||
| 			} | ||||
| 			name = cmd.pInfo->pCmd->GetName(); | ||||
| 			if (cmd.pHook->helptext.size()) | ||||
| 			{ | ||||
| 				help = cmd.pHook->helptext.c_str(); | ||||
| 			} else { | ||||
| 				help = cmd.pInfo->pCmd->GetHelpText(); | ||||
| 			} | ||||
| 			g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);		 | ||||
| 		} | ||||
| 
 | ||||
|  | ||||
| @ -19,8 +19,11 @@ | ||||
| #include "sourcemm_api.h" | ||||
| #include "ForwardSys.h" | ||||
| #include "sm_trie.h" | ||||
| #include "sm_memtable.h" | ||||
| #include <sh_list.h> | ||||
| #include <sh_string.h> | ||||
| #include <IRootConsoleMenu.h> | ||||
| #include <IAdminSystem.h> | ||||
| 
 | ||||
| using namespace SourceHook; | ||||
| 
 | ||||
| @ -28,7 +31,32 @@ enum CmdType | ||||
| { | ||||
| 	Cmd_Server, | ||||
| 	Cmd_Console, | ||||
| 	Cmd_Client | ||||
| 	Cmd_Admin, | ||||
| }; | ||||
| 
 | ||||
| struct AdminCmdInfo | ||||
| { | ||||
| 	AdminCmdInfo() | ||||
| 	{ | ||||
| 		cmdGrpId = -1; | ||||
| 		flags = 0; | ||||
| 		eflags = 0; | ||||
| 	} | ||||
| 	int cmdGrpId;			/* index into cmdgroup string table */ | ||||
| 	FlagBits flags;			/* default flags */ | ||||
| 	FlagBits eflags;		/* effective flags */ | ||||
| }; | ||||
| 
 | ||||
| struct CmdHook | ||||
| { | ||||
| 	CmdHook() | ||||
| 	{ | ||||
| 		pf = NULL; | ||||
| 		pAdmin = NULL; | ||||
| 	} | ||||
| 	IPluginFunction *pf;	/* function hook */ | ||||
| 	String helptext;		/* help text */ | ||||
| 	AdminCmdInfo *pAdmin;	/* admin requirements, if any */ | ||||
| }; | ||||
| 
 | ||||
| struct ConCmdInfo | ||||
| @ -37,13 +65,11 @@ 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 */ | ||||
| 	List<CmdHook *> srvhooks;		/**< Hooks as a server command */ | ||||
| 	List<CmdHook *> conhooks;		/**< Hooks as a console command */ | ||||
| }; | ||||
| 
 | ||||
| class CConCmdManager : | ||||
| @ -59,24 +85,33 @@ public: //SMGlobalClass | ||||
| 	void OnSourceModAllInitialized(); | ||||
| 	void OnSourceModShutdown(); | ||||
| public: //IPluginsListener
 | ||||
| 	void OnPluginLoaded(IPlugin *plugin); | ||||
| 	void OnPluginDestroyed(IPlugin *plugin); | ||||
| 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); | ||||
| 	bool AddAdminCommand(IPluginFunction *pFunction,  | ||||
| 						 const char *name,  | ||||
| 						 const char *group, | ||||
| 						 int adminflags, | ||||
| 						 const char *description,  | ||||
| 						 int flags); | ||||
| 	ResultType DispatchClientCommand(int client, ResultType type); | ||||
| private: | ||||
| 	void InternalDispatch(); | ||||
| 	ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args); | ||||
| 	ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags); | ||||
| 	void SetCommandClient(int client); | ||||
| 	void AddToCmdList(ConCmdInfo *info); | ||||
| 	void RemoveConCmd(ConCmdInfo *info); | ||||
| 	void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext); | ||||
| private: | ||||
| 	Trie *m_pCmds; | ||||
| 	List<ConCmdInfo *> m_CmdList; | ||||
| 	int m_CmdClient; | ||||
| 	Trie *m_pCmds;					/* command lookup */ | ||||
| 	Trie *m_pCmdGrps;				/* command group lookup */ | ||||
| 	List<ConCmdInfo *> m_CmdList;	/* command list, currently unused */ | ||||
| 	int m_CmdClient;				/* current client */ | ||||
| 	BaseStringTable m_Strings;		/* string table */ | ||||
| }; | ||||
| 
 | ||||
| extern CConCmdManager g_ConCmds; | ||||
|  | ||||
| @ -115,7 +115,7 @@ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:descripti | ||||
| #if 0
 | ||||
| /** | ||||
|  * Creates a console command as an administrative command.  If the command does not exist, | ||||
|  * it is created.  This command cannot be used to create duplicate admin commands. | ||||
|  * it is created.  | ||||
|  * | ||||
|  * @param cmd			String containing command to register. | ||||
|  * @param callback		A function to use as a callback for when the command is invoked. | ||||
| @ -125,7 +125,6 @@ native RegConsoleCmd(const String:cmd[], ConCmd:callback, const String:descripti | ||||
|  * @param description	Optional description to use for help. | ||||
|  * @param flags			Optional console flags. | ||||
|  * @noreturn | ||||
|  * @error				If this command has already been registered as an admin command. | ||||
|  */ | ||||
| native RegAdminCmd(const String:cmd[],  | ||||
| 						ConCmd:callback,  | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user