amxmodx/amxmodx/CCmd.cpp
2004-01-31 20:56:22 +00:00

278 lines
6.3 KiB
C++
Executable File

/*
* Copyright (c) 2002-2003 Aleksander Naszko
*
* This file is part of AMX Mod.
*
* AMX Mod 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.
*
* AMX Mod 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 AMX Mod; 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 <extdll.h>
#include <meta_api.h>
#include "amxmod.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;