276 lines
6.2 KiB
C++
Executable File
276 lines
6.2 KiB
C++
Executable File
/* AMX Mod X
|
|
*
|
|
* by the AMX Mod X Development Team
|
|
* originally developed by OLO
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* In addition, as a special exception, the author gives permission to
|
|
* link the code of this program with the Half-Life Game Engine ("HL
|
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
* respects for all of the code used other than the HL Engine and MODs
|
|
* from Valve. If you modify this file, you may extend this exception
|
|
* to your version of the file, but you are not obligated to do so. If
|
|
* you do not wish to do so, delete this exception statement from your
|
|
* version.
|
|
*/
|
|
|
|
#include "amxmodx.h"
|
|
#include "CCmd.h"
|
|
|
|
// *****************************************************
|
|
// class CmdMngr
|
|
// *****************************************************
|
|
CmdMngr::CmdMngr() {
|
|
memset(sortedlists,0,sizeof(sortedlists));
|
|
srvcmdlist = 0;
|
|
clcmdlist = 0;
|
|
prefixHead = 0;
|
|
buf_type = -1;
|
|
buf_access = 0;
|
|
buf_id = -1;
|
|
buf_cmdid = -1;
|
|
buf_cmdtype = -1;
|
|
buf_cmdaccess = 0;
|
|
|
|
}
|
|
|
|
CmdMngr::Command::Command( CPluginMngr::CPlugin* pplugin,const char* pcmd,
|
|
const char* pinfo , int pflags , int pfunc,
|
|
bool pviewable, CmdMngr* pparent ) : commandline(pcmd) , info(pinfo) {
|
|
|
|
char szCmd[64], szArg[64];
|
|
*szCmd = 0; *szArg=0;
|
|
sscanf(pcmd,"%s %s",szCmd,szArg);
|
|
command.assign(szCmd);
|
|
argument.assign(szArg);
|
|
plugin = pplugin;
|
|
flags = pflags;
|
|
cmdtype = 0;
|
|
prefix = 0;
|
|
function = pfunc;
|
|
listable = pviewable;
|
|
parent = pparent;
|
|
id = --uniqueid;
|
|
}
|
|
|
|
CmdMngr::Command::~Command()
|
|
{
|
|
++uniqueid;
|
|
}
|
|
|
|
CmdMngr::Command* CmdMngr::registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable )
|
|
{
|
|
Command* b = new Command( plugin , cmd , info , level , func , listable, this );
|
|
if ( b == 0 ) return 0;
|
|
setCmdLink( &sortedlists[0] , b );
|
|
return b;
|
|
}
|
|
|
|
CmdMngr::Command* CmdMngr::getCmd( long int id ,int type, int access )
|
|
{
|
|
//if ( id >= 1024 || id < 0 ) return (Command*)id;
|
|
if ( id < 0 ){
|
|
for (CmdMngr::iterator a = begin( type ); a ; ++a){
|
|
if ( (*a).id == id )
|
|
return &(*a);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if ( (id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype) )
|
|
{
|
|
buf_cmdptr = begin( type );
|
|
buf_cmdaccess = access;
|
|
buf_cmdtype = type;
|
|
buf_cmdid = id;
|
|
}
|
|
else
|
|
{
|
|
int a = id;
|
|
id -= buf_cmdid;
|
|
buf_cmdid = a;
|
|
}
|
|
|
|
while ( buf_cmdptr )
|
|
{
|
|
|
|
if ( (*buf_cmdptr).gotAccess( access ) &&
|
|
(*buf_cmdptr).getPlugin()->isExecutable( (*buf_cmdptr).getFunction() )
|
|
&& (*buf_cmdptr).isViewable() )
|
|
{
|
|
|
|
if ( id-- == 0 )
|
|
return &(*buf_cmdptr);
|
|
|
|
}
|
|
|
|
++buf_cmdptr;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CmdMngr::getCmdNum( int type, int access )
|
|
{
|
|
if ( (access == buf_access) && (type == buf_type) )
|
|
return buf_num; // once calculated don't have to be done again
|
|
|
|
buf_access = access;
|
|
buf_type = type;
|
|
buf_num = 0;
|
|
|
|
CmdMngr::iterator a = begin( type );
|
|
|
|
while ( a )
|
|
{
|
|
|
|
if ( (*a).gotAccess( access ) &&
|
|
(*a).getPlugin()->isExecutable( (*a).getFunction() )
|
|
&& (*a).isViewable() )
|
|
++buf_num;
|
|
++a;
|
|
}
|
|
|
|
return buf_num;
|
|
}
|
|
|
|
void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
|
|
{
|
|
CmdLink* np = new CmdLink( c );
|
|
|
|
if ( np == 0 ) return;
|
|
|
|
if ( sorted )
|
|
{
|
|
while( *a )
|
|
{
|
|
int i = strcmp(c->getCommand(),(*a)->cmd->getCommand() );
|
|
|
|
if ( (i<0) || (i==0) && ( strcmp( c->getArgument() , (*a)->cmd->getArgument() ) < 0 ) )
|
|
break;
|
|
|
|
a = &(*a)->next;
|
|
}
|
|
|
|
np->next = *a;
|
|
*a = np;
|
|
}
|
|
else
|
|
{
|
|
while ( *a ) a = &(*a)->next;
|
|
*a = np;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CmdMngr::clearCmdLink( CmdLink** phead, bool pclear )
|
|
{
|
|
while( *phead ){
|
|
CmdLink* pp = (*phead)->next;
|
|
if ( pclear ) delete (*phead)->cmd;
|
|
delete *phead;
|
|
*phead = pp;
|
|
}
|
|
}
|
|
|
|
void CmdMngr::Command::setCmdType( int a )
|
|
{
|
|
switch(a){
|
|
case CMD_ConsoleCommand: cmdtype |= 3; break;
|
|
case CMD_ClientCommand: cmdtype |= 1; break;
|
|
case CMD_ServerCommand: cmdtype |= 2; break;
|
|
}
|
|
if ( cmdtype & 1 ) { // ClientCommand
|
|
parent->setCmdLink( &parent->sortedlists[1] , this );
|
|
if ( !parent->registerCmdPrefix( this ) )
|
|
parent->setCmdLink( &parent->clcmdlist , this , false );
|
|
}
|
|
if ( cmdtype & 2 ) { // ServerCommand
|
|
parent->setCmdLink( &parent->sortedlists[2] , this );
|
|
parent->setCmdLink( &parent->srvcmdlist , this , false );
|
|
}
|
|
}
|
|
|
|
const char* CmdMngr::Command::getCmdType() const {
|
|
switch( cmdtype ){
|
|
case 1: return"client";
|
|
case 2: return "server";
|
|
case 3: return "console";
|
|
}
|
|
return "unknown";
|
|
}
|
|
|
|
bool CmdMngr::registerCmdPrefix( Command* cc )
|
|
{
|
|
CmdPrefix** b = findPrefix( cc->getCommand() );
|
|
if (*b){
|
|
setCmdLink( &(*b)->list , cc , false );
|
|
cc->prefix = (*b)->name.size();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CmdMngr::registerPrefix( const char* nn )
|
|
{
|
|
if ( *nn == 0 ) return;
|
|
CmdPrefix** b = findPrefix( nn );
|
|
if (*b) return;
|
|
*b = new CmdPrefix( nn , this );
|
|
}
|
|
|
|
CmdMngr::CmdPrefix** CmdMngr::findPrefix( const char* nn ){
|
|
CmdPrefix** aa = &prefixHead;
|
|
while(*aa){
|
|
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
|
|
break;
|
|
aa=&(*aa)->next;
|
|
}
|
|
return aa;
|
|
}
|
|
|
|
void CmdMngr::clearPrefix(){
|
|
while(prefixHead){
|
|
CmdPrefix* a = prefixHead->next;
|
|
delete prefixHead;
|
|
prefixHead = a;
|
|
}
|
|
}
|
|
|
|
void CmdMngr::clear()
|
|
{
|
|
clearCmdLink(&sortedlists[0], true);
|
|
clearCmdLink(&sortedlists[1]);
|
|
clearCmdLink(&sortedlists[2]);
|
|
clearCmdLink(&srvcmdlist);
|
|
clearCmdLink(&clcmdlist);
|
|
clearPrefix();
|
|
clearBufforedInfo();
|
|
}
|
|
|
|
void CmdMngr::clearBufforedInfo() {
|
|
buf_type = -1;
|
|
buf_access = 0;
|
|
buf_id = -1;
|
|
buf_cmdid = -1;
|
|
buf_cmdtype = -1;
|
|
buf_cmdaccess = 0;
|
|
}
|
|
|
|
int CmdMngr::Command::uniqueid = 0; |