/* 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.set(szCmd); argument.set(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.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;