Initial revision

This commit is contained in:
Felix Geyer
2004-01-31 20:56:22 +00:00
parent 88eadb34bc
commit 9e999a0ba6
106 changed files with 24019 additions and 0 deletions

278
amxmodx/CCmd.cpp Executable file
View File

@ -0,0 +1,278 @@
/*
* 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;

165
amxmodx/CCmd.h Executable file
View File

@ -0,0 +1,165 @@
/*
* 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.
*
*/
#ifndef COMMANDS_H
#define COMMANDS_H
// *****************************************************
// class CmdMngr
// *****************************************************
enum {
CMD_ConsoleCommand,
CMD_ClientCommand,
CMD_ServerCommand
};
class CmdMngr
{
public:
class Command;
friend class Command;
class Command {
friend class CmdMngr;
CPluginMngr::CPlugin* plugin;
CmdMngr* parent;
String command;
String argument;
String commandline;
String info;
bool listable;
int function;
int flags;
int id;
int cmdtype;
int prefix;
static int uniqueid;
Command( CPluginMngr::CPlugin* pplugin,const char* pcmd, const char* pinfo , int pflags , int pfunc, bool pviewable, CmdMngr* pparent );
~Command();
public:
inline const char* getCommand() const{ return command.str(); }
inline const char* getArgument() const{ return argument.str(); }
inline const char* getCmdInfo() const{ return info.str(); }
inline const char* getCmdLine() const{ return commandline.str(); }
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.str()+prefix, cmd+prefix ) && (argument.empty() || !stricmp(argument.str() , arg ))); }
inline bool matchCommand(const char* cmd) { return (!strcmp(command.str(), cmd )); }
inline int getFunction() const { return function; }
inline bool gotAccess(int f) const { return (!flags||((flags & f)==flags)); }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool isViewable() const { return listable; }
inline int getFlags() const { return flags; }
inline long int getId() const { return (long int)id; }
const char* getCmdType() const;
void setCmdType( int a );
};
private:
struct CmdPrefix;
friend struct CmdPrefix;
struct CmdLink {
Command* cmd;
CmdLink* next;
CmdLink(Command* c): cmd(c), next(0) {}
};
CmdLink* sortedlists[3];
CmdLink* srvcmdlist;
CmdLink* clcmdlist;
struct CmdPrefix {
CmdMngr* parent;
String name;
CmdLink* list;
CmdPrefix* next;
CmdPrefix( const char* nn , CmdMngr* pp) : name(nn),parent(pp),list(0),next(0){}
~CmdPrefix(){ parent->clearCmdLink(&list); }
} *prefixHead;
bool registerCmdPrefix( Command* cc );
CmdPrefix** findPrefix( const char* nn );
void clearPrefix();
void setCmdLink( CmdLink** a , Command* c, bool sorted = true );
void clearCmdLink( CmdLink** phead, bool pclear = false );
public:
CmdMngr();
~CmdMngr() {clear();}
// Interface
void registerPrefix( const char* nn );
Command* registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable );
Command* getCmd( long int id ,int type, int access);
int getCmdNum( int type, int access );
void clearBufforedInfo();
void clear();
class iterator {
CmdLink *a;
public:
iterator(CmdLink*aa = 0) : a(aa) {}
iterator& operator++() { a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
operator bool () const { return a ? true : false; }
Command& operator*() { return *a->cmd; }
};
inline iterator clcmdprefixbegin(const char* nn){
CmdPrefix* a = *findPrefix(nn);
return iterator( a ? a->list : 0 );
}
inline iterator clcmdbegin() const {return iterator(clcmdlist);}
inline iterator srvcmdbegin() const {return iterator(srvcmdlist);}
inline iterator begin( int type ) const { return iterator(sortedlists[type]); }
inline iterator end() const { return iterator(0); }
private:
int buf_cmdid;
int buf_cmdtype;
int buf_cmdaccess;
iterator buf_cmdptr;
int buf_id;
int buf_type;
int buf_access;
int buf_num;
};
#endif

337
amxmodx/CEvent.cpp Executable file
View File

@ -0,0 +1,337 @@
/*
* 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 "CEvent.h"
// *****************************************************
// class EventsMngr
// *****************************************************
EventsMngr::EventsMngr()
{
memset( modMsgsFunCall, 0 , sizeof(modMsgsFunCall) );
}
EventsMngr::~EventsMngr()
{
clearEvents();
}
EventsMngr::ClEvent::ClEvent( CPluginMngr::CPlugin* amxplugin, int function, int flags )
{
plugin = amxplugin;
func = function;
stamp = 0.0;
next = 0;
done = false;
alive=true;
dead=true;
if ( flags & 24 ){
alive=(flags&16)?true:false; //e
dead=(flags&8)?true:false; //d
}
world=(flags&1)?true:false; //a
player=(flags&2)?true:false; //b
once=(flags&4)?true:false; //c
memset(cond,0,sizeof(cond));
}
void EventsMngr::ClEvent::registerFilter( char* filter )
{
if ( filter == 0 ) return;
char* value = filter;
while ( isdigit(*value) )
++value;
if ( *value == 0 ) return;
cond_t* b = new cond_t;
if ( b == 0 ) return;
b->type = *value;
*value++ = 0;
b->sValue.set(value);
b->fValue = atof(value);
b->iValue = atoi(value);
int i = atoi(filter);
if (i >= 0 && i < MAX_PARSE_VALUES) {
b->next = cond[i];
cond[i] = b;
}
else delete b;
}
EventsMngr::ClEvent* EventsMngr::registerEvent( CPluginMngr::CPlugin* p, int f, int flags, int pos )
{
ClEvent* a = new ClEvent( p , f , flags );
if ( a == 0 ) return 0;
ClEvent** end = &modMsgsFunCall[pos];
while( *end ) end = &(*end)->next;
return *end = a;
}
void EventsMngr::parserInit(int msg_type, float* tim, CPlayer *pPlayer, int index) {
parseNotDone = false;
timer = tim;
if ( (parseFun = modMsgsFunCall[msg_type]) == 0 ) return;
for(EventsMngr::ClEvent*p=parseFun;p;p=p->next){
if ( p->done ) continue;
if ( !p->plugin->isExecutable(p->func) ){
p->done = true;
continue;
}
if ( pPlayer ) {
if ( !p->player || ( pPlayer->IsAlive() ? !p->alive : !p->dead ) ) {
p->done = true;
continue;
}
}
else if ( !p->world ){
p->done = true;
continue;
}
if ( p->once && p->stamp == (float)(*timer) ){
p->done = true;
continue;
}
parseNotDone = true;
}
if ( parseNotDone ) {
parseVault[parsePos = 0].type = MSG_INTEGER;
parseVault[parsePos].iValue = index;
}
}
const char* EventsMngr::getArgString(int a)
{
if ( a < 0 || a > parsePos ) return "";
static char var[32];
switch(parseVault[a].type){
case MSG_INTEGER:
sprintf( var, "%d", parseVault[a].iValue );
return var;
case MSG_STRING:
return parseVault[a].sValue;
default:
sprintf( var, "%g", parseVault[a].fValue );
return var;
}
}
int EventsMngr::getArgInteger(int a)
{
if ( a < 0 || a > parsePos ) return 0;
switch(parseVault[a].type){
case MSG_INTEGER: return parseVault[a].iValue;
case MSG_STRING: return atoi(parseVault[a].sValue);
default: return (int)parseVault[a].fValue;
}
}
float EventsMngr::getArgFloat(int a)
{
if ( a < 0 || a > parsePos ) return 0.0f;
switch(parseVault[a].type){
case MSG_INTEGER: return parseVault[a].iValue;
case MSG_STRING: return atof(parseVault[a].sValue);
default: return parseVault[a].fValue;
}
}
void EventsMngr::executeEvents() {
int err;
#ifdef ENABLEEXEPTIONS
try
{
#endif
for ( ClEvent*p = parseFun ; p ; p = p->next )
{
if ( p->done )
{
p->done = false;
continue;
}
p->stamp = *timer;
if ((err = amx_Exec(p->plugin->getAMX(), NULL , p->func , 1,parseVault[0].iValue)) != AMX_ERR_NONE)
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n",err,p->plugin->getAMX()->curline,p->plugin->getName());
}
#ifdef ENABLEEXEPTIONS
}
catch( ... )
{
print_srvconsole( "[AMX] fatal error at event execution\n");
}
#endif
}
void EventsMngr::parseValue(int iValue) {
if ( !parseNotDone ) return;
parseVault[++parsePos].type = MSG_INTEGER;
parseVault[parsePos].iValue = iValue;
bool skip;
for (ClEvent*p=parseFun;p;p=p->next){
if ( p->done || !p->cond[parsePos] ) continue;
skip = false;
ClEvent::cond_t* a = p->cond[parsePos];
do {
switch(a->type){
case '=': if (a->iValue == iValue) skip=true; break;
case '!': if (a->iValue != iValue) skip=true; break;
case '&': if (iValue & a->iValue) skip=true; break;
case '<': if (iValue < a->iValue) skip=true; break;
case '>': if (iValue > a->iValue) skip=true; break;
}
if (skip) break;
} while ( a = a->next );
if (skip) continue;
p->done = true;
}
}
void EventsMngr::parseValue(float flValue) {
if ( !parseNotDone ) return;
parseVault[++parsePos].type = MSG_FLOAT;
parseVault[parsePos].fValue = flValue;
bool skip;
for (ClEvent*p=parseFun;p;p=p->next){
if ( p->done || !p->cond[parsePos] ) continue;
skip = false;
ClEvent::cond_t* a = p->cond[parsePos];
do {
switch(a->type){
case '=': if (a->fValue == flValue) skip=true; break;
case '!': if (a->fValue != flValue) skip=true; break;
case '<': if (flValue < a->fValue) skip=true; break;
case '>': if (flValue > a->fValue) skip=true; break;
}
if (skip) break;
} while ( a = a->next );
if (skip) continue;
p->done = true;
}
}
void EventsMngr::parseValue(const char *sz) {
if ( !parseNotDone ) return;
parseVault[++parsePos].type = MSG_STRING;
parseVault[parsePos].sValue = sz;
bool skip;
for (ClEvent*p=parseFun;p;p=p->next){
if ( p->done || !p->cond[parsePos] ) continue;
skip = false;
ClEvent::cond_t* a = p->cond[parsePos];
do {
switch(a->type){
case '=': if (!strcmp(sz,a->sValue.str())) skip=true; break;
case '!': if (strcmp(sz,a->sValue.str())) skip=true; break;
case '&': if (strstr(sz,a->sValue.str())) skip=true; break;
}
if (skip) break;
} while ( a = a->next );
if (skip) continue;
p->done = true;
}
}
void EventsMngr::clearEvents()
{
for(int i=0;i<MAX_AMX_REG_MSG;++i){
ClEvent**b = &modMsgsFunCall[i];
while (*b){
ClEvent*aa = (*b)->next;
delete *b;
*b = aa;
}
}
}
EventsMngr::ClEvent::~ClEvent(){
for(int a = 0; a < MAX_PARSE_VALUES; ++a){
cond_t** b = &cond[a];
while(*b){
cond_t* nn = (*b)->next;
delete *b;
*b = nn;
}
}
}
EventsMngr::ClEvent* EventsMngr::getValidEvent(ClEvent* a ) {
while(a){
if ( a->done ) {
a->done = false;
a = a->next;
continue;
}
a->stamp = *timer;
return a;
}
return 0;
}
int EventsMngr::getEventId( const char* msg ){
struct CS_Events {
const char* name;
CS_EventsIds id;
} table[] = {
{ "CS_DeathMsg" , CS_DeathMsg },
// { "CS_RoundEnd" , CS_RoundEnd },
// { "CS_RoundStart" , CS_RoundStart },
// { "CS_Restart" , CS_Restart },
{ "" , CS_Null }
};
int pos;
if ( (pos = atoi( msg )) != 0 )
return pos;
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
if ( !strcmp( table[ pos ].name , msg ) )
return table[ pos ].id;
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
}

154
amxmodx/CEvent.h Executable file
View File

@ -0,0 +1,154 @@
/*
* 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.
*
*/
#ifndef EVENTS_H
#define EVENTS_H
#define MAX_PARSE_VALUES 32
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
enum {
CS_DEATHMSG = MAX_REG_MSGS,
// CS_ROUNDEND,
// CS_ROUNDSTART,
// CS_RESTART,
};
// *****************************************************
// class EventsMngr
// *****************************************************
class EventsMngr {
enum MsgValueType{
MSG_INTEGER,
MSG_FLOAT,
MSG_STRING,
};
public:
enum CS_EventsIds {
CS_Null = 0,
CS_DeathMsg = MAX_REG_MSGS, // start from last element
// CS_RoundEnd,
// CS_RoundStart,
// CS_Restart,
};
class iterator;
friend class iterator;
class ClEvent {
friend class EventsMngr;
friend class iterator;
CPluginMngr::CPlugin* plugin;
int func;
bool player;
bool world;
bool once;
bool done;
bool dead;
bool alive;
float stamp;
struct cond_t {
String sValue;
float fValue;
int iValue;
int type;
cond_t* next;
} *cond[MAX_PARSE_VALUES];
ClEvent* next;
ClEvent( CPluginMngr::CPlugin* p, int f, int flags );
~ClEvent();
public:
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline int getFunction() { return func; }
void registerFilter( char* filter );
};
private:
struct MsgDataVault {
float fValue;
int iValue;
const char* sValue;
MsgValueType type;
} parseVault[MAX_PARSE_VALUES];
ClEvent* modMsgsFunCall[MAX_AMX_REG_MSG];
ClEvent* parseFun;
bool parseNotDone;
int parsePos; // is -1 less then args. num.
float* timer;
ClEvent* getValidEvent(ClEvent* a );
public:
EventsMngr();
~EventsMngr();
// Interface
ClEvent* registerEvent( CPluginMngr::CPlugin* p, int f, int flags, int pos );
void parserInit(int msg_type, float* timer , CPlayer* target = 0, int index = 0);
void parseValue(int iValue);
void parseValue(float fValue);
void parseValue(const char *sz);
void executeEvents();
inline int getArgNum() { return (parsePos+1); }
const char* getArgString(int a);
int getArgInteger(int a);
float getArgFloat(int a);
void clearEvents(void);
static int getEventId( const char* msg );
class iterator {
EventsMngr* b;
ClEvent* a;
public:
inline iterator(ClEvent*aa,EventsMngr* bb) : a(aa), b(bb) {}
inline iterator& operator++() {
a = b->getValidEvent( a->next );
return *this;
}
inline bool operator==(const iterator& c) const { return a == c.a; }
inline bool operator!=(const iterator& c) const { return !operator==(c); }
ClEvent& operator*() { return *a; }
operator bool ( ) const { return a ? true : false; }
};
inline iterator begin() { return iterator(getValidEvent(parseFun),this); }
inline iterator end() { return iterator(0,this); }
};
#endif

115
amxmodx/CFile.cpp Executable file
View File

@ -0,0 +1,115 @@
/*
* 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 "CFile.h"
#include <ctype.h>
// *****************************************************
// class File
// *****************************************************
File::File( const char* n, const char* m )
{
fp = fopen( n , m );
}
File::~File( )
{
if ( fp )
fclose( fp );
}
File::operator bool ( ) const
{
return fp && !feof(fp);
}
File& operator<<( File& f, const String& n )
{
if ( f ) fputs( n.str() , f.fp ) ;
return f;
}
File& operator<<( File& f, const char* n )
{
if ( f ) fputs( n , f.fp ) ;
return f;
}
File& operator<<( File& f, int n )
{
if ( f ) fprintf( f.fp , "%d" , n ) ;
return f;
}
File& operator<<( File& f, const char& c )
{
if ( f ) fputc( c , f.fp ) ;
return f;
}
File& operator>>( File& f, String& n )
{
if ( !f ) return f;
char temp[1024];
fscanf( f.fp , "%s", temp );
n.set(temp);
return f;
}
File& operator>>( File& f, char* n )
{
if ( f ) fscanf( f.fp , "%s", n );
return f;
}
int File::getline( char* buf, int sz )
{
int a = sz;
if ( *this )
{
int c;
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
*buf++ = c;
*buf = 0;
}
return a - sz;
}
File& File::skipWs( )
{
if ( !*this ) return *this;
int c;
while( isspace( c = getc( fp ) ) ){};
ungetc( c , fp );
return *this;
}

58
amxmodx/CFile.h Executable file
View File

@ -0,0 +1,58 @@
/*
* 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 "CString.h"
#include <stdio.h>
// *****************************************************
// class File
// *****************************************************
class File
{
FILE* fp;
public:
File( const char* n, const char* m );
~File( );
operator bool ( ) const;
friend File& operator<<( File& f, const String& n );
friend File& operator<<( File& f, const char* n );
friend File& operator<<( File& f, const char& c );
friend File& operator<<( File& f, int n );
friend File& operator>>( File& f, String& n );
friend File& operator>>( File& f, char* n );
int getline( char* buf, int sz );
File& skipWs( );
};

80
amxmodx/CForward.cpp Executable file
View File

@ -0,0 +1,80 @@
/*
* 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 "CForward.h"
void CForwardMngr::registerForward( CPluginMngr::CPlugin* p, int func , int type ){
CForward** a = &head[ type ];
while(*a) a = &(*a)->next;
*a = new CForward( p , func );
}
void CForwardMngr::clearForwards( CForward** a ){
while( *a ) {
CForward* b = (*a)->next;
delete *a;
*a = b;
}
}
void CForwardMngr::clear()
{
for ( int a = 0; a < FORWARD_NUM; ++a )
clearForwards( &head[ a ] );
}
void CForwardMngr::executeForwards( int type , int num , int player ) {
cell ret = 0;
int err;
CForward* a = head[ type ];
while ( a )
{
if ( a->getPlugin()->isExecutable( a->getFunction() ) )
{
if ((err = amx_Exec(a->getPlugin()->getAMX(), &ret, a->getFunction() , num, player)) != AMX_ERR_NONE)
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n", err,a->getPlugin()->getAMX()->curline,a->getPlugin()->getName());
if ( ret )
break;
}
a = a->next;
}
}

115
amxmodx/CForward.h Executable file
View File

@ -0,0 +1,115 @@
/*
* 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.
*
*/
#ifndef FORWARD_H
#define FORWARD_H
// *****************************************************
// class CmdMngr
// *****************************************************
#define FORWARD_NUM 12
enum {
FF_ClientCommand,
FF_ClientConnect,
FF_ClientDisconnect,
FF_ClientInfoChanged,
FF_ClientPutInServer,
FF_PluginInit,
FF_PluginCfg,
FF_PluginPrecache,
FF_PluginLog,
FF_PluginEnd,
FF_InconsistentFile,
FF_ClientAuthorized,
};
class CForwardMngr
{
public:
class iterator;
class CForward
{
friend class iterator;
friend class CForwardMngr;
CPluginMngr::CPlugin* plugin;
int function;
CForward* next;
CForward( CPluginMngr::CPlugin* p, int func ) : plugin(p) , function(func) {next=0;}
public:
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline int getFunction() { return function; }
};
private:
CForward *head[ FORWARD_NUM ];
void clearForwards( CForward** a );
public:
CForwardMngr() {memset( head, 0, sizeof(head));}
~CForwardMngr() { clear(); }
// Interface
void registerForward( CPluginMngr::CPlugin* p, int func , int type );
void executeForwards( int type , int num = 0, int player = 0 );
void clear();
class iterator {
CForward *a;
public:
iterator(CForward*aa) : a(aa) {}
iterator& operator++() { a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
operator bool () const { return a ? true : false; }
CForward& operator*() { return *a; }
};
inline iterator begin( int type ) const { return iterator(head[(int)type]); }
inline iterator end() const { return iterator(0); }
inline bool forwardsExist( int type ) {return head[(int)type]?true:false;}
};
#endif

104
amxmodx/CList.h Executable file
View File

@ -0,0 +1,104 @@
/*
* 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.
*
*/
#ifndef CLIST_H
#define CLIST_H
// *****************************************************
// class CList
// *****************************************************
template <typename T, typename F = char* >
class CList {
public:
class iterator;
class CListEle {
friend class CList<T,F>;
friend class iterator;
T* obj;
CListEle* next;
CListEle( T* a , CListEle* nn ) : obj(a) , next(nn) {}
public:
T& operator* () { return *obj; }
};
private:
CListEle *head;
public:
CList<T,F>() { head = 0; }
~CList<T,F>() { clear(); }
void clear() {
iterator a = begin();
while( a ) a.remove();
}
void put( T* a ) {
head = new CListEle( a , head );
}
class iterator {
CListEle** a;
public:
iterator(CListEle** i=0) : a(i){}
T& operator*() const { return *(*a)->obj;}
inline operator bool () const { return (a && *a); }
inline iterator& operator++() {
a = &(*a)->next;
return *this;
}
inline iterator operator++(int) {
iterator tmp(a);
a = &(*a)->next;
return tmp;
}
iterator& remove(){
CListEle* aa = (*a)->next;
delete (*a)->obj;
delete *a;
*a = aa;
return *this;
}
iterator& put( T* aa ){
*a = new CListEle( aa , *a );
return *this;
}
};
inline iterator begin() { return iterator(&head); }
iterator find( F a ){
iterator cc = begin();
while(cc){
if ( *cc == a )
break;
++cc;
}
return cc;
}
};
#endif

253
amxmodx/CLogEvent.cpp Executable file
View File

@ -0,0 +1,253 @@
/*
* 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 "CLogEvent.h"
// *****************************************************
// class LogEventsMngr
// *****************************************************
LogEventsMngr::LogEventsMngr() {
logCurrent = logCounter = 0;
logcmplist = 0;
arelogevents = false;
memset( logevents, 0, sizeof(logevents) );
}
LogEventsMngr::~LogEventsMngr() {
clearLogEvents();
}
int LogEventsMngr::CLogCmp::compareCondition(const char* string){
if ( logid == parent->logCounter )
return result;
logid = parent->logCounter;
if ( in ) return result = strstr( string , text.str() ) ? 0 : 1;
return result = strcmp(string,text.str());
}
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter){
char* temp = filter;
// expand "1=message"
while ( isdigit(*filter) )
++filter;
bool in = (*filter=='&');
*filter++ = 0;
int pos = atoi(temp);
if ( pos < 0 || pos >= MAX_LOGARGS) pos = 0;
CLogCmp* c = logcmplist;
while( c ) {
if ( (c->pos==pos) && (c->in==in) && !strcmp(c->text.str(), filter))
return c;
c = c->next;
}
return logcmplist = new CLogCmp( filter , in , pos , logcmplist,this );
}
void LogEventsMngr::CLogEvent::registerFilter( char* filter ){
CLogCmp *cmp = parent->registerCondition( filter );
if ( cmp == 0 ) return;
for(LogCond* c = filters; c ; c = c->next){
if ( c->argnum == cmp->pos ){
c->list = new LogCondEle( cmp , c->list );
return;
}
}
LogCondEle* aa = new LogCondEle( cmp , 0 );
if ( aa == 0 ) return;
filters = new LogCond( cmp->pos , aa , filters );
}
void LogEventsMngr::setLogString( char* frmt, va_list& vaptr ) {
++logCounter;
int len = vsnprintf (logString, 255 , frmt, vaptr );
if ( len == - 1) {
len = 255;
logString[len] = 0;
}
if ( len ) logString[--len] = 0;
logArgc = 0;
}
void LogEventsMngr::setLogString( char* frmt, ... ) {
++logCounter;
va_list logArgPtr;
va_start ( logArgPtr , frmt );
int len = vsnprintf(logString, 255 , frmt, logArgPtr );
if ( len == - 1) {
len = 255;
logString[len] = 0;
}
va_end ( logArgPtr );
if ( len ) logString[--len] = 0;
logArgc = 0;
}
void LogEventsMngr::parseLogString( ) {
register const char* b = logString;
register int a;
while( *b && logArgc < MAX_LOGARGS ){
a = 0;
if ( *b == '"' ) {
++b;
while ( *b && *b != '"' && a < 127 )
logArgs[logArgc][a++] = *b++;
logArgs[logArgc++][a] = 0;
if ( *b) b+=2; // thanks to double terminator
}
else if ( *b == '(' ) {
++b;
while ( *b && *b != ')' && a < 127 )
logArgs[logArgc][a++] = *b++;
logArgs[logArgc++][a] = 0;
if ( *b) b+=2;
}
else {
while ( *b && *b != '(' && *b != '"' && a < 127 )
logArgs[logArgc][a++] = *b++;
if ( *b ) --a;
logArgs[logArgc++][a] = 0;
}
}
}
LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos )
{
if ( pos < 1 || pos > MAX_LOGARGS)
return 0;
arelogevents = true;
CLogEvent** d = &logevents[pos];
while(*d) d = &(*d)->next;
return *d = new CLogEvent( plugin , func, this );
}
void LogEventsMngr::executeLogEvents()
{
int err;
bool valid;
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next){
valid = true;
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
valid = false;
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
valid = true;
break;
}
}
if (!valid) break;
}
#ifdef ENABLEEXEPTIONS
try
{
#endif
if (valid){
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n",
err,a->plugin->getAMX()->curline,a->plugin->getName());
}
#ifdef ENABLEEXEPTIONS
}
catch( ... )
{
print_srvconsole( "[AMX] fatal error at log forward function execution\n");
}
#endif
}
}
void LogEventsMngr::clearLogEvents(){
logCurrent = logCounter = 0;
arelogevents = false;
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
CLogEvent **a = &logevents[i];
while(*a){
CLogEvent* bb = (*a)->next;
delete *a;
*a = bb;
}
}
clearConditions();
}
void LogEventsMngr::clearConditions() {
while (logcmplist){
CLogCmp* a = logcmplist->next;
delete logcmplist;
logcmplist = a;
}
}
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
while( list ) {
LogCondEle* cc = list->next;
delete list;
list = cc;
}
}
LogEventsMngr::CLogEvent::~CLogEvent() {
while( filters ) {
LogCond* cc = filters->next;
delete filters;
filters = cc;
}
}
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent( CLogEvent * a )
{
bool valid;
while(a){
valid = true;
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
valid = false;
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
valid = true;
break;
}
}
if (!valid) break;
}
if (!valid){
a = a->next;
continue;
}
return a;
}
return 0;
}

166
amxmodx/CLogEvent.h Executable file
View File

@ -0,0 +1,166 @@
/*
* 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.
*
*/
#ifndef LOGEVENTS_H
#define LOGEVENTS_H
#define MAX_LOGARGS 12
#include <stdarg.h>
// *****************************************************
// class LogEventsMngr
// *****************************************************
class LogEventsMngr {
char logString[256];
char logArgs[MAX_LOGARGS][128];
int logArgc;
int logCounter;
int logCurrent;
bool arelogevents;
public:
class CLogCmp;
class iterator;
class CLogEvent;
friend class CLogEvent;
friend class CLogCmp;
friend class iterator;
class CLogCmp
{
friend class LogEventsMngr;
friend class CLogEvent;
LogEventsMngr* parent;
String text;
int logid;
int pos;
int result;
bool in;
CLogCmp *next;
CLogCmp( const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg ) : text(s) {
logid = result = 0;
pos = p;
parent = mg;
in = r;
next = n;
}
public:
int compareCondition(const char* string);
};
private:
CLogCmp *logcmplist;
public:
class CLogEvent {
friend class LogEventsMngr;
friend class iterator;
struct LogCondEle {
CLogCmp *cmp;
LogCondEle *next;
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
};
struct LogCond {
LogCondEle *list;
int argnum;
LogCond *next;
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
~LogCond();
};
CPluginMngr::CPlugin *plugin;
int func;
LogEventsMngr* parent;
LogCond *filters;
CLogEvent *next;
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
~CLogEvent();
public:
void registerFilter( char* filter );
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
inline int getFunction() { return func; }
};
private:
CLogEvent *logevents[MAX_LOGARGS+1];
CLogEvent *getValidLogEvent( CLogEvent * a );
CLogCmp* registerCondition(char* filter);
void clearConditions();
public:
LogEventsMngr();
~LogEventsMngr();
// Interface
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
inline bool logEventsExist() { return arelogevents; }
void setLogString( char* frmt, va_list& vaptr );
void setLogString( char* frmt , ... );
void parseLogString( );
void executeLogEvents();
inline const char* getLogString() { return logString; }
inline int getLogArgNum() { return logArgc; }
inline const char* getLogArg( int i ) { return ( i < 0 || i >= logArgc ) ? "" : logArgs[ i ]; }
void clearLogEvents();
class iterator {
LogEventsMngr* b;
CLogEvent* a;
public:
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
inline iterator& operator++() {
a = b->getValidLogEvent( a->next );
return *this;
}
inline bool operator==(const iterator& c) const { return a == c.a; }
inline bool operator!=(const iterator& c) const { return !operator==(c); }
CLogEvent& operator*() { return *a; }
operator bool ( ) const { return a ? true : false; }
};
inline iterator begin() { return iterator(getValidLogEvent(logevents[ logArgc ]),this); }
inline iterator end() { return iterator(0,this); }
};
#endif

94
amxmodx/CMenu.cpp Executable file
View File

@ -0,0 +1,94 @@
/*
* 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 "CMenu.h"
// *****************************************************
// class MenuMngr
// *****************************************************
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
plugin = a;
keys = k;
menuid = mi;
function = f;
next = 0;
}
MenuMngr::~MenuMngr()
{
clear();
}
int MenuMngr::findMenuId(const char* name, AMX* amx)
{
for( MenuIdEle* b = headid; b ; b = b->next) {
if ( (!b->amx || amx == b->amx) && strstr(name,b->name.str()) )
return b->id;
}
return 0;
}
int MenuMngr::registerMenuId(const char* n, AMX* a )
{
int id = findMenuId( n, a );
if (id) return id;
headid = new MenuIdEle( n, a , headid );
return headid->id;
}
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
{
MenuCommand** temp = &headcmd;
while(*temp) temp = &(*temp)->next;
*temp = new MenuCommand(a,mi, k,f);
}
void MenuMngr::clear()
{
while (headid)
{
MenuIdEle* a = headid->next;
delete headid;
headid = a;
}
while (headcmd)
{
MenuCommand* a = headcmd->next;
delete headcmd;
headcmd = a;
}
}
int MenuMngr::MenuIdEle::uniqueid = 0;

107
amxmodx/CMenu.h Executable file
View File

@ -0,0 +1,107 @@
/*
* 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.
*
*/
#ifndef MENUS_H
#define MENUS_H
// *****************************************************
// class MenuMngr
// *****************************************************
class MenuMngr
{
struct MenuIdEle
{
String name;
AMX* amx;
MenuIdEle* next;
int id;
static int uniqueid;
MenuIdEle( const char* n, AMX* a, MenuIdEle* m ) : name( n ) , amx(a) , next( m ) {
id = ++uniqueid;
}
~MenuIdEle() { --uniqueid; }
} *headid;
public:
class iterator;
private:
class MenuCommand
{
friend class iterator;
friend class MenuMngr;
CPluginMngr::CPlugin *plugin;
int menuid;
int keys;
int function;
MenuCommand* next;
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
public:
inline int getFunction() { return function; }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool matchCommand( int m, int k ) { return ((m == menuid) && (keys & k)); }
} *headcmd;
public:
MenuMngr() { headid = 0; headcmd = 0; }
~MenuMngr();
// Interface
int findMenuId(const char* name, AMX* a = 0);
int registerMenuId(const char* n, AMX* a );
void registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f );
void clear();
class iterator {
MenuCommand* a;
public:
iterator(MenuCommand*aa) : a(aa) {}
iterator& operator++() { a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
operator bool () const { return a ? true : false; }
MenuCommand& operator*() { return *a; }
};
inline iterator begin() const { return iterator(headcmd); }
inline iterator end() const { return iterator(0); }
};
#endif

232
amxmodx/CMisc.cpp Executable file
View File

@ -0,0 +1,232 @@
/*
* 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"
// *****************************************************
// class CPlayer
// *****************************************************
void CPlayer::Init( edict_t* e , int i )
{
index = i;
pEdict = e;
initialized = false;
ingame = false;
bot = false;
authorized = false;
current = 0;
teamId = -1;
deaths = 0;
aiming = 0;
menu = 0;
keys = 0;
death_weapon.clear();
name.clear();
ip.clear();
team.clear();
}
void CPlayer::Disconnect() {
ingame = false;
initialized = false;
authorized = false;
}
void CPlayer::PutInServer() {
playtime = gpGlobals->time;
ingame = true;
}
bool CPlayer::Connect(const char* connectname,const char* ipaddress) {
name.set(connectname);
ip.set(ipaddress);
time = gpGlobals->time;
bot = IsBot();
death_killer = 0;
memset(flags,0,sizeof(flags));
memset(weapons,0,sizeof(weapons));
initialized = true;
authorized = false;
const char* authid = GETPLAYERAUTHID( pEdict );
if ( (authid == 0) || (*authid == 0)
|| (strcmp( authid , "STEAM_ID_PENDING") == 0) )
return true;
return false;
}
// *****************************************************
// class Grenades
// *****************************************************
void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
{
Obj* a = new Obj;
if ( a == 0 ) return;
a->player = player;
a->grenade = grenade;
a->time = gpGlobals->time + time;
a->type = type;
a->next = head;
head = a;
}
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type )
{
bool found = false;
Obj** a = &head;
while ( *a ){
if ( (*a)->time > gpGlobals->time ) {
if ( (*a)->grenade == enemy ) {
found = true;
(*p) = (*a)->player;
type = (*a)->type;
}
}
else {
Obj* b = (*a)->next;
delete *a;
*a = b;
continue;
}
a = &(*a)->next;
}
return found;
}
void Grenades::clear()
{
while(head){
Obj* a = head->next;
delete head;
head = a;
}
}
// *****************************************************
// class XVars
// *****************************************************
void XVars::clear() {
delete[] head;
head = 0;
num = 0;
size = 0;
}
int XVars::put( AMX* p, cell* v )
{
for(int a = 0; a < num; ++a) {
if ( (head[a].amx == p) && (head[a].value == v) )
return a;
}
if ( (num >= size) && realloc_array( size ? (size * 2) : 8 ) )
return -1;
head[num].value = v;
head[num].amx = p;
return num++;
}
int XVars::realloc_array( int nsize )
{
XVarEle* me = new XVarEle[nsize];
if ( me ){
for(int a = 0 ; a < num; ++a)
me[a] = head[a];
delete[] head;
head = me;
size = nsize;
return 0;
}
return 1;
}
// *****************************************************
// class TeamIds
// *****************************************************
TeamIds::TeamIds() { head = 0; newTeam = 0; }
TeamIds::~TeamIds() {
while( head ) {
TeamEle* a = head->next;
delete head;
head = a;
}
}
void TeamIds::registerTeam( const char* n ,int s )
{
TeamEle** a = &head;
while( *a ){
if ( strcmp((*a)->name.str(),n) == 0 ){
if (s != -1){
(*a)->id = s;
newTeam &= ~(1<<(*a)->tid);
}
return;
}
a = &(*a)->next;
}
*a = new TeamEle( n , s );
if ( *a == 0 ) return;
newTeam |= (1<<(*a)->tid);
}
int TeamIds::findTeamId( const char* n )
{
TeamEle* a = head;
while( a ){
if ( !strcmpi(a->name.str(),n) )
return a->id;
a = a->next;
}
return -1;
}
int TeamIds::findTeamIdCase( const char* n)
{
TeamEle* a = head;
while( a ){
if ( !strcmp(a->name.str(), n) )
return a->id;
a = a->next;
}
return -1;
}
char TeamIds::TeamEle::uid = 0;

252
amxmodx/CMisc.h Executable file
View File

@ -0,0 +1,252 @@
/*
* 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.
*
*/
#ifndef CMISC_H
#define CMISC_H
#include "CList.h"
#include "string.h"
// *****************************************************
// class CCVar
// *****************************************************
class CCVar
{
cvar_t cvar;
String name;
String plugin;
public:
CCVar( const char* pname, const char* pplugin,
int pflags, float pvalue ) : name(pname) , plugin(pplugin ) {
cvar.name = (char*)name.str();
cvar.flags = pflags;
cvar.string = "";
cvar.value = pvalue;
}
inline cvar_t* getCvar() { return &cvar; }
inline const char* getPluginName() { return plugin.str(); }
inline const char* getName() { return name.str(); }
inline bool operator == ( const char* string ) const { return (strcmp(name.str(),string)==0); }
};
// *****************************************************
// class CPlayer
// *****************************************************
class CPlayer
{
public:
edict_t* pEdict;
String name;
String ip;
String team;
bool initialized;
bool ingame;
bool bot;
bool authorized;
float time;
float playtime;
struct {
int ammo;
int clip;
} weapons[MAX_WEAPONS];
int current;
int teamId;
int deaths;
int aiming;
int menu;
int keys;
int index;
int flags[32];
int death_headshot;
int death_killer;
int death_victim;
bool death_tk;
String death_weapon;
Vector lastTrace;
Vector thisTrace;
Vector lastHit;
void Init( edict_t* e , int i );
void Disconnect();
void PutInServer();
bool Connect(const char* connectname,const char* ipaddress);
inline bool IsBot(){
const char* auth= (*g_engfuncs.pfnGetPlayerAuthId)(pEdict);
return ( auth && !strcmp( auth , "BOT" ) );
}
inline bool IsAlive(){
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
}
inline void Authorize() { authorized = true; }
};
// *****************************************************
// class Grenades
// *****************************************************
class Grenades
{
struct Obj
{
CPlayer* player;
edict_t* grenade;
float time;
int type;
Obj* next;
} *head;
public:
Grenades() { head = 0; }
~Grenades() { clear(); }
void put( edict_t* grenade, float time, int type, CPlayer* player );
bool find( edict_t* enemy, CPlayer** p, int& type );
void clear();
};
// *****************************************************
// class ForceObject
// *****************************************************
class ForceObject {
AMX* amx;
String filename;
FORCE_TYPE type;
Vector mins;
Vector maxs;
public:
ForceObject(const char* n, FORCE_TYPE c,Vector& mi, Vector& ma, AMX* a) :
filename(n) , type(c), mins(mi), maxs(ma), amx(a) {}
inline const char* getFilename() { return filename.str(); }
inline AMX* getAMX() { return amx; }
Vector& getMin() { return mins; }
Vector& getMax() { return maxs; }
inline FORCE_TYPE getForceType() { return type; }
};
// *****************************************************
// class XVars
// *****************************************************
class XVars
{
struct XVarEle {
AMX* amx;
cell* value;
};
XVarEle* head;
int size;
int num;
int realloc_array( int nsize );
public:
XVars() { num = 0; size = 0; head = 0; }
~XVars() { clear(); }
void clear();
int put( AMX* a, cell* v );
inline cell getValue( int a ) {
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
}
inline int setValue( int a, cell v ) {
if ( a >= 0 && a < num ){
*(head[a].value) = v;
return 0;
}
return 1;
}
};
// *****************************************************
// class CScript
// *****************************************************
class CScript
{
String filename;
AMX* amx;
void* code;
public:
CScript(AMX* aa, void* cc,const char* ff):filename(ff),amx(aa),code(cc){}
inline AMX* getAMX() { return amx; }
inline const char* getName() { return filename.str(); }
inline bool operator==( void* a ) { return (amx == (AMX*)a); }
inline void* getCode() { return code; }
};
// *****************************************************
// class TeamIds
// *****************************************************
class TeamIds
{
struct TeamEle {
String name;
int id;
char tid;
static char uid;
TeamEle* next;
TeamEle(const char* n, int& i) : name(n) , id(i) , next(0) {
tid = uid++;
};
~TeamEle(){ --uid; }
} *head;
int newTeam;
public:
TeamIds();
~TeamIds();
void registerTeam( const char* n ,int s );
int findTeamId( const char* n);
int findTeamIdCase( const char* n);
inline bool isNewTeam() { return newTeam ? true : false; }
};
#endif

188
amxmodx/CModule.cpp Executable file
View File

@ -0,0 +1,188 @@
/*
* 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"
typedef int (FAR *QUERYMOD)(module_info_s**);
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
typedef int (FAR *DETACHMOD)(void);
QUERYMOD QueryModule;
ATTACHMOD AttachModule;
DETACHMOD DetachModule;
pfnamx_engine_g engAmxFunc = {
amx_Align16,
amx_Align32,
amx_Allot,
amx_Callback,
amx_Clone,
amx_Debug,
amx_Exec,
amx_Execv,
amx_FindPublic,
amx_FindPubVar,
amx_FindTagId,
amx_Flags,
amx_GetAddr,
amx_GetPublic,
amx_GetPubVar,
amx_GetString,
amx_GetTag,
amx_GetUserData,
amx_Init,
amx_InitJIT,
amx_MemInfo,
amx_NameLength,
amx_NativeInfo,
amx_NumPublics,
amx_NumPubVars,
amx_NumTags,
amx_RaiseError,
amx_Register,
amx_Release,
amx_SetCallback,
amx_SetDebugHook,
amx_SetString,
amx_SetUserData,
amx_StrLen,
};
pfnmodule_engine_g engModuleFunc = {
add_amxnatives,
build_pathname,
copy_amxmemory,
format_amxstring,
get_amxaddr,
get_amxscript,
get_amxscriptname,
get_amxstring,
get_modname,
load_amxscript,
print_srvconsole,
report_error,
set_amxnatives,
set_amxstring,
amxstring_len,
unload_amxscript,
alloc_amxmemory,
free_amxmemory,
};
// *****************************************************
// class CModule
// *****************************************************
CModule::CModule(const char* fname) : filename(fname)
{
metamod = false;
info = 0;
module = 0;
status = MODULE_NONE;
}
CModule::~CModule()
{
if ( module ) DLFREE(module);
natives.clear();
}
bool CModule::attachModule()
{
if ( status != MODULE_QUERY )
return false;
AttachModule = (ATTACHMOD)DLPROC(module,"AMX_Attach");
if ( AttachModule ) (*AttachModule)(&engAmxFunc,&engModuleFunc);
status = MODULE_LOADED;
return true;
}
bool CModule::queryModule()
{
if ( status != MODULE_NONE ) // don't check if already quried
return false;
module = DLLOAD( filename.str() ); // link dll
if ( !module ){
status = MODULE_BADLOAD;
return false;
}
int meta = (int)DLPROC(module,"Meta_Attach"); // check if also MM
if ( meta ) metamod = true;
QueryModule = (QUERYMOD)DLPROC(module,"AMX_Query"); // check what version
if (QueryModule == 0) {
status = MODULE_NOQUERY;
return false;
}
(*QueryModule)( &info );
if ( info == 0 ){
status = MODULE_NOINFO;
return false;
}
if ( info->ivers != AMX_INTERFACE_VERSION ) {
status = MODULE_OLD;
return false;
}
AttachModule = (ATTACHMOD)DLPROC(module,"AMX_Attach"); // check for attach
if ( AttachModule == 0) {
status = MODULE_NOATTACH;
return false;
}
info->serial = (long int)this;
status = MODULE_QUERY;
return true;
}
bool CModule::detachModule()
{
if ( status != MODULE_LOADED )
return false;
DetachModule = (DETACHMOD)DLPROC(module,"AMX_Detach");
if (DetachModule) (*DetachModule)();
DLFREE(module);
module = 0;
natives.clear();
status = MODULE_NONE;
return true;
}
const char* CModule::getStatus() const {
switch(status){
case MODULE_NONE: return "error";
case MODULE_QUERY: return "pending";
case MODULE_BADLOAD:return "bad load";
case MODULE_LOADED:return "running";
case MODULE_NOINFO:return "no info";
case MODULE_NOQUERY:return "no query";
case MODULE_NOATTACH:return "no attach";
case MODULE_OLD:return "old";
}
return "unknown";
}

84
amxmodx/CModule.h Executable file
View File

@ -0,0 +1,84 @@
/*
* 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.
*
*/
// *****************************************************
// class CModule
// *****************************************************
#ifndef CMODULE_H
#define CMODULE_H
enum MODULE_STATUS {
MODULE_NONE,
MODULE_QUERY,
MODULE_BADLOAD,
MODULE_LOADED,
MODULE_NOINFO,
MODULE_NOQUERY,
MODULE_NOATTACH,
MODULE_OLD
};
class CModule
{
String filename;
bool metamod;
module_info_s* info;
DLHANDLE module;
MODULE_STATUS status;
public:
CModule(const char* fname);
~CModule();
// Interface
bool attachModule();
bool queryModule();
bool detachModule();
const char* getStatus() const;
inline const char* getType() const { return metamod ? "amx&mm" : "amx"; }
inline const char* getAuthor() const { return info ? info->author : "unknown"; }
inline const char* getVersion() const { return info ? info->version : "unknown"; }
inline const char* getName() const { return info ? info->name : "unknown"; }
inline module_info_s* getInfo() const { return info; }
inline int getStatusValue() { return status; }
inline bool operator==( void* fname ) { return !strcmp( filename.str() , (char*)fname ); }
inline bool isReloadable() { return ( (status==MODULE_LOADED) && (info->type==RELOAD_MODULE)); }
CList<AMX_NATIVE_INFO*> natives;
};
#endif

340
amxmodx/COPYING Executable file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

207
amxmodx/CPlugin.cpp Executable file
View File

@ -0,0 +1,207 @@
/*
* 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 "CPlugin.h"
#include "CForward.h"
#include "CFile.h"
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error) {
CPlugin** a = &head;
while( *a ) a = &(*a)->next;
*a = new CPlugin( pCounter++ ,path,name,error);
return *error ? 0 : *a;
}
void CPluginMngr::unloadPlugin( CPlugin** a ) {
CPlugin* next = (*a)->next;
delete *a;
*a = next;
--pCounter;
}
int CPluginMngr::loadPluginsFromFile( const char* filename )
{
File fp( build_pathname("%s",filename) , "r" );
if ( !fp )
{
print_srvconsole( "[AMX] Plugins list not found (file \"%s\")\n",filename);
return 1;
}
// Find now folder
char pluginName[256], line[256], error[256], pluginsDir[256];
strcpy(pluginsDir,filename);
char* ptrEnd = pluginsDir;
for (int i = 0; pluginsDir[i];++i ) {
if (pluginsDir[i] == '/' || pluginsDir[i] == '\\')
ptrEnd = &pluginsDir[i];
}
*ptrEnd = 0;
while ( fp.getline(line , 255 ) )
{
*pluginName = 0;
sscanf(line,"%s",pluginName);
if (!isalnum(*pluginName)) continue;
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error );
if ( plugin != 0 ) // load_amxscript fills it with info in case of error
{
AMX* amx = plugin->getAMX();
int iFunc;
if(amx_FindPublic(amx, "client_command" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientCommand);
if(amx_FindPublic(amx, "client_connect" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientConnect);
if(amx_FindPublic(amx, "client_disconnect" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientDisconnect);
if(amx_FindPublic(amx, "client_infochanged" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientInfoChanged);
if(amx_FindPublic(amx, "client_putinserver" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientPutInServer);
if(amx_FindPublic(amx, "plugin_init" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_PluginInit);
if(amx_FindPublic(amx, "plugin_cfg" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_PluginCfg);
if(amx_FindPublic(amx, "plugin_precache" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_PluginPrecache);
if(amx_FindPublic(amx, "plugin_log" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_PluginLog);
if(amx_FindPublic(amx, "plugin_end" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_PluginEnd);
if(amx_FindPublic(amx, "inconsistent_file" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_InconsistentFile);
if(amx_FindPublic(amx, "client_authorized" , &iFunc) == AMX_ERR_NONE)
g_forwards.registerForward( plugin , iFunc , FF_ClientAuthorized);
}
else
{
print_srvconsole("[AMX] %s (plugin \"%s\")\n", error, pluginName );
}
}
return pCounter;
}
void CPluginMngr::clear() {
CPlugin**a = &head;
while ( *a )
unloadPlugin(a);
}
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
{
return (CPlugin*)(amx->userdata[3]);
/*CPlugin*a = head;
while ( a && &a->amx != amx )
a=a->next;
return a;*/
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
CPlugin*a = head;
while ( a && &a->amx != amx )
a=a->next;
return a;
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){
CPlugin*a = head;
while ( a && index--)
a=a->next;
return a;
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) {
if (!name) return 0;
int len = strlen(name);
if (!len) return 0;
CPlugin*a = head;
while( a && strncmp(a->name.str(), name,len) )
a=a->next;
return a;
}
const char* CPluginMngr::CPlugin::getStatus() const {
switch(status){
case ps_running: return "running";
case ps_paused: return "paused";
case ps_bad_load: return "bad load";
case ps_stopped: return "stopped";
case ps_locked: return "locked";
}
return "error";
}
CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e) : name(n), title(n) {
const char* unk = "unknown";
title.set(unk);
author.set(unk);
version.set(unk);
char* path = build_pathname("%s/%s",p,n);
code = 0;
int err = load_amxscript(&amx,&code,path,e );
if ( err == AMX_ERR_NONE ) status = ps_running;
else status = ps_bad_load;
amx.userdata[3] = this;
paused_fun = 0;
next = 0;
id = i;
}
CPluginMngr::CPlugin::~CPlugin( ){
unload_amxscript( &amx, &code );
}
void CPluginMngr::CPlugin::pauseFunction( int id ) {
if (isValid()){
paused_fun |= (1<<id);
g_commands.clearBufforedInfo();
}
}
void CPluginMngr::CPlugin::unpauseFunction( int id ) {
if (isValid()) {
paused_fun &= ~(1<<id);
g_commands.clearBufforedInfo();
}
}
void CPluginMngr::CPlugin::setStatus( int a ) {
status = a;
g_commands.clearBufforedInfo(); // ugly way
}

132
amxmodx/CPlugin.h Executable file
View File

@ -0,0 +1,132 @@
/*
* 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.
*
*/
#ifndef PLUGIN_H
#define PLUGIN_H
// *****************************************************
// class CPluginMngr
// *****************************************************
enum {
ps_bad_load,
ps_error,
ps_paused,
ps_running,
ps_stopped,
ps_locked
};
class CPluginMngr
{
public:
class iterator;
class CPlugin
{
friend class iterator;
friend class CPluginMngr;
AMX amx;
void* code;
String name;
String version;
String title;
String author;
int paused_fun;
int status;
CPlugin* next;
int id;
CPlugin(int i , const char* p,const char* n, char* e);
~CPlugin( );
public:
inline const char* getName() const { return name.str();}
inline const char* getVersion() const { return version.str();}
inline const char* getTitle() const { return title.str();}
inline const char* getAuthor()const { return author.str();}
inline int getId() const { return id; }
inline AMX* getAMX() { return &amx; }
inline void setTitle( const char* n ) { title.set(n); }
inline void setAuthor( const char* n ) { author.set(n); }
inline void setVersion( const char* n ) { version.set(n); }
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); }
inline bool isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); }
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
inline void pausePlugin( ) { if ( isValid() ) setStatus(ps_paused); }
inline void unpausePlugin( ) { if ( isValid() ) setStatus(ps_running); }
void pauseFunction( int id );
void unpauseFunction( int id );
void setStatus( int a );
const char* getStatus() const;
};
private:
CPlugin *head;
int pCounter;
public:
CPluginMngr() { head = 0; pCounter = 0; }
~CPluginMngr() { clear(); }
// Interface
CPlugin* loadPlugin(const char* path, const char* name, char* error);
void unloadPlugin( CPlugin** a );
int loadPluginsFromFile( const char* filename );
CPlugin* findPluginFast(AMX *amx);
CPlugin* findPlugin(AMX *amx);
CPlugin* findPlugin(int index);
CPlugin* findPlugin(const char* name);
inline int getPluginsNum() const { return pCounter; }
void clear();
class iterator {
CPlugin *a;
public:
iterator(CPlugin*aa) : a(aa) {}
iterator& operator++() { a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
operator bool () const { return a ? true : false; }
CPlugin& operator*() { return *a; }
};
inline iterator begin() const { return iterator(head); }
inline iterator end() const { return iterator(0); }
};
#endif

69
amxmodx/CString.cpp Executable file
View File

@ -0,0 +1,69 @@
/*
* 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 "CString.h"
#include "string.h"
#include "CFile.h"
String::String()
{
len = 0;
napis = 0;
}
String::String( const char* n )
{
napis = 0;
set(n);
}
String::~String()
{
clear();
}
void String::set( const char* n )
{
clear();
if ( n != 0 ){
len = strlen( n );
napis = new char[ len + 1 ];
if ( napis ) strcpy( napis , n );
else len = 0;
}
}
void String::clear() {
delete[] napis;
napis = 0;
len = 0;
}

58
amxmodx/CString.h Executable file
View File

@ -0,0 +1,58 @@
/*
* 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.
*
*/
#ifndef STRING_CUSTOM_H
#define STRING_CUSTOM_H
// *****************************************************
// class String
// *****************************************************
class String
{
char* napis;
short int len;
public:
String();
String( const char* n );
~String();
void set( const char* n );
inline bool empty() const { return (len == 0); }
inline const char* str() const { return napis ? napis : "(null)"; }
inline short int size() const { return len; }
void clear();
};
#endif

192
amxmodx/CTask.cpp Executable file
View File

@ -0,0 +1,192 @@
/*
* 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 "CTask.h"
CTaskMngr::CTask::CTask( CPluginMngr::CPlugin* p, int f, int flags,
int i, float base, float exec, int parlen ,
const cell* par, int r){
plugin = p;
func = f;
id = i;
next = 0;
prev = 0;
param_len = 0;
param = 0;
base_time = base;
exec_time = exec;
repeat = (flags & 1) ? r : 0;
loop = (flags & 2) ? true : false;
afterstart = (flags & 4) ? true : false;
beforeend = (flags & 8) ? true : false;
if ( parlen )
{
param = new cell[ parlen + 1 ];
if ( param ){
param_len = parlen + 1;
memcpy( param , par , sizeof( cell ) * parlen );
param[ parlen ] = 0;
}
}
}
CTaskMngr::CTask* CTaskMngr::getFirstValidTask(CTask* h){
CTask* a = h;
while( a ) {
if ( a->isRemoved() ) {
CTask* b = a->next;
unlink( a );
delete a;
a = b;
continue;
}
else if ( a->afterstart ){
if ( *m_timer - *m_timeleft + 1 < a->base_time ) {
a = a->next;
continue;
}
}
else if ( a->beforeend ){
if ( *m_timelimit == 0 ){
a = a->next;
continue;
}
if ( (*m_timeleft + *m_timelimit * 60.0) - *m_timer - 1 >
a->base_time ){
a = a->next;
continue;
}
}
else if ( a->exec_time > *m_timer ) {
a = a->next;
continue;
}
return a;
}
return 0;
}
CTaskMngr::CTask* CTaskMngr::getNextTask(CTask* a) {
if ( a->isRemoved() )
return a->next;
if ( a->loop || a->isToReply() ){
a->exec_time = *m_timer + a->base_time;
return a->next;
}
a->setToRemove();
return a->next;
}
CTaskMngr::CTaskMngr() {
head = 0;
tail = 0;
m_timer = 0;
m_timelimit = 0;
m_timeleft = 0;
}
CTaskMngr::~CTaskMngr() {
clear();
}
void CTaskMngr::clear() {
while ( head ) {
tail = head->next;
delete head;
head = tail;
}
}
void CTaskMngr::registerTimers( float* timer , float* timelimit, float* timeleft ) {
m_timer = timer;
m_timelimit = timelimit;
m_timeleft = timeleft;
}
void CTaskMngr::registerTask( CPluginMngr::CPlugin* plugin, int func,
int flags, int i, float base, float exec,
int parlen , const cell* par, int repeat ){
CTask* a = new CTask(plugin,func,flags,i,base,exec,parlen,par,repeat );
if ( a == 0 ) return;
if ( tail )
{
tail->next = a;
a->prev = tail;
tail = a;
}
else {
head = a;
tail = a;
}
}
CTaskMngr::CTask* CTaskMngr::findTask( int id , AMX* amx )
{
for (CTask* a = head; a ; a = a->next)
{
if ( !a->isRemoved() && (a->getTaskId() == id) && (!amx ||
(a->getPlugin()->getAMX() == amx)) )
return a;
}
return 0;
}
void CTaskMngr::unlink(CTask* a){
if ( a->prev ) a->prev->next = a->next;
else head = a->next;
if ( a->next ) a->next->prev = a->prev;
else tail = a->prev;
}
int CTaskMngr::removeTasks( int id , AMX* amx )
{
CTask* a;
int i = 0;
while ( (a = findTask(id, amx )) != 0 ) {
a->setToRemove();
++i;
}
return i;
}

128
amxmodx/CTask.h Executable file
View File

@ -0,0 +1,128 @@
/*
* 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.
*
*/
#ifndef CTASK_H
#define CTASK_H
// *****************************************************
// class CTaskMngr
// *****************************************************
class CTaskMngr
{
public:
class iterator;
class CTask
{
friend class iterator;
friend class CTaskMngr;
CPluginMngr::CPlugin* plugin;
int id;
int func;
int repeat;
bool loop;
bool afterstart;
bool beforeend;
float base_time;
float exec_time;
int param_len;
cell* param;
CTask* next;
CTask* prev;
inline void setToRemove() { exec_time = -1.0f; }
inline bool isToReply() { return (repeat-- > 0); }
inline bool isRemoved() { return (exec_time == -1.0f); }
CTask( CPluginMngr::CPlugin* p, int f, int flags, int i,
float base, float exec, int parlen , const cell* par, int r );
~CTask() { if ( param_len ) delete[] param; }
public:
inline int getParamLen() { return param_len; }
inline int getTaskId() { return id; }
inline int getFunction() { return func; }
cell* getParam() { return param; }
CPluginMngr::CPlugin* getPlugin() { return plugin; }
};
private:
friend class iterator;
CTask *head;
CTask *tail;
float* m_timer;
float* m_timelimit;
float* m_timeleft;
CTask* getFirstValidTask(CTask* a);
CTask* getNextTask(CTask* a);
CTask* findTask( int id , AMX* amx );
void unlink(CTask* a);
public:
CTaskMngr();
~CTaskMngr();
// Interface
void registerTimers( float* timer , float* timelimit, float* timeleft );
void registerTask( CPluginMngr::CPlugin* plugin, int func, int flags, int i, float base, float exec, int parlen , const cell* par, int repeat );
inline int taskExists( int id ,AMX* amx) { return findTask(id,amx ) ? 1 : 0; }
int removeTasks( int id , AMX* amx );
void clear();
class iterator {
CTaskMngr* b;
CTask* a;
public:
iterator(CTask*aa,CTaskMngr* bb) : a(aa), b(bb) {}
iterator& operator++() {
a = b->getNextTask( a );
a = b->getFirstValidTask( a );
return *this;
}
CTask& operator*() { return *a; }
operator bool ( ) const { return a ? true : false; }
};
inline iterator begin() { return iterator(getFirstValidTask(head),this); }
};
#endif

177
amxmodx/CVault.cpp Executable file
View File

@ -0,0 +1,177 @@
/*
* 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 "CVault.h"
#include "CFile.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
// *****************************************************
// class Vault
// *****************************************************
bool Vault::exists( const char* k )
{
if ( *k == 0 ) return false;
return *find( k ) != 0;
}
void Vault::put( const char* k, const char* v )
{
if ( *k == 0 ) return;
if ( *v == 0 )
{
remove( k );
return;
}
Obj** a = find( k );
if ( *a )
{
(*a)->value.set(v);
(*a)->number = atoi( v );
}
else
*a = new Obj( k , v );
}
Vault::Obj::Obj( const char* k, const char* v): key(k) , value(v) , next(0) {
number = atoi(v);
}
Vault::Obj** Vault::find( const char* n )
{
Obj** a = &head;
while( *a )
{
if ( strcmp((*a)->key.str(), n) == 0 )
return a;
a = &(*a)->next;
}
return a;
}
int Vault::get_number( const char* n )
{
if ( *n == 0 ) return 0;
Obj* b = *find( n );
if ( b == 0 ) return 0;
return b->number;
}
const char* Vault::get( const char* n )
{
if ( *n == 0 ) return "";
Obj* b = *find( n );
if ( b == 0 ) return "";
return b->value.str();
}
void Vault::clear()
{
while ( head )
{
Obj* a = head->next;
delete head;
head = a;
}
}
void Vault::remove( const char* n )
{
Obj** b = find( n );
if ( *b == 0 ) return;
Obj* a = (*b)->next;
delete *b;
*b = a;
}
void Vault::setSource( const char* n )
{
path.set(n);
}
bool Vault::loadVault( )
{
if ( path.empty() ) return false;
clear();
File a( path.str() , "r" );
if ( !a ) return false;
const int sz = 512;
char value[sz+1];
char key[sz+1];
while ( a >> key && a.skipWs() && a.getline( value , sz ) )
{
if ( isalpha ( *key ) )
put( key, value );
}
return true;
}
bool Vault::saveVault( )
{
if ( path.empty() ) return false;
File a( path.str() , "w" );
if ( !a ) return false;
a << "; Don't modify!" << '\n';
for (Obj* b = head; b ;b = b->next)
a << b->key << '\t' << b->value << '\n';
return true;
}

93
amxmodx/CVault.h Executable file
View File

@ -0,0 +1,93 @@
/*
* 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.
*
*/
#ifndef VAULT_CUSTOM_H
#define VAULT_CUSTOM_H
#include "CString.h"
#include "CList.h"
// *****************************************************
// class Vault
// *****************************************************
class Vault
{
struct Obj
{
String key;
String value;
int number;
Obj *next;
Obj( const char* k, const char* v);
} *head;
String path;
Obj** find( const char* n );
public:
Vault() {head=0;}
~Vault() { clear();}
// Interface
bool exists( const char* k );
void put(const char* k, const char* v);
void remove( const char* k );
const char* get( const char* n );
int get_number( const char* n );
void setSource( const char* n );
bool loadVault( );
bool saveVault( );
void clear();
class iterator {
Obj * a;
public:
iterator(Obj*aa) : a(aa) {}
iterator& operator++() { if ( a ) a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
String& key() const { return a->key; }
String& value() const { return a->value; }
};
inline iterator begin() const { return iterator(head); }
inline iterator end() const { return iterator(0); }
};
#endif

116
amxmodx/Makefile Executable file
View File

@ -0,0 +1,116 @@
MODNAME = amx_mm
SRCFILES = meta_api.cpp CFile.cpp CString.cpp CVault.cpp vault.cpp\
float.cpp file.cpp modules.cpp CMisc.cpp CTask.cpp string.cpp\
amxmod.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp srvcmd.cpp strptime.cpp\
CForward.cpp CPlugin.cpp CModule.cpp CMenu.cpp emsg.cpp util.cpp
CSRCFILES = amx.c amxcore.c amxtime.c power.c
EXTRA_LIBS_LINUX =
EXTRA_LIBS_WIN32 =
EXTRA_LIBDIRS_LINUX = -Lextra/lib_linux
EXTRA_LIBDIRS_WIN32 = -Lextra/lib_win32
EXTRA_INCLUDEDIRS = -Iextra/include
EXTRA_FLAGS = -Dstrcmpi=strcasecmp
SDKTOP=../hlsdk
METADIR=../metamod/metamod
SDKSRC=$(SDKTOP)/SourceCode
OBJDIR_LINUX=obj.linux
OBJDIR_WIN32=obj.win32
SRCDIR=.
ifdef windir
OS=WIN32
else
OS=LINUX
endif
CC_LINUX=gcc
ifeq "$(OS)" "WIN32"
CC_WIN32=gcc
LD_WINDLL=dllwrap
DEFAULT=win32
CLEAN=clean_win32
else
CC_WIN32=/usr/local/cross-tools/i386-mingw32msvc/bin/gcc
LD_WINDLL=/usr/local/cross-tools/bin/i386-mingw32msvc-dllwrap
DEFAULT=linux win32
CLEAN=clean_both
endif
LIBFILE_LINUX = $(MODNAME)_i386.so
LIBFILE_WIN32 = $(MODNAME).dll
TARGET_LINUX = $(OBJDIR_LINUX)/$(LIBFILE_LINUX)
TARGET_WIN32 = $(OBJDIR_WIN32)/$(LIBFILE_WIN32)
FILES_ALL = *.cpp *.h [A-Z]* *.rc
ifeq "$(OS)" "LINUX"
ASRCFILES := $(shell ls -t $(SRCFILES))
else
ASRCFILES := $(shell dir /b)
endif
OBJ_LINUX := $(SRCFILES:%.cpp=$(OBJDIR_LINUX)/%.o)
OBJC_LINUX := $(CSRCFILES:%.c=$(OBJDIR_LINUX)/%.o)
OBJ_WIN32 := $(SRCFILES:%.cpp=$(OBJDIR_WIN32)/%.o)
OBJC_WIN32 := $(CSRCFILES:%.c=$(OBJDIR_WIN32)/%.o)
CCOPT = -march=i586 -O6 -ffast-math -funroll-loops \
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
-malign-jumps=2 -malign-functions=2 -s -DNDEBUG
INCLUDEDIRS=-I../curl/include -I$(SRCDIR) -I$(METADIR) -I$(SDKSRC)/engine -I$(SDKSRC)/common -I$(SDKSRC)/pm_shared -I$(SDKSRC)/dlls -I$(SDKSRC) $(EXTRA_INCLUDEDIRS)
CFLAGS=-Wall -Wno-unknown-pragmas
ODEF = -DOPT_TYPE=\"optimized\"
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
DO_CC_LINUX=$(CC_LINUX) $(CFLAGS) -fPIC $(INCLUDEDIRS) -o $@ -c $<
DO_CC_WIN32=$(CC_WIN32) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $<
LINK_LINUX=$(CC_LINUX) $(CFLAGS) -shared -ldl -lm $(OBJ_LINUX) $(OBJC_LINUX) $(EXTRA_LIBDIRS_LINUX) $(EXTRA_LIBS_LINUX) -o $@
LINK_WIN32=$(LD_WINDLL) -mwindows --def $(MODNAME).def --add-stdcall-alias $(OBJ_WIN32) $(OBJC_WIN32) $(EXTRA_LIBDIRS_WIN32) $(EXTRA_LIBS_WIN32) -o $@
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c
$(DO_CC_LINUX)
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp
$(DO_CC_LINUX)
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c
$(DO_CC_WIN32)
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.cpp
$(DO_CC_WIN32)
default: $(DEFAULT)
$(TARGET_LINUX): $(OBJDIR_LINUX) $(OBJ_LINUX) $(OBJC_LINUX)
$(LINK_LINUX)
$(TARGET_WIN32): $(OBJDIR_WIN32) $(OBJ_WIN32) $(OBJC_WIN32)
$(LINK_WIN32)
$(OBJDIR_LINUX):
mkdir $@
$(OBJDIR_WIN32):
mkdir $@
win32: $(TARGET_WIN32)
linux: $(TARGET_LINUX)
clean: $(CLEAN)
clean_both:
-rm -f $(OBJDIR_LINUX)/*
-rm -f $(OBJDIR_WIN32)/*
clean_win32:
del /q $(OBJDIR_WIN32)

3208
amxmodx/amx.c Executable file

File diff suppressed because it is too large Load Diff

271
amxmodx/amx.h Executable file
View File

@ -0,0 +1,271 @@
/* Abstract Machine for the Small compiler
*
* Copyright (c) ITB CompuPhase, 1997-2002
* This file may be freely used. No warranties of any kind.
*
* Version: $Id$
*/
#if defined __linux__
#include <sclinux.h>
#endif
#ifndef __AMX_H
#define __AMX_H
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
* here, these types are probably undefined.
*/
#if defined __LCC__ || defined __linux__
#include <stdint.h>
#else
typedef short int int16_t;
typedef unsigned short int uint16_t;
#if defined SN_TARGET_PS2
typedef int int32_t;
typedef unsigned int uint32_t;
#else
typedef long int int32_t;
typedef unsigned long int uint32_t;
#endif
#endif
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if defined SN_TARGET_PS2
#define AMX_NO_ALIGN
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* calling convention for native functions */
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL
#endif
/* calling convention for all interface functions and callback functions */
#if !defined AMXAPI
#define AMXAPI
#endif
/* File format version Required AMX version
* 0 (original version) 0
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
* 2 (compressed files) 2
* 3 (public variables) 2
* 4 (opcodes SWAP.pri/alt and PUSHADDR) 4
* 5 (tagnames table) 4
* 6 (reformatted header) 6
*/
#define MIN_FILE_VERSION 6 /* lowest file format version */
#define CUR_FILE_VERSION 6 /* current AMX version (parallel with file version) */
#if !defined CELL_TYPE
#define CELL_TYPE
#if defined(BIT16)
typedef uint16_t ucell; /* only for type casting */
typedef int16_t cell;
#else
typedef uint32_t ucell;
typedef int32_t cell;
#endif
#endif
struct __amx;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct __amx *amx, cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct __amx *amx, cell index,
cell *result, cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct __amx *amx);
#if !defined FAR
#define FAR
#endif
#if defined _MSC_VER
#pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */
#endif
#if !defined AMX_NO_ALIGN
#if defined __linux__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#if defined __TURBOC__
#pragma option -a- /* "pack" pragma for older Borland compilers */
#endif
#endif
#endif
typedef struct {
char FAR *name;
AMX_NATIVE func;
} AMX_NATIVE_INFO;
#define AMX_USERNUM 4
#define sEXPMAX 19
typedef struct {
uint32_t address;
char name[sEXPMAX+1];
} AMX_FUNCSTUB;
/* The AMX structure is the internal structure for many functions. Not all
* fields are valid at all times; many fields are cached in local variables.
*/
typedef struct __amx {
unsigned char FAR *base; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
unsigned char FAR *data; /* points to separate data+stack+heap, may be NULL */
AMX_CALLBACK callback;
AMX_DEBUG debug;
/* for external functions a few registers must be accessible from the outside */
cell cip; /* relative to base + amxhdr->cod */
cell frm; /* relative to base + amxhdr->dat */
cell hea, hlw, stk, stp; /* all four are relative to base + amxhdr->dat */
int flags; /* current status, see amx_Flags() */
/* for assertions and debug hook */
cell curline, curfile;
int dbgcode;
cell dbgaddr, dbgparam;
char FAR *dbgname;
/* user data */
long usertags[AMX_USERNUM];
void FAR *userdata[AMX_USERNUM];
/* native functions can raise an error */
int error;
/* the sleep opcode needs to store the full AMX status */
cell pri, alt, reset_stk, reset_hea;
#if defined JIT
/* support variables for the JIT */
int reloc_size; /* required temporary buffer for relocations */
long code_size; /* estimated memory footprint of the native code */
#endif
} AMX;
/* The AMX_HEADER structure is both the memory format as the file format. The
* structure is used internaly.
*/
typedef struct __amx_header {
int32_t size; /* size of the "file" */
uint16_t magic; /* signature */
char file_version; /* file format version */
char amx_version; /* required version of the AMX */
int16_t flags;
int16_t defsize;
int32_t cod; /* initial value of COD - code block */
int32_t dat; /* initial value of DAT - data block */
int32_t hea; /* initial value of HEA - start of the heap */
int32_t stp; /* initial value of STP - stack top */
int32_t cip; /* initial value of CIP - the instruction pointer */
int32_t publics; /* offset to the "public functions" table */
int32_t natives; /* offset to the "native functions" table */
int32_t libraries; /* offset to the table of libraries */
int32_t pubvars; /* the "public variables" table */
int32_t tags; /* the "public tagnames" table */
} AMX_HEADER;
#define AMX_MAGIC 0xf1e0
enum {
AMX_ERR_NONE,
/* reserve the first 15 error codes for exit codes of the abstract machine */
AMX_ERR_EXIT, /* forced exit */
AMX_ERR_ASSERT, /* assertion failed */
AMX_ERR_STACKERR, /* stack/heap collision */
AMX_ERR_BOUNDS, /* index out of bounds */
AMX_ERR_MEMACCESS, /* invalid memory access */
AMX_ERR_INVINSTR, /* invalid instruction */
AMX_ERR_STACKLOW, /* stack underflow */
AMX_ERR_HEAPLOW, /* heap underflow */
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
AMX_ERR_NATIVE, /* native function failed */
AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
AMX_ERR_NOTFOUND, /* function not found */
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
AMX_ERR_DEBUG, /* debugger cannot run */
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
AMX_ERR_PARAMS, /* parameter error */
};
enum {
DBG_INIT, /* query/initialize */
DBG_FILE, /* file number in curfile, filename in name */
DBG_LINE, /* line number in curline, file number in curfile */
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
DBG_CALL, /* function call, address jumped to in dbgaddr */
DBG_RETURN, /* function returns */
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
};
#define AMX_FLAG_CHAR16 0x01 /* characters are 16-bit */
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */
#define AMX_FLAG_BROWSE 0x4000
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
#define AMX_EXEC_MAIN -1 /* start at program entry point */
#define AMX_EXEC_CONT -2 /* continue from last address */
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
uint16_t * AMXAPI amx_Align16(uint16_t *v);
uint32_t * AMXAPI amx_Align32(uint32_t *v);
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
int AMXAPI amx_FindPublic(AMX *amx, char *funcname, int *index);
int AMXAPI amx_FindPubVar(AMX *amx, char *varname, cell *amx_addr);
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
int AMXAPI amx_GetString(char *dest,cell *source);
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
int AMXAPI amx_Init(AMX *amx, void *program);
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
int AMXAPI amx_NameLength(AMX *amx, int *length);
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(char *name,AMX_NATIVE func);
int AMXAPI amx_NumPublics(AMX *amx, int *number);
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
int AMXAPI amx_NumTags(AMX *amx, int *number);
int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
int AMXAPI amx_SetString(cell *dest, char *source, int pack);
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
int AMXAPI amx_StrLen(cell *cstring, int *length);
#if !defined AMX_NO_ALIGN
#if defined __linux__
#pragma pack() /* reset default packing */
#else
#pragma pack(pop) /* reset previous packing */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* __AMX_H */

11
amxmodx/amx_mm.def Executable file
View File

@ -0,0 +1,11 @@
; /usr/local/cross-tools/bin/i386-mingw32msvc-dlltool --base-file /tmp/cc4kB6s0.base --output-exp amx_mm.exp --dllname amx_mm.dll --output-def amx_mm.def --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def /tmp/ccyI7I7K.def
EXPORTS
GetEngineFunctions @ 1 ;
GetEngineFunctions_Post @ 2 ;
GetEntityAPI2 @ 3 ;
GetEntityAPI2_Post @ 4 ;
GiveFnptrsToDll = GiveFnptrsToDll@8 @ 5 ;
GiveFnptrsToDll@8 @ 6 ;
Meta_Attach @ 7 ;
Meta_Detach @ 8 ;
Meta_Query @ 9 ;

548
amxmodx/amxcore.c Executable file
View File

@ -0,0 +1,548 @@
/* Core module for the Small AMX
*
* Copyright (c) ITB CompuPhase, 1997-2002
* This file may be freely used. No warranties of any kind.
*
* Version: $Id$
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include "amx.h"
#define NOPROPLIST
/* A few compilers do not provide the ANSI C standard "time" functions */
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
#include <time.h>
#endif
#define CHARBITS (8*sizeof(char))
typedef unsigned char uchar;
#if !defined NOPROPLIST
typedef struct _property_list {
struct _property_list *next;
cell id;
char *name;
cell value;
} proplist;
static proplist proproot = { NULL };
static proplist *list_additem(proplist *root)
{
proplist *item;
assert(root!=NULL);
if ((item=(proplist *)malloc(sizeof(proplist)))==NULL)
return NULL;
item->name=NULL;
item->id=0;
item->value=0;
item->next=root->next;
root->next=item;
return item;
}
static void list_delete(proplist *pred,proplist *item)
{
assert(pred!=NULL);
assert(item!=NULL);
pred->next=item->next;
assert(item->name!=NULL);
free(item->name);
free(item);
}
static void list_setitem(proplist *item,cell id,char *name,cell value)
{
char *ptr;
assert(item!=NULL);
if ((ptr=(char *)malloc(strlen(name)+1))==NULL)
return;
if (item->name!=NULL)
free(item->name);
strcpy(ptr,name);
item->name=ptr;
item->id=id;
item->value=value;
}
static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
proplist **pred)
{
proplist *item=root->next;
proplist *prev=root;
/* check whether to find by name or by value */
assert(name!=NULL);
if (strlen(name)>0) {
/* find by name */
while (item!=NULL && (item->id!=id || stricmp(item->name,name)!=0)) {
prev=item;
item=item->next;
} /* while */
} else {
/* find by value */
while (item!=NULL && (item->id!=id || item->value!=value)) {
prev=item;
item=item->next;
} /* while */
} /* if */
if (pred!=NULL)
*pred=prev;
return item;
}
#endif
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell bytes;
hdr=(AMX_HEADER *)amx->base;
data=amx->base+(int)hdr->dat;
/* the number of bytes is on the stack, at "frm + 2*cell" */
bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
/* the number of arguments is the number of bytes divided
* by the size of a cell */
return bytes/sizeof(cell);
}
static cell AMX_NATIVE_CALL getarg(AMX *amx, cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell value;
hdr=(AMX_HEADER *)amx->base;
data=amx->base+(int)hdr->dat;
/* get the base value */
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
/* adjust the address in "value" in case of an array access */
value+=params[2]*sizeof(cell);
/* get the value indirectly */
value= * (cell *)(data+(int)value);
return value;
}
static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
{
AMX_HEADER *hdr;
uchar *data;
cell value;
hdr=(AMX_HEADER *)amx->base;
data=amx->base+(int)hdr->dat;
/* get the base value */
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
/* adjust the address in "value" in case of an array access */
value+=params[2]*sizeof(cell);
/* verify the address */
if (value<0 || value>=amx->hea && value<amx->stk)
return 0;
/* set the value indirectly */
* (cell *)(data+(int)value) = params[3];
return 1;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
{
return amx->stk - amx->hea;
}
static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
{
char name[64];
cell *cstr;
int index,err,len;
amx_GetAddr(amx,params[1],&cstr);
/* verify string length */
amx_StrLen(cstr,&len);
if (len>=64) {
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
} /* if */
amx_GetString(name,cstr);
err=amx_FindPublic(amx,name,&index);
if (err!=AMX_ERR_NONE)
index=-1; /* this is not considered a fatal error */
return index;
}
int amx_StrPack(cell *dest,cell *source)
{
int len;
amx_StrLen(source,&len);
if ((ucell)*source>UCHAR_MAX) {
/* source string is already packed */
while (len >= 0) {
*dest++ = *source++;
len-=sizeof(cell);
} /* while */
} else {
/* pack string, from bottom up */
cell c;
int i;
for (c=0,i=0; i<len; i++) {
assert((*source & ~0xffL)==0);
c=(c<<CHARBITS) | *source++;
if (i%sizeof(cell) == sizeof(cell)-1) {
*dest++=c;
c=0;
} /* if */
} /* for */
if (i%sizeof(cell) != 0) /* store remaining packed characters */
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
else
*dest=0; /* store full cell of zeros */
} /* if */
return AMX_ERR_NONE;
}
int amx_StrUnpack(cell *dest,cell *source)
{
if ((ucell)*source>UCHAR_MAX) {
/* unpack string, from top down (so string can be unpacked in place) */
cell c;
int i,len;
amx_StrLen(source,&len);
dest[len]=0;
for (i=len-1; i>=0; i--) {
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
dest[i]=c & UCHAR_MAX;
} /* for */
} else {
/* source string is already unpacked */
while ((*dest++ = *source++) != 0)
/* nothing */;
} /* if */
return AMX_ERR_NONE;
}
static int verify_addr(AMX *amx,cell addr)
{
int err;
cell *cdest;
err=amx_GetAddr(amx,addr,&cdest);
if (err!=AMX_ERR_NONE)
amx_RaiseError(amx,err);
return err;
}
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
{
cell *cptr;
int len = 0;
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
amx_StrLen(cptr,&len);
return len;
}
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
{
cell *cdest,*csrc;
int len,needed,lastaddr,err;
/* calculate number of cells needed for (packed) destination */
amx_GetAddr(amx,params[2],&csrc);
amx_StrLen(csrc,&len);
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
assert(needed>0);
lastaddr=params[1]+sizeof(cell)*needed-1;
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
return 0;
amx_GetAddr(amx,params[1],&cdest);
err=amx_StrPack(cdest,csrc);
if (err!=AMX_ERR_NONE)
return amx_RaiseError(amx,err);
return len;
}
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
{
cell *cdest,*csrc;
int len,err,lastaddr;
/* calculate number of cells needed for (packed) destination */
amx_GetAddr(amx,params[2],&csrc);
amx_StrLen(csrc,&len);
assert(len>=0);
lastaddr=params[1]+sizeof(cell)*(len+1)-1;
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
return 0;
amx_GetAddr(amx,params[1],&cdest);
err=amx_StrUnpack(cdest,csrc);
if (err!=AMX_ERR_NONE)
return amx_RaiseError(amx,err);
return len;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
{
union {
cell c;
#if defined BIT16
uchar b[2];
#else
uchar b[4];
#endif
} value;
uchar t;
assert((size_t)params[0]==sizeof(cell));
value.c = params[1];
#if defined BIT16
t = value.b[0];
value.b[0] = value.b[1];
value.b[1] = t;
#else
t = value.b[0];
value.b[0] = value.b[3];
value.b[3] = t;
t = value.b[1];
value.b[1] = value.b[2];
value.b[2] = t;
#endif
return value.c;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
{
assert((size_t)params[0]==sizeof(cell));
return tolower((int)params[1]);
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
{
assert((size_t)params[0]==sizeof(cell));
return toupper((int)params[1]);
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
{
return params[1] <= params[2] ? params[1] : params[2];
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
{
return params[1] >= params[2] ? params[1] : params[2];
}
static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
{
cell value = params[1];
if (params[2] > params[3]) /* minimum value > maximum value ! */
amx_RaiseError(amx,AMX_ERR_NATIVE);
if (value < params[2])
value = params[2];
else if (value > params[3])
value = params[3];
return value;
}
#if !defined NOPROPLIST
static char *MakePackedString(cell *cptr)
{
int len;
char *dest;
amx_StrLen(cptr,&len);
dest=(char *)malloc(len+sizeof(cell));
amx_GetString(dest,cptr);
return dest;
}
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
{
cell *cstr;
char *name;
proplist *item;
amx_GetAddr(amx,params[2],&cstr);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
/* if list_finditem() found the value, store the name */
if (item!=NULL && item->value==params[3] && strlen(name)==0) {
int needed=(strlen(item->name)+sizeof(cell)-1)/sizeof(cell); /* # of cells needed */
if (verify_addr(amx,(cell)(params[4]+needed))!=AMX_ERR_NONE) {
free(name);
return 0;
} /* if */
amx_GetAddr(amx,params[4],&cstr);
amx_SetString(cstr,item->name,1);
} /* if */
free(name);
return (item!=NULL) ? item->value : 0;
}
static cell AMX_NATIVE_CALL setproperty(AMX *amx,cell *params)
{
cell prev=0;
cell *cstr;
char *name;
proplist *item;
amx_GetAddr(amx,params[2],&cstr);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
if (item==NULL)
item=list_additem(&proproot);
if (item==NULL) {
amx_RaiseError(amx,AMX_ERR_MEMORY);
} else {
prev=item->value;
if (strlen(name)==0) {
free(name);
amx_GetAddr(amx,params[4],&cstr);
name=MakePackedString(cstr);
} /* if */
list_setitem(item,params[1],name,params[3]);
} /* if */
free(name);
return prev;
}
static cell AMX_NATIVE_CALL delproperty(AMX *amx,cell *params)
{
cell prev=0;
cell *cstr;
char *name;
proplist *item,*pred;
amx_GetAddr(amx,params[2],&cstr);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],&pred);
if (item!=NULL) {
prev=item->value;
list_delete(pred,item);
} /* if */
free(name);
return prev;
}
static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
{
cell *cstr;
char *name;
proplist *item;
amx_GetAddr(amx,params[2],&cstr);
name=MakePackedString(cstr);
item=list_finditem(&proproot,params[1],name,params[3],NULL);
free(name);
return (item!=NULL);
}
#endif
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
* generator" that has been extended to 31-bits (the standard C version returns
* only 15-bits).
*/
static unsigned long IL_StandardRandom_seed = 0L;
#define IL_RMULT 1103515245L
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
{
unsigned long lo, hi, ll, lh, hh, hl;
unsigned long result;
/* one-time initialization (or, mostly one-time) */
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
if (IL_StandardRandom_seed == 0L)
IL_StandardRandom_seed=(unsigned long)time(NULL);
#endif
lo = IL_StandardRandom_seed & 0xffff;
hi = IL_StandardRandom_seed >> 16;
IL_StandardRandom_seed = IL_StandardRandom_seed * IL_RMULT + 12345;
ll = lo * (IL_RMULT & 0xffff);
lh = lo * (IL_RMULT >> 16 );
hl = hi * (IL_RMULT & 0xffff);
hh = hi * (IL_RMULT >> 16 );
result = ((ll + 12345) >> 16) + lh + hl + (hh << 16);
result &= ~LONG_MIN; /* remove sign bit */
if (params[1]!=0)
result %= params[1];
return (cell)result;
}
#if 0
void core_Init(void)
{
/* reduced to a do-nothing routine */
}
void core_Exit(void)
{
#if !defined NOPROPLIST
while (proproot.next!=NULL)
list_delete(&proproot,proproot.next);
#endif
}
#endif
AMX_NATIVE_INFO core_Natives[] = {
{ "numargs", numargs },
{ "getarg", getarg },
{ "setarg", setarg },
{ "heapspace", heapspace },
{ "funcidx", funcidx },
{ "strlen", core_strlen },
{ "strpack", strpack },
{ "strunpack", strunpack },
{ "swapchars", swapchars },
{ "tolower", core_tolower },
{ "toupper", core_toupper },
{ "random", core_random },
{ "min", core_min },
{ "max", core_max },
{ "clamp", core_clamp },
#if !defined NOPROPLIST
{ "getproperty", getproperty },
{ "setproperty", setproperty },
{ "deleteproperty",delproperty },
{ "existproperty", existproperty },
#endif
{ NULL, NULL } /* terminator */
};

2202
amxmodx/amxmod.cpp Executable file

File diff suppressed because it is too large Load Diff

237
amxmodx/amxmod.h Executable file
View File

@ -0,0 +1,237 @@
/*
* 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.
*
*/
#ifndef AMXMOD_H
#define AMXMOD_H
#include "modules.h"
#include "CString.h"
#include "CList.h"
#include "CPlugin.h"
#include "CMisc.h"
#include "CVault.h"
#include "CModule.h"
#include "CTask.h"
#include "CLogEvent.h"
#include "CForward.h"
#include "CCmd.h"
#include "CMenu.h"
#include "CEvent.h"
#define AMX_VERSION "0.9.7"
#ifdef __cplusplus
extern "C" {
#endif
extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[];
extern AMX_NATIVE_INFO power_Natives[];
#ifdef __cplusplus
}
#endif
extern AMX_NATIVE_INFO amxmod_Natives[];
extern AMX_NATIVE_INFO file_Natives[];
extern AMX_NATIVE_INFO float_Natives[];
extern AMX_NATIVE_INFO string_Natives[];
extern AMX_NATIVE_INFO vault_Natives[];
#ifndef __linux__
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path);
#define DLPROC(m,func) GetProcAddress(m,func);
#define DLFREE(m) FreeLibrary(m);
#else
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW);
#define DLPROC(m,func) dlsym(m,func);
#define DLFREE(m) dlclose(m);
#endif
#ifndef __linux__
typedef HINSTANCE DLHANDLE;
#else
typedef void* DLHANDLE;
#endif
#ifndef GETPLAYERAUTHID
#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId)
#endif
#define ANGLEVECTORS (*g_engfuncs.pfnAngleVectors)
#define CLIENT_PRINT (*g_engfuncs.pfnClientPrintf)
#define CVAR_DIRECTSET (*g_engfuncs.pfnCvar_DirectSet)
#define GETCLIENTLISTENING (*g_engfuncs.pfnVoice_GetClientListening)
#define RUNPLAYERMOVE (*g_engfuncs.pfnRunPlayerMove)
#define SETCLIENTLISTENING (*g_engfuncs.pfnVoice_SetClientListening)
#define SETCLIENTMAXSPEED (*g_engfuncs.pfnSetClientMaxspeed)
char* UTIL_SplitHudMessage(register const char *src);
int UTIL_ReadFlags(const char* c);
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg );
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL);
void UTIL_GetFlags(char* flags,int flag);
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
void UTIL_IntToString(int value, char *output);
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name);
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen );
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t ))])
#define GET_PLAYER_POINTER_I(i) (&g_players[i])
struct WeaponsVault {
String fullName;
short int iId;
short int ammoSlot;
};
struct fakecmd_t {
char args[256];
const char *argv[3];
//char argv[3][128];
int argc;
bool fake;
};
extern CPluginMngr g_plugins;
extern CTaskMngr g_tasksMngr;
extern CPlayer g_players[33];
extern CPlayer* mPlayer;
extern CmdMngr g_commands;
extern CList<CCVar> g_cvars;
extern CList<ForceObject> g_forcemodels;
extern CList<ForceObject> g_forcesounds;
extern CList<ForceObject> g_forcegeneric;
extern CList<CModule> g_modules;
extern CList<CPlayer*> g_auth;
extern EventsMngr g_events;
extern Grenades g_grenades;
extern LogEventsMngr g_logevents;
extern MenuMngr g_menucmds;
extern String g_log_dir;
extern String g_mod_name;
extern TeamIds g_teamsIds;
extern Vault g_vault;
extern CForwardMngr g_forwards;
extern WeaponsVault g_weaponsData[MAX_WEAPONS];
extern XVars g_xvars;
extern bool g_bmod_cstrike;
extern bool g_bmod_dod;
extern bool g_dontprecache;
extern bool g_initialized;
extern int g_srvindex;
extern cvar_t* amx_version;
extern cvar_t* hostname;
extern cvar_t* mp_timelimit;
extern fakecmd_t g_fakecmd;
extern float g_game_restarting;
extern float g_game_timeleft;
extern float g_task_time;
extern float g_auth_time;
extern hudtextparms_t g_hudset;
//extern int g_edict_point;
extern int g_players_num;
extern int mPlayerIndex;
extern int mState;
extern void (*endfunction)(void*);
extern void (*function)(void*);
typedef void (*funEventCall)(void*);
extern funEventCall modMsgsEnd[MAX_REG_MSGS];
extern funEventCall modMsgs[MAX_REG_MSGS];
extern int gmsgAmmoPickup;
extern int gmsgAmmoX;
extern int gmsgBattery;
extern int gmsgCurWeapon;
extern int gmsgDamage;
extern int gmsgDeathMsg;
extern int gmsgHealth;
extern int gmsgMOTD;
extern int gmsgScoreInfo;
extern int gmsgSendAudio;
extern int gmsgServerName;
extern int gmsgShowMenu;
extern int gmsgTeamInfo;
extern int gmsgTextMsg;
extern int gmsgVGUIMenu;
extern int gmsgWeapPickup;
extern int gmsgWeaponList;
extern int gmsgintermission;
extern int gmsgResetHUD;
extern int gmsgRoundTime;
void Client_AmmoPickup(void*);
void Client_AmmoX(void*);
void Client_CurWeapon(void*);
void Client_ScoreInfo(void*);
void Client_ShowMenu(void*);
void Client_TeamInfo(void*);
void Client_TextMsg(void*);
void Client_VGUIMenu(void*);
void Client_WeaponList(void*);
void Client_DamageEnd(void*);
void Client_DeathMsg(void*);
void amx_command();
void plugin_srvcmd();
const char* stristr(const char* a,const char* b);
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
int loadModules(const char* filename);
void dettachModules();
void dettachReloadModules();
void attachModules();
void attachMetaModModules( const char* filename );
void dettachMetaModModules( const char* filename );
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
cell* get_amxaddr(AMX *amx,cell amx_addr);
char* build_pathname(char *fmt, ... );
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
AMX* get_amxscript(int, void**,const char**);
const char* get_amxscriptname(AMX* amx);
char* get_amxstring(AMX *amx,cell amx_addr,int id,int& len);
int amxstring_len(cell* cstr);
int load_amxscript(AMX* amx, void** program, const char* path, char error[64]);
int set_amxnatives(AMX* amx,char error[64]);
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max);
int unload_amxscript(AMX* amx,void** program);
void copy_amxmemory(cell* dest,cell* src,int len);
void get_modname(char*);
void print_srvconsole( char *fmt, ... );
void report_error( int code, char* fmt, ... );
void* alloc_amxmemory(void**, int size);
void free_amxmemory(void **ptr);
#endif // AMXMOD_H

104
amxmodx/amxtime.c Executable file
View File

@ -0,0 +1,104 @@
/* Date/time module for the Small AMX
*
* Copyright (c) ITB CompuPhase, 2001-2002
* This file may be freely used. No warranties of any kind.
*
* Version: $Id$
*/
#include <time.h>
#include <assert.h>
#if defined __WIN32__ || defined _WIN32
#include <windows.h>
#include <mmsystem.h>
#endif
#include "amx.h"
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
{
time_t sec1970;
struct tm gtm;
cell *cptr;
assert(params[0]==3*sizeof(cell));
time(&sec1970);
/* on DOS/Windows, the timezone is usually not set for the C run-time
* library; in that case gmtime() and localtime() return the same value
*/
gtm=*localtime(&sec1970);
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_hour;
if (amx_GetAddr(amx,params[2],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_min;
if (amx_GetAddr(amx,params[3],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_sec;
/* the time() function returns the number of seconds since January 1 1970
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
*/
return sec1970;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL _date(AMX *amx, cell *params)
{
time_t sec1970;
struct tm gtm;
cell *cptr;
assert(params[0]==3*sizeof(cell));
time(&sec1970);
gtm=*localtime(&sec1970);
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_year+1900;
if (amx_GetAddr(amx,params[2],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_mon+1;
if (amx_GetAddr(amx,params[3],&cptr)==AMX_ERR_NONE)
*cptr=gtm.tm_mday;
return 0;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL _tickcount(AMX *amx, cell *params)
{
// #if defined __WIN32__ || defined _WIN32
// static int timerset = 0;
// #endif
cell value;
assert(params[0]==sizeof(cell));
//#if defined __WIN32__ || defined _WIN32
// if (!timerset) {
// timeBeginPeriod(1); /* timeGetTime() is more accurate on WindowsNT
// * if timeBeginPeriod(1) is set */
// timerset=1;
// } /* if */
// value=timeGetTime(); /* this value is already in milliseconds */
// #else
value=(cell)clock();
/* convert to milliseconds */
value=(cell)((1000L * (value+CLK_TCK/2)) / CLK_TCK);
//#endif
return value;
}
AMX_NATIVE_INFO time_Natives[] = {
{ "time", _time },
{ "date", _date },
{ "tickcount", _tickcount },
{ NULL, NULL } /* terminator */
};

328
amxmodx/emsg.cpp Executable file
View File

@ -0,0 +1,328 @@
/*
* 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"
int gmsgAmmoPickup;
int gmsgAmmoX;
int gmsgBattery;
int gmsgCurWeapon;
int gmsgDamage;
int gmsgDeathMsg;
int gmsgHealth;
int gmsgMOTD;
int gmsgScoreInfo;
int gmsgSendAudio;
int gmsgServerName;
int gmsgShowMenu;
int gmsgTeamInfo;
int gmsgTextMsg;
int gmsgVGUIMenu;
int gmsgWeapPickup;
int gmsgWeaponList;
int gmsgintermission;
int gmsgResetHUD;
int gmsgRoundTime;
TeamIds g_teamsIds;
WeaponsVault g_weaponsData[MAX_WEAPONS];
void Client_VGUIMenu(void* mValue)
{
if (!mPlayer) return;
switch (mState++){
case 0:
mPlayer->menu = -(*(int*)mValue);
break;
case 1:
mPlayer->keys = *(int*)mValue;
}
}
void Client_ShowMenu(void* mValue)
{
if (!mPlayer) return;
switch (mState++){
case 0:
mPlayer->keys = *(int*)mValue;
break;
case 3:
mPlayer->menu = g_menucmds.findMenuId( (char*)mValue );
}
}
void Client_TeamInfo(void* mValue)
{
if (mPlayer) return;
static int index;
switch (mState++) {
case 0:
index = *(int*)mValue;
break;
case 1:
if ( index < 1 || index > gpGlobals->maxClients ) break;
char* msg = (char*)mValue;
g_players[ index ].team.set( msg );
g_teamsIds.registerTeam( msg , -1 );
}
}
void Client_TextMsg(void* mValue)
{
if ( mPlayer ) return;
switch (mState++) {
case 1:{
char * msg = (char*)mValue;
if (!msg) break;
if ( !strncmp("#Game_C", msg , 7) ) {
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
// g_endround_time = gpGlobals->time;
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
}
else if (!strncmp("#Game_w", msg , 7) ) {
g_game_timeleft = -2;
}
else if ( !strncmp("#game_clan_s", msg , 12) ){
g_game_timeleft = -3;
}
break;
}
case 2:{
char * msg = (char*)mValue;
if (!msg) break;
if (g_game_timeleft == -2 ){
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
}
else if ( g_game_timeleft == -3 )
g_game_restarting = atoi( msg ) * 60;
break;
}
case 3:{
char * msg = (char*)mValue;
if (!msg) break;
if ( g_game_timeleft != -3 ) break;
g_game_restarting += atoi( msg );
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
break;
}
}
}
void Client_WeaponList(void* mValue)
{
static int wpnList = 0;
//static int wpnList2;
static int iSlot;
static const char* wpnName;
switch (mState++) {
case 0:
wpnName = (char*)mValue;
break;
case 1:
iSlot = *(int*)mValue;
break;
case 7:
int iId = *(int*)mValue;
/*int* blocker;
int iwpn = iId;
if (iId > 31) {
iwpn -= 31;
blocker = &wpnList2;
}
else
blocker = &wpnList;*/
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
break;
wpnList |= (1<<iId);
g_weaponsData[iId].iId = iId;
g_weaponsData[iId].ammoSlot = iSlot;
g_weaponsData[iId].fullName.set(wpnName);
}
}
void Client_CurWeapon(void* mValue)
{
static int iState;
static int iId;
switch (mState++){
case 0:
iState = *(int*)mValue;
break;
case 1:
if (!iState) break;
iId = *(int*)mValue;
break;
case 2:
if (!mPlayer) return;
if (!iState || (iId < 1 || iId >= MAX_WEAPONS ) ) break;
mPlayer->weapons[iId].clip = *(int*)mValue;
mPlayer->current = iId;
mPlayer->lastHit = mPlayer->lastTrace;
}
}
void Client_AmmoX(void* mValue)
{
static int iAmmo;
switch (mState++){
case 0:
iAmmo = *(int*)mValue;
break;
case 1:
if (!mPlayer) return;
for(int i=1;i<MAX_WEAPONS;++i)
if (iAmmo == g_weaponsData[i].ammoSlot)
mPlayer->weapons[i].ammo = *(int*)mValue;
}
}
void Client_AmmoPickup(void* mValue)
{
static int iSlot;
switch (mState++){
case 0:
iSlot = *(int*)mValue;
break;
case 1:
if (!mPlayer) return;
for(int i=1;i<MAX_WEAPONS;++i)
if (g_weaponsData[i].ammoSlot==iSlot)
mPlayer->weapons[i].ammo += *(int*)mValue;
}
}
void Client_ScoreInfo(void* mValue)
{
static int index;
static int deaths;
switch (mState++){
case 0:
index = *(int*)mValue;
break;
case 2:
deaths = *(int*)mValue;
break;
case 4:
if ( index < 1 || index > gpGlobals->maxClients ) break;
CPlayer*pPlayer = GET_PLAYER_POINTER_I( index );
pPlayer->deaths = deaths;
pPlayer->teamId = *(int*)mValue;
if ( g_teamsIds.isNewTeam() )
g_teamsIds.registerTeam( pPlayer->team.str() , pPlayer->teamId );
}
}
void Client_DamageEnd(void* mValue)
{
CPlayer* dead = mPlayer;
if ( dead && dead->death_killer )
{
g_events.parserInit( CS_DEATHMSG , &gpGlobals->time , mPlayer = 0, mPlayerIndex = 0 );
g_events.parseValue( dead->death_killer );
g_events.parseValue( dead->index );
g_events.parseValue( dead->death_headshot );
g_events.parseValue( dead->death_weapon.str() );
g_events.parseValue( dead->death_tk ? 1 : 0 );
g_events.executeEvents();
dead->death_killer = 0;
}
}
void Client_DeathMsg(void* mValue)
{
static CPlayer *killer;
static CPlayer *victim;
static int killer_id;
static int victim_id;
static int hs;
switch (mState++){
case 0:
killer_id = *(int*)mValue;
killer = (killer_id > 0 && killer_id < 33) ?
GET_PLAYER_POINTER_I(killer_id) : 0;
break;
case 1:
victim_id = *(int*)mValue;
victim = (victim_id > 0 && victim_id < 33) ?
GET_PLAYER_POINTER_I(victim_id) : 0;
break;
case 2:
hs = *(int*)mValue;
break;
case 3:
if ( !killer || !victim ) break;
victim->death_killer = killer_id;
victim->death_weapon.set((char*)mValue);
victim->death_headshot = hs;
victim->death_tk = (killer->teamId == victim->teamId);
}
}
/*
void Client_SendAudio(void* mValue)
{
}
void Client_SendAudioEnd(void* mValue)
{
}
void Client_RoundTimeEnd(void* mValue)
{
}
void Client_RoundTime(void* mValue)
{
}
void Client_ResetHUD(void* mValue)
{
}
*/

246
amxmodx/file.cpp Executable file
View File

@ -0,0 +1,246 @@
/*
* 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"
// header file for unlink()
#ifdef __linux__
#include <unistd.h>
#else
#include <io.h>
#endif
#ifdef __GNUC__
//#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#endif
static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
{
#ifdef __GNUC__
int a;
struct dirent *ep;
DIR *dp;
char* dirname = build_pathname("%s",get_amxstring(amx,params[1],0,a) );
a = params[2];
if ( (dp = opendir (dirname)) == NULL )
return 0;
seekdir( dp , a );
if ( (ep = readdir (dp)) != NULL ) {
cell *length = get_amxaddr(amx,params[5]);
*length = set_amxstring(amx,params[3], ep->d_name ,params[4]);
a = telldir( dp );
}
else
a = 0;
closedir (dp);
return a;
#else
return 0;
#endif
}
static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
{
int iLen;
char* szFile = get_amxstring(amx,params[1],0,iLen);
FILE*fp;
if ( (fp =fopen(build_pathname("%s",szFile),"r")) == NULL) {
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
char buffor[1024];
int i = 0, iLine = params[2];
while((i <= iLine) && fgets(buffor,1023,fp) )
i++;
fclose(fp);
if (i > iLine){
int len = strlen(buffor);
if (buffor[len-1]=='\n')
buffor[--len]=0;
if (buffor[len-1]=='\r')
buffor[--len]=0;
cell *length = get_amxaddr(amx,params[5]);
*length = set_amxstring(amx,params[3],buffor,params[4]);
return i;
}
return 0;
}
static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
{
int i;
char* sFile = build_pathname("%s", get_amxstring(amx,params[1],0,i) );
char* sText = get_amxstring(amx,params[2],0,i);
FILE* pFile;
int iLine = params[3];
// apending to the end
if (iLine < 0) {
if ( (pFile = fopen( sFile ,"a")) == NULL ){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
fputs( sText , pFile );
fputc( '\n', pFile );
fclose( pFile );
return 1;
}
// creating a new file with a line in a middle
if ( (pFile = fopen(sFile,"r")) == NULL ) {
if ( (pFile = fopen(sFile,"w")) == NULL ){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
for(i=0;i < iLine;++i)
fputc('\n',pFile);
fputs( sText , pFile );
fputc( '\n', pFile );
fclose(pFile);
return 1;
}
// adding a new line in a middle of already existing file
FILE* pTemp;
char buffor[1024];
if ( (pTemp = tmpfile()) == NULL ){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
for(i=0;;++i){
if ( i == iLine ){
fgets(buffor,1023,pFile);
fputs( sText , pTemp );
fputc( '\n', pTemp );
}
else if ( fgets(buffor,1023,pFile) ){
fputs(buffor , pTemp );
}
else if ( i < iLine ) {
fputc( '\n', pTemp );
}
else break;
}
fclose(pFile);
rewind(pTemp);
// now rewrite because file can be now smaller...
if ( (pFile = fopen(sFile,"w")) == NULL ){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
while(fgets(buffor,1023,pTemp))
fputs(buffor,pFile );
fclose(pTemp);
fclose(pFile);
return 1;
}
static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */
{
int iLen;
char* sFile = get_amxstring(amx,params[1],0,iLen);
return (unlink( build_pathname("%s",sFile) )?0:1);
}
static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
{
int iLen;
char* sFile = get_amxstring(amx,params[1],0,iLen);
FILE* fp = fopen(build_pathname("%s",sFile),"r");
if ( fp != NULL) {
fclose(fp);
return 1;
}
return 0;
}
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
{
int iLen;
char* sFile = get_amxstring(amx,params[1],0,iLen);
FILE* fp = fopen(build_pathname("%s",sFile),"r");
if ( fp != NULL) {
if ( params[0] < 2 || params[2] == 0 ){
fseek(fp,0,SEEK_END);
int size = ftell(fp);
fclose(fp);
return size;
}
else if ( params[2] == 1 ){
int a = 0,lines = 0;
while( a != EOF ){
++lines;
while ( (a = fgetc(fp)) != '\n' && a != EOF )
;
}
//int a, b = '\n';
//while( (a = fgetc(fp)) != EOF ){
// if ( a == '\n')
// ++lines;
// b = a;
//}
//if ( b != '\n' )
// ++lines;
return lines;
}
else if ( params[2] == 2 ){
fseek(fp,-1,SEEK_END);
if ( fgetc(fp) == '\n' )
return 1;
return 0;
}
}
return -1;
}
AMX_NATIVE_INFO file_Natives[] = {
{ "delete_file", delete_file },
{ "file_exists", file_exists },
{ "file_size", file_size },
{ "read_dir", read_dir },
{ "read_file", read_file },
{ "write_file", write_file },
{ NULL, NULL }
};

96
amxmodx/float.cpp Executable file
View File

@ -0,0 +1,96 @@
/* Float arithmetic for the Small AMX engine
*
* Copyright (c) Artran, Inc. 1999
* Written by Greg Garner (gmg@artran.com)
* This file may be freely used. No warranties of any kind.
*
*/
#include <math.h>
#include <stdlib.h>
#include <extdll.h>
#include <meta_api.h>
#include "amxmod.h"
inline cell FloatToCell(float fValue) {
return *(cell *)((void *)&fValue);
}
inline float CellToFloat(cell cellValue){
return *(float *)((void *)&cellValue);
}
static cell _float(AMX *,cell *params){
return FloatToCell((float)params[1]);
}
static cell _floatstr(AMX *amx,cell *params){
int len;
return FloatToCell((float)atof(get_amxstring(amx,params[1],0,len)));
}
static cell _floatmul(AMX *,cell *params){
return FloatToCell(CellToFloat(params[1]) * CellToFloat(params[2]));
}
static cell _floatdiv(AMX *,cell *params){
return FloatToCell(CellToFloat(params[1]) / CellToFloat(params[2]));
}
static cell _floatadd(AMX *,cell *params){
return FloatToCell(CellToFloat(params[1]) + CellToFloat(params[2]));
}
static cell _floatsub(AMX *,cell *params){
return FloatToCell(CellToFloat(params[1]) - CellToFloat(params[2]));
}
static cell _floatfract(AMX *,cell *params){
float fA = CellToFloat(params[1]);
fA -= (float)(floor((double)fA));
return FloatToCell(fA);
}
static cell _floatround(AMX *,cell *params){
float fA = CellToFloat(params[1]);
switch (params[2]) {
case 1:
fA = (float)(floor((double)fA));
break;
case 2:
float fValue;
fValue = (float)(floor((double)fA));
if ( (fA>=0) && ((fA-fValue)!=0) )
fValue++;
fA = fValue;
break;
default:
fA = (float)(floor((double)fA+.5));
break;
}
return (long)fA;
}
static cell _floatcmp(AMX *,cell *params){
float fA = CellToFloat(params[1]);
float fB = CellToFloat(params[2]);
if (fA == fB)
return 0;
else if (fA > fB)
return 1;
else
return -1;
}
AMX_NATIVE_INFO float_Natives[] = {
{ "float", _float },
{ "floatstr", _floatstr },
{ "floatmul", _floatmul },
{ "floatdiv", _floatdiv },
{ "floatadd", _floatadd },
{ "floatsub", _floatsub },
{ "floatfract", _floatfract},
{ "floatround", _floatround},
{ "floatcmp", _floatcmp},
{ NULL, NULL }
};

1096
amxmodx/meta_api.cpp Executable file

File diff suppressed because it is too large Load Diff

526
amxmodx/modules.cpp Executable file
View File

@ -0,0 +1,526 @@
/*
* 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 "osdep.h" // sleep, etc
#include "CFile.h"
CList<CModule> g_modules;
CList<CScript,AMX*> g_loadedscripts;
#ifdef __cplusplus
extern "C" {
#endif
extern const char* no_function; // stupid work around
#ifdef __cplusplus
}
#endif
void report_error( int code, char* fmt, ... )
{
va_list argptr;
char string[256];
*string = 0;
va_start (argptr, fmt);
vsnprintf (string, 255, fmt,argptr);
string[255] = 0;
va_end (argptr);
if ( *string ) {
//File fp( "error_amx.log","a" );
//fp << string;
print_srvconsole( string );
print_srvconsole("[AMX] Make sure that modules are compatible with AMX %s\n" , AMX_VERSION );
print_srvconsole("[AMX] Please fix the problem then start the server again\n" );
}
sleep( 5 );
exit( code );
}
void print_srvconsole( char *fmt, ... )
{
va_list argptr;
char string[256];
va_start (argptr, fmt);
vsnprintf (string, 255, fmt,argptr);
string[255] = 0;
va_end (argptr);
SERVER_PRINT(string);
}
void* alloc_amxmemory(void** p, int size)
{
*p = new unsigned char[ size ];
return *p;
}
void free_amxmemory(void **ptr)
{
delete[] *ptr;
*ptr = 0;
}
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64]){
AMX_HEADER hdr;
int err;
FILE *fp;
memset(amx, 0, sizeof(*amx));
*program = 0;
*error = 0;
if ( (fp = fopen( filename, "rb" )) == NULL)
{
strcpy(error,"Plugin file open error");
return (amx->error = AMX_ERR_NOTFOUND);
}
fread(&hdr, sizeof(hdr), 1, fp);
amx_Align16(&hdr.magic);
if (hdr.magic!=AMX_MAGIC)
{
strcpy(error,"Invalid plugin");
return (amx->error = AMX_ERR_FORMAT);
}
amx_Align32((uint32_t *)&hdr.stp);
amx_Align32((uint32_t *)&hdr.size);
if ( (*program = new unsigned char[ (int)hdr.stp ]) == 0 )
//if ( (*program = malloc( (int)hdr.stp )) == 0 )
{
strcpy(error,"Failed to allocate memory");
return (amx->error = AMX_ERR_MEMORY);
}
rewind(fp);
fread(*program, 1, (size_t)hdr.size, fp);
fclose(fp);
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
{
sprintf(error,"Load error %d (invalid file format or version)", err);
return (amx->error = AMX_ERR_INIT);
}
#ifdef JIT
void *np = new unsigned char[ amx->code_size ];
void *rt = new unsigned char[ amx->reloc_size ];
if ( !np || (!rt && amx->reloc_size > 0) )
{
delete[] np;
delete[] rt;
strcpy(error,"Failed to initialize plugin");
return (amx->error = AMX_ERR_INIT);
}
if (amx_InitJIT(amx, rt, np) == AMX_ERR_NONE)
{
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
amx->base = new unsigned char FAR[ amx->code_size ];
if ( amx->base )
memcpy( amx->base , np , amx->code_size );
delete[] np;
delete[] rt;
delete[] *program;
(*program) = amx->base;
if ( *program == 0 ){
strcpy(error,"Failed to allocate memory");
return (amx->error = AMX_ERR_MEMORY);
}
}
else
{
delete[] np;
delete[] rt;
strcpy(error,"Failed to initialize plugin");
return (amx->error = AMX_ERR_INIT_JIT);
}
#endif
CScript* aa = new CScript(amx,*program,filename);
if ( aa == 0 )
{
strcpy(error,"Failed to allocate memory");
return (amx->error = AMX_ERR_MEMORY);
}
g_loadedscripts.put( aa );
return set_amxnatives(amx,error);
}
int set_amxnatives(AMX* amx,char error[64])
{
for ( CList<CModule>::iterator a = g_modules.begin(); a ; ++a )
{
for( CList<AMX_NATIVE_INFO*>::iterator cc =
(*a).natives.begin(); cc; ++cc )
amx_Register(amx, *cc , -1);
}
amx_Register(amx, string_Natives, -1);
amx_Register(amx, float_Natives, -1);
amx_Register(amx, file_Natives, -1);
amx_Register(amx, amxmod_Natives, -1);
amx_Register(amx, power_Natives, -1);
amx_Register(amx, time_Natives, -1);
amx_Register(amx, vault_Natives, -1);
if ( amx_Register(amx, core_Natives, -1) != AMX_ERR_NONE )
{
sprintf(error,"Function not found (name \"%s\")",no_function);
return (amx->error = AMX_ERR_NATIVE);
}
return AMX_ERR_NONE;
}
int unload_amxscript(AMX* amx, void** program)
{
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
if ( a ) a.remove();
delete[] *program;
//free( *program );
*program = 0;
return AMX_ERR_NONE;
}
AMX* get_amxscript(int id , void** code, const char** filename)
{
CList<CScript,AMX*>::iterator a = g_loadedscripts.begin();
while ( a && id-- )
++a;
if ( a ){
*filename = (*a).getName();
*code = (*a).getCode();
return (*a).getAMX();
}
return 0;
}
const char* get_amxscriptname(AMX* amx)
{
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
return a ? (*a).getName() : "";
}
void get_modname(char* buffer )
{
strcpy( buffer , g_mod_name.str() );
}
char* build_pathname(char *fmt, ... )
{
static char string[256];
int b;
int a = b = snprintf(string , 255 ,
#ifndef __linux__
"%s\\",
#else
"%s/",
#endif
g_mod_name.str());
va_list argptr;
va_start (argptr, fmt);
a += vsnprintf (&string[a], 255 - a , fmt,argptr);
string[ a ] = 0;
va_end (argptr);
char* path = &string[b];
while (*path)
{
#ifndef __linux__
if (*path == '/') *path = '\\';
#else
if (*path == '\\') *path = '/';
#endif
++path;
}
return string;
}
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives)
{
CList<CModule>::iterator a = g_modules.begin();
while ( a )
{
if ( (*a).getInfo() == info )
{
AMX_NATIVE_INFO** aa = new AMX_NATIVE_INFO*(natives);
if ( aa == 0 ) return AMX_ERR_NATIVE;
(*a).natives.put( aa );
return AMX_ERR_NONE;
}
++a;
}
return AMX_ERR_NATIVE;
}
bool validFile(const char* file)
{
const char* a = 0;
while(*file)
if (*file++=='.')
a = file;
#ifndef __linux__
return (a && !strcmp(a,"dll"));
#else
return (a && !strcmp(a,"so"));
#endif
}
int loadModules(const char* filename)
{
File fp( build_pathname("%s",filename), "r" );
if ( !fp )
{
print_srvconsole( "[AMX] Modules list not found (file \"%s\")\n",filename);
return 0;
}
char line[256], moduleName[256];
int loaded = 0;
while ( fp.getline( line , 255 ) )
{
*moduleName = 0;
sscanf(line,"%s",moduleName);
if (!isalnum(*moduleName) || !validFile(moduleName) )
continue;
char* pathname = build_pathname("%s",moduleName);
CList<CModule>::iterator a = g_modules.find( pathname );
if ( a ) continue; // already loaded
CModule* cc = new CModule( pathname );
if ( cc == 0 ) return loaded;
cc->queryModule();
switch( cc->getStatusValue() ) {
case MODULE_BADLOAD:
report_error( 1 , "[AMX] Module is not a valid library (file \"%s\")\n",pathname );
break;
case MODULE_NOINFO:
report_error( 1 ,"[AMX] Couldn't find info. about module (file \"%s\")\n",pathname );
break;
case MODULE_NOQUERY:
report_error( 1 , "[AMX] Couldn't find \"AMX_Query\" (file \"%s\")\n", pathname );
break;
case MODULE_NOATTACH:
report_error( 1 , "[AMX] Couldn't find \"AMX_Attach\" (file \"%s\")\n", pathname );
break;
case MODULE_OLD:
report_error( 1 , "[AMX] Module has a different interface version (file \"%s\")\n",pathname );
break;
default:
++loaded;
}
g_modules.put( cc );
}
return loaded;
}
void dettachModules()
{
CList<CModule>::iterator a = g_modules.begin();
while ( a )
{
(*a).detachModule();
a.remove();
}
}
void dettachReloadModules()
{
CList<CModule>::iterator a = g_modules.begin();
while ( a )
{
if ( (*a).isReloadable() )
{
(*a).detachModule();
a.remove();
continue;
}
++a;
}
}
void attachModules()
{
CList<CModule>::iterator a = g_modules.begin();
while ( a )
{
(*a).attachModule();
++a;
}
}
const char* strip_name( const char* a )
{
const char* ret = a;
while(*a){
if ( *a== '/' || *a=='\\' ){
ret = ++a;
continue;
}
++a;
}
return ret;
}
void dettachMetaModModules( const char* filename )
{
File fp( build_pathname("%s",filename), "r" );
if ( !fp )
{
print_srvconsole( "[AMX] Modules list not found (file \"%s\")\n",filename);
return;
}
char line[256], moduleName[256], cmdline[256];
DLHANDLE module;
while ( fp.getline( line , 255 ) )
{
*moduleName = 0;
sscanf(line,"%s",moduleName);
if (!isalnum(*moduleName) || !validFile(moduleName) )
continue;
char* pathname = build_pathname("%s",moduleName);
module = DLLOAD( pathname ); // link dll
if ( module )
{
int a = (int)DLPROC(module,"Meta_Attach");
if ( a )
{
snprintf(cmdline,255, "meta unload %s\n", strip_name(moduleName) );
cmdline[255] = 0;
SERVER_COMMAND( cmdline );
}
DLFREE(module);
}
}
}
void attachMetaModModules( const char* filename )
{
File fp( build_pathname("%s",filename), "r" );
if ( !fp )
{
print_srvconsole( "[AMX] Modules list not found (file \"%s\")\n",filename);
return;
}
char line[256], moduleName[256], cmdline[256];
DLHANDLE module;
int loaded = 0;
while ( fp.getline( line , 255 ) )
{
*moduleName = 0;
sscanf(line,"%s",moduleName);
if (!isalnum(*moduleName) || !validFile(moduleName) )
continue;
char* pathname = build_pathname("%s",moduleName);
module = DLLOAD( pathname ); // link dll
if ( module )
{
int a = (int)DLPROC(module,"Meta_Attach");
if ( a )
{
snprintf(cmdline,255, "meta load %s\n", moduleName );
cmdline[255] = 0;
SERVER_COMMAND( cmdline );
++loaded;
}
DLFREE(module);
}
}
if ( loaded )
{
SERVER_COMMAND( "restart\n" );
/* must be or modules can cause crash
since they were not initialized with all routines (spawn, server active
players think, etc.) and metamod calls other routines
like nothing has never happened. */
}
}

179
amxmodx/modules.h Executable file
View File

@ -0,0 +1,179 @@
/*
* 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.
*
*/
#ifndef __MODULES_H__
#define __MODULES_H__
#include "amx.h"
#undef DLLEXPORT
#ifndef __linux__
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#define WINAPI
#endif
#undef C_DLLEXPORT
#define C_DLLEXPORT extern "C" DLLEXPORT
#define AMX_INTERFACE_VERSION 6
#define RELOAD_MODULE 0
#define STATIC_MODULE 1
struct module_info_s {
const char* name;
const char* author;
const char* version;
int ivers;
int type;
long int serial;
};
// Small scripting language
struct pfnamx_engine_g {
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
int (*pfnamx_Init)(AMX*, void *); // amx, program
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
};
extern pfnamx_engine_g* g_engAmxFunc;
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
// Modules API
struct pfnmodule_engine_g {
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
char* (*pfnbuild_pathname)(char*, ...); // format, ....
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
void (*pfnget_modname)(char*); // modname
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64]); // amx, code, path, error info
void (*pfnprint_console)(char*, ...); // format, ....
void (*pfnreport_error)(int code, char*, ... );
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
int (*pfnamxstring_length)(cell*); // src
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
void* (*pfnalloc_amxmemory)(void**,int size);
void (*pfnfree_amxmemory)(void**);
};
extern pfnmodule_engine_g* g_engModuleFunc;
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
#endif // __MODULES_H__

6
amxmodx/msvc/amxmod_mm.def Executable file
View File

@ -0,0 +1,6 @@
LIBRARY amx_mm
EXPORTS
GiveFnptrsToDll @1
SECTIONS
.data READ WRITE

288
amxmodx/msvc/amxmod_mm.dsp Executable file
View File

@ -0,0 +1,288 @@
# Microsoft Developer Studio Project File - Name="amxmod_mm" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=amxmod_mm - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "amxmod_mm.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "amxmod_mm.mak" CFG="amxmod_mm - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "amxmod_mm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "amxmod_mm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "amxmod_mm - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "release"
# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\metamod\metamod" /I "..\..\hlsdk\sourcecode\common" /I "..\..\hlsdk\sourcecode\engine" /I "..\..\hlsdk\sourcecode\dlls" /I "..\..\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:".\amxmod_mm.def" /out:"release/amx_mm.dll" /libpath:"..\extra\lib_win32"
# Begin Custom Build
TargetPath=.\release\amx_mm.dll
TargetName=amx_mm
InputPath=.\release\amx_mm.dll
SOURCE="$(InputPath)"
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
# End Custom Build
!ELSEIF "$(CFG)" == "amxmod_mm - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "debug"
# PROP Intermediate_Dir "debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Zp4 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\metamod\metamod" /I "..\...\hlsdk\sourcecode\common" /I "..\...\hlsdk\sourcecode\engine" /I "..\...\hlsdk\sourcecode\dlls" /I "..\...\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\amxmod_mm.def" /out:"debug/amx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
# SUBTRACT LINK32 /incremental:no /nodefaultlib
# Begin Custom Build
TargetPath=.\debug\amx_mm.dll
TargetName=amx_mm
InputPath=.\debug\amx_mm.dll
SOURCE="$(InputPath)"
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
# End Custom Build
!ENDIF
# Begin Target
# Name "amxmod_mm - Win32 Release"
# Name "amxmod_mm - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\amx.c
# End Source File
# Begin Source File
SOURCE=..\amxcore.c
# End Source File
# Begin Source File
SOURCE=..\amxmod.cpp
# End Source File
# Begin Source File
SOURCE=..\amxtime.c
# End Source File
# Begin Source File
SOURCE=..\CCmd.cpp
# End Source File
# Begin Source File
SOURCE=..\CEvent.cpp
# End Source File
# Begin Source File
SOURCE=..\CFile.cpp
# End Source File
# Begin Source File
SOURCE=..\CForward.cpp
# End Source File
# Begin Source File
SOURCE=..\CLogEvent.cpp
# End Source File
# Begin Source File
SOURCE=..\CMenu.cpp
# End Source File
# Begin Source File
SOURCE=..\CMisc.cpp
# End Source File
# Begin Source File
SOURCE=..\CModule.cpp
# End Source File
# Begin Source File
SOURCE=..\CPlugin.cpp
# End Source File
# Begin Source File
SOURCE=..\CString.cpp
# End Source File
# Begin Source File
SOURCE=..\CTask.cpp
# End Source File
# Begin Source File
SOURCE=..\CVault.cpp
# End Source File
# Begin Source File
SOURCE=..\emsg.cpp
# End Source File
# Begin Source File
SOURCE=..\file.cpp
# End Source File
# Begin Source File
SOURCE=..\float.cpp
# End Source File
# Begin Source File
SOURCE=..\meta_api.cpp
# End Source File
# Begin Source File
SOURCE=..\modules.cpp
# End Source File
# Begin Source File
SOURCE=..\power.c
# End Source File
# Begin Source File
SOURCE=..\srvcmd.cpp
# End Source File
# Begin Source File
SOURCE=..\string.cpp
# End Source File
# Begin Source File
SOURCE=..\strptime.cpp
# End Source File
# Begin Source File
SOURCE=..\util.cpp
# End Source File
# Begin Source File
SOURCE=..\vault.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\amxmod.h
# End Source File
# Begin Source File
SOURCE=..\CCmd.h
# End Source File
# Begin Source File
SOURCE=..\CEvent.h
# End Source File
# Begin Source File
SOURCE=..\CFile.h
# End Source File
# Begin Source File
SOURCE=..\CForward.h
# End Source File
# Begin Source File
SOURCE=..\CList.h
# End Source File
# Begin Source File
SOURCE=..\CLogEvent.h
# End Source File
# Begin Source File
SOURCE=..\CMenu.h
# End Source File
# Begin Source File
SOURCE=..\CMisc.h
# End Source File
# Begin Source File
SOURCE=..\CModule.h
# End Source File
# Begin Source File
SOURCE=..\CPlugin.h
# End Source File
# Begin Source File
SOURCE=..\CString.h
# End Source File
# Begin Source File
SOURCE=..\CTask.h
# End Source File
# Begin Source File
SOURCE=..\CVault.h
# End Source File
# Begin Source File
SOURCE=..\modules.h
# End Source File
# End Group
# End Target
# End Project

29
amxmodx/msvc/amxmod_mm.dsw Executable file
View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "amxmod_mm"=.\amxmod_mm.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

60
amxmodx/osdefs.h Executable file
View File

@ -0,0 +1,60 @@
/* __MSDOS__ set when compiling for DOS (not Windows)
* _Windows set when compiling for any version of Microsoft Windows
* __WIN32__ set when compiling for Windows95 or WindowsNT (32 bit mode)
* __32BIT__ set when compiling in 32-bit "flat" mode (DOS or Windows)
*
* Copyright 1998-2002, ITB CompuPhase, The Netherlands.
* info@compuphase.com.
*/
#ifndef _OSDEFS_H
#define _OSDEFS_H
/* Every compiler uses different "default" macros to indicate the mode
* it is in. Throughout the source, we use the Borland C++ macros, so
* the macros of Watcom C/C++ and Microsoft Visual C/C++ are mapped to
* those of Borland C++.
*/
#if defined(__WATCOMC__)
# if defined(__WINDOWS__) || defined(__NT__)
# define _Windows 1
# endif
# ifdef __386__
# define __32BIT__ 1
# endif
# if defined(_Windows) && defined(__32BIT__)
# define __WIN32__ 1
# endif
#elif defined(_MSC_VER)
# if defined(_WINDOWS) || defined(_WIN32)
# define _Windows 1
# endif
# ifdef _WIN32
# define __WIN32__ 1
# define __32BIT__ 1
# endif
#endif
#if defined __linux__
#include <endian.h>
#endif
/* Linux NOW has these */
#if !defined BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#if !defined LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
/* educated guess, BYTE_ORDER is undefined, i386 is common => little endian */
#if !defined BYTE_ORDER
#if defined UCLINUX
#define BYTE_ORDER BIG_ENDIAN
#else
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#endif
#endif /* _OSDEFS_H */

42
amxmodx/power.c Executable file
View File

@ -0,0 +1,42 @@
/* This file implements two native functions. It is provided as
* an example to show how to add native functions. See the manual
* for more information.
*
* Copyright (c) ITB CompuPhase, 1998, 1999
* This file may be freely used. No warranties of any kind.
*/
#include "amx.h"
static cell power(AMX *amx, cell *params)
{
/* power(value, exponent);
* params[1] = value
* params[2] = exponent
*/
cell result = 1;
while (params[2]-- > 0)
result *= params[1];
return result;
}
static cell sqroot(AMX *amx, cell *params)
{
/* sqroot(value);
* params[1] = value
* This routine uses a simple successice approximation algorithm.
*/
cell div = params[1];
cell result = 1;
while (div > result) { /* end when div == result, or just below */
div = (div + result) / 2; /* take mean value as new divisor */
result = params[1] / div;
} /* while */
return div;
}
AMX_NATIVE_INFO power_Natives[] = {
{ "power", power },
{ "sqroot", sqroot },
{ 0, 0 } /* terminator */
};

48
amxmodx/sclinux.h Executable file
View File

@ -0,0 +1,48 @@
/*
* Things needed to compile under linux.
*
* Should be reworked totally to use GNU's 'configure'
*/
/*
* Getchar is not a 'cool' replacement for MSDOS getch: Linux/unix depends on the features activated or not about the
* controlling terminal's tty. This means that ioctl(2) calls must be performed, for instance to have the controlling terminal tty's
* in 'raw' mode, if we want to be able to fetch a single character. This also means that everything must be put back
* correctly when the program ends.
*
* For interactive use of SRUN/SDBG if would be much better to use GNU's readline package: the user would be able to have
* a complete emacs/vi like line editing system.
*
* So we stick to getchar at the moment... (one needs to key ctrl-d to terminate input if getch is called with a controlling
* terminal driven by a tty having -raw)
*/
#define getch getchar
#define stricmp(a,b) strcasecmp(a,b)
#define strnicmp(a,b,c) strncasecmp(a,b,c)
/*
* WinWorld wants '\'. Unices do not.
*/
#define DIRECTORY_SEP_CHAR '/'
#define DIRECTORY_SEP_STR "/"
/*
* SC assumes that a computer is Little Endian unless told otherwise. It uses
* (and defines) the macros BYTE_ORDER and BIG_ENDIAN.
* For Linux, we must overrule these settings with those defined in glibc.
*/
#if !defined __BYTE_ORDER
# include <stdlib.h>
#endif
#if defined __OpenBSD__
# define __BYTE_ORDER BYTE_ORDER
# define __LITTLE_ENDIAN LITTLE_ENDIAN
# define __BIG_ENDIAN BIG_ENDIAN
#endif
#if !defined __BYTE_ORDER
# error "Can't figure computer byte order (__BYTE_ORDER macro not found)"
#endif

228
amxmodx/srvcmd.cpp Executable file
View File

@ -0,0 +1,228 @@
/*
* 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"
void amx_command(){
const char* cmd = CMD_ARGV(1);
if (!strcmp(cmd,"plugins") || !strcmp(cmd,"list"))
{
print_srvconsole( "Currently loaded plugins:\n");
print_srvconsole( " %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
"name","version","author","file","status");
int plugins = 0;
int running = 0;
CPluginMngr::iterator a = g_plugins.begin();
while (a)
{
++plugins;
if ( (*a).isValid() && !(*a).isPaused() )
++running;
print_srvconsole( " [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
plugins,(*a).getTitle(),(*a).getVersion(),
(*a).getAuthor(), (*a).getName(), (*a).getStatus() );
++a;
}
print_srvconsole( "%d plugins, %d running\n",plugins,running );
}
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
{
const char* sPlugin = CMD_ARGV(2);
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if ( plugin && plugin->isValid() )
{
plugin->pausePlugin();
print_srvconsole("Paused plugin \"%s\"\n",plugin->getName() );
}
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
}
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
{
const char* sPlugin = CMD_ARGV(2);
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if ( plugin && plugin->isValid() )
{
plugin->unpausePlugin();
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
}
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
}
else if (!strcmp(cmd,"cvars"))
{
print_srvconsole( "Registered cvars:\n");
print_srvconsole( " %-24.23s %-24.23s %-16.15s\n",
"name","value","plugin");
int ammount = 0;
for( CList<CCVar>::iterator a = g_cvars.begin(); a ; ++a )
{
print_srvconsole( " [%3d] %-24.23s %-24.23s %-16.15s\n",++ammount,
(*a).getName() ,CVAR_GET_STRING( (*a).getName() ),(*a).getPluginName() );
}
print_srvconsole( "%d cvars\n",ammount);
}
else if ( !strcmp(cmd,"cmds") )
{
print_srvconsole( "Registered commands:\n");
print_srvconsole( " %-24.23s %-16.15s %-8.7s %-16.15s\n",
"name","access" ,"type" ,"plugin");
int ammount = 0;
char access[32];
CmdMngr::iterator a = g_commands.begin( CMD_ConsoleCommand );
while( a )
{
UTIL_GetFlags( access , (*a).getFlags() );
print_srvconsole( " [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n",
++ammount,(*a).getCmdLine() , access , (*a).getCmdType() , (*a).getPlugin()->getName());
++a;
}
print_srvconsole( "%d commands\n",ammount);
}
else if (!strcmp(cmd,"version"))
{
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
print_srvconsole( "author: %s (%s)\n", Plugin_info.author, Plugin_info.url);
print_srvconsole( "compiled: %s\n", __DATE__ ", " __TIME__);
}
else if (!strcmp(cmd,"modules"))
{
print_srvconsole( "Currently loaded modules:\n");
print_srvconsole( " %-23.22s %-7.8s %-8.7s %-20.19s %-11.10s\n",
"name","type","version", "author", "status");
int running = 0;
int modules = 0;
CList<CModule>::iterator a = g_modules.begin();
while ( a )
{
if ( (*a).getStatusValue() == MODULE_LOADED )
++running;
++modules;
print_srvconsole( " [%2d] %-23.22s %-7.6s %-8.7s %-20.19s %-11.10s\n",modules,
(*a).getName(), (*a).getType(), (*a).getVersion(), (*a).getAuthor() , (*a).getStatus() );
++a;
}
print_srvconsole( "%d modules, %d correct\n",modules,running);
}
else
{
print_srvconsole("Usage: amx < command > [ argument ]\n");
print_srvconsole("Commands:\n");
print_srvconsole(" version - display amx version info\n");
print_srvconsole(" plugins - list plugins currently loaded\n");
print_srvconsole(" modules - list modules currently loaded\n");
print_srvconsole(" cvars - list cvars registered by plugins\n");
print_srvconsole(" cmds - list commands registered by plugins\n");
print_srvconsole(" pause < plugin > - pause a running plugin\n");
print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n");
}
}
void plugin_srvcmd()
{
cell ret = 0;
int err;
const char* cmd = CMD_ARGV(0);
#ifdef ENABLEEXEPTIONS
try{
#endif
CmdMngr::iterator a = g_commands.srvcmdbegin();
while ( a )
{
if ( (*a).matchCommand( cmd ) &&
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
{
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
print_srvconsole("[AMX] Run time error %d on line %ld (plugin \"%s\")\n",
err,(*a).getPlugin()->getAMX()->curline,(*a).getPlugin()->getName());
if ( ret ) break;
}
++a;
}
#ifdef ENABLEEXEPTIONS
}catch( ... )
{
print_srvconsole( "[AMX] fatal error at forward function execution\n");
}
#endif
}

541
amxmodx/string.cpp Executable file
View File

@ -0,0 +1,541 @@
/*
* 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 <ctype.h>
#include "amxmod.h"
const char* stristr(const char* str,const char* substr)
{
register char *needle = (char *)substr;
register char *prevloc = (char *)str;
register char *haystack = (char *)str;
while (*haystack) {
if (tolower(*haystack) == tolower(*needle)) {
haystack++;
if (!*++needle)
return prevloc;
}
else {
haystack = ++prevloc;
needle = (char *)substr;
}
}
return NULL;
}
char* format_amxstring(AMX *amx, cell *params, int parm,int& len)
{
static char buffer[2][3072];
static char format[16];
char *ptr,*arg;
char *dest = *buffer;
cell *src = get_amxaddr(amx, params[parm++]);
int numparam = *params/sizeof(cell);
while(*src) {
if (*src=='%'&&*(src+1)) {
ptr = format;
*ptr++ = *src++;
if (*src=='%'){
*dest++=*src++;
continue;
}
while (!isalpha(*ptr++=*src++))
;
*ptr=0;
if (numparam < parm) continue;
arg = buffer[1];
switch(*(ptr-1)){
case 's': sprintf(arg,format,get_amxstring(amx, params[parm++],2,len)); break;
case 'f': case 'g': sprintf(arg,format,*(float*)get_amxaddr(amx, params[parm++])); break;
default: sprintf(arg,format,(int)*get_amxaddr(amx, params[parm++]));
}
while(*arg) *dest++=*arg++;
continue;
}
*dest++=*src++;
}
*dest=0;
len = dest - *buffer;
return *buffer;
}
int amxstring_len(cell* a)
{
register int c = 0;
while( a[ c ] )
++c;
return c;
}
cell* get_amxaddr(AMX *amx,cell amx_addr)
{
return (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
}
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max)
{
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
cell* start = dest;
while (max--&&*source)
*dest++=(cell)*source++;
*dest = 0;
return dest-start;
}
char* get_amxstring(AMX *amx,cell amx_addr,int id, int& len)
{
static char buffor[4][3072];
register cell* source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register char* dest = buffor[id];
char* start = dest;
while (*dest++=(char)*source++)
;
len = --dest - start;
return start;
}
void copy_amxmemory(cell* dest,cell* src,int len)
{
while (len--)
*dest++=*src++;
}
char* parse_arg(char** line,int& state)
{
static char arg[3072];
char* dest = arg;
state = 0;
while(**line) {
if ( isspace(**line) ) {
if (state == 1)
break;
else if (!state) {
(*line)++;
continue;
}
}
else if (state != 2)
state = 1;
if (**line=='"') {
(*line)++;
if (state == 2)
break;
state = 2;
continue;
}
*dest++ = *(*line)++;
}
*dest = '\0';
return arg;
}
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
{
static char buffor[3072];
cell *a = get_amxaddr(amx,params[1]);
cell *b = get_amxaddr(amx,params[3]);
cell *c = get_amxaddr(amx,params[4]);
int iMain = amxstring_len(a);
int iWhat = amxstring_len(b);
int iWith = amxstring_len(c);
int iPot = iMain + iWith - iWhat;
if (iPot>=params[2]){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
char *d = buffor;
cell *x, *y, *z = a, *l = a;
int p = 0;
while(*a){
if (*a==*b){
x=a+1;
y=b+1;
p=1;
if (!*y) break;
while(*x==*y){
x++; y++; p++;
if (!*y) break;
}
if (!*y) break;
p = 0;
*d++=(char)*a++;
continue;
}
*d++=(char)*a++;
}
if (p){
while(*c) *d++=(char)*c++;
a+=p;
while(*a) *d++=(char)*a++;
*d=0;
d = buffor;
while(*d) *z++=*d++;
*z=0;
return (z-l);
}
return 0;
}
static cell AMX_NATIVE_CALL contain(AMX *amx, cell *params) /* 2 param */
{
register cell *a = get_amxaddr(amx,params[2]);
register cell *b = get_amxaddr(amx,params[1]);
register cell *c = b;
cell* str = b;
cell* substr = a;
while (*c) {
if (*c == *a) {
c++;
if (!*++a)
return b - str;
}
else {
c = ++b;
a = substr;
}
}
return -1;
}
static cell AMX_NATIVE_CALL containi(AMX *amx, cell *params) /* 2 param */
{
register cell *a = get_amxaddr(amx,params[2]);
register cell *b = get_amxaddr(amx,params[1]);
register cell *c = b;
cell* str = b;
cell* substr = a;
while (*c) {
if (tolower(*c) == tolower(*a)) {
c++;
if (!*++a)
return b - str;
}
else {
c = ++b;
a = substr;
}
}
return -1;
}
static cell AMX_NATIVE_CALL strtonum(AMX *amx, cell *params) /* 1 param */
{
int iLen;
return atoi(get_amxstring(amx,params[1],0,iLen));
}
static cell AMX_NATIVE_CALL numtostr(AMX *amx, cell *params) /* 3 param */
{
char szTemp[32];
sprintf(szTemp,"%d",(int)params[1]);
return set_amxstring(amx,params[2],szTemp,params[3]);
}
static cell AMX_NATIVE_CALL add(AMX *amx, cell *params) /* 4 param */
{
cell *src = get_amxaddr(amx,params[3]);
cell *dest = get_amxaddr(amx,params[1]);
cell *start = dest;
int c = params[2], d = params[4];
while(*dest&&c--)
++dest;
if (d){
while(c--&&d--&&*src)
*dest++=*src++;
*dest=0;
return (dest-start);
}
while(c--&&*src)
*dest++=*src++;
*dest=0;
return (dest-start);
}
static cell AMX_NATIVE_CALL copy(AMX *amx, cell *params) /* 4 param */
{
cell *src = get_amxaddr(amx,params[3]);
cell *dest = get_amxaddr(amx,params[1]);
cell *start = dest;
int c = params[2];
while(c--&&*src)
*dest++=*src++;
*dest=0;
return (dest-start);
}
static cell AMX_NATIVE_CALL copyc(AMX *amx, cell *params) /* 4 param */
{
cell *src = get_amxaddr(amx,params[3]);
cell *dest = get_amxaddr(amx,params[1]);
cell *start = dest;
int c = params[2];
cell ch = params[4];
while(c--&&*src&&*src!=ch)
*dest++=*src++;
*dest=0;
return (dest-start);
}
static cell AMX_NATIVE_CALL setc(AMX *amx, cell *params) /* 4 param */
{
cell *src = get_amxaddr(amx,params[1]);
int c = params[2];
cell ch = params[3];
while(c--)
*src++=ch;
return 1;
}
static cell AMX_NATIVE_CALL equal(AMX *amx, cell *params) /* 3 param */
{
cell *a = get_amxaddr(amx,params[1]);
cell *b = get_amxaddr(amx,params[2]);
int c = params[3];
if (c) {
while (--c&&*a&&(*a==*b))
++a, ++b;
return (*a-*b)?0:1;
}
int ret;
while(!(ret=*a-*b)&&*b)
++a, ++b;
return ret?0:1;
}
static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
{
cell *a = get_amxaddr(amx,params[1]);
cell *b = get_amxaddr(amx,params[2]);
int f,l, c = params[3];
if (c) {
do {
f = tolower(*a++);
l = tolower(*b++);
}
while (--c &&l&&f&& f==l);
return(f - l)?0:1;
}
do {
f = tolower(*a++);
l = tolower(*b++);
} while (f && f == l);
return (f - l)?0:1;
}
static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */
{
int len;
return set_amxstring(amx,params[1],format_amxstring(amx,params,3,len),params[2]);
}
static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */
{
int inum = *params/sizeof(cell), iarg = 2, c;
char* arg, *parse = get_amxstring(amx,params[1],0,c);
cell *cptr;
int state;
while(*parse){
arg = parse_arg(&parse,state);
if (state){
if (inum <= iarg)
return( (iarg-2)>>1 );
cptr = get_amxaddr(amx,params[iarg++]);
c = *get_amxaddr(amx,params[iarg++]);
while(c--&&*arg)
*cptr++=(cell)*arg++;
*cptr=0;
}
}
return( (iarg-2)>>1 );
}
static cell AMX_NATIVE_CALL strtolower(AMX *amx, cell *params) /* 1 param */
{
cell *cptr = get_amxaddr(amx,params[1]);
cell *begin = cptr;
while(*cptr){
*cptr = tolower(*cptr);
cptr++;
}
return cptr - begin;
}
static cell AMX_NATIVE_CALL strtoupper(AMX *amx, cell *params) /* 1 param */
{
cell *cptr = get_amxaddr(amx,params[1]);
cell *begin = cptr;
while(*cptr){
*cptr = toupper(*cptr);
cptr++;
}
return cptr - begin;
}
int fo_numargs(AMX *amx)
{
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
cell bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
return (int)(bytes/sizeof(cell));
}
int fo_getargnum(AMX *amx, int pos)
{
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
return *(cell *)(data+(int)value);
}
float fo_getargfloat(AMX *amx, int pos)
{
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
cell number = *(cell *)(data+(int)value);
return *(float *)((void *)&number);
}
char* fo_getargstr(AMX *amx, int swap, int pos)
{
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
cell src_value= * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
cell value;
static char buffer[2][3072];
char* b = buffer[swap];
int a = 0;
do {
value = src_value + a++ * sizeof(cell);
value = *(cell *)(data+(int)value);
*b++ = value;
} while (value);
return buffer[swap];
}
char* format_arguments(AMX *amx, int parm,int& len)
{
static char buffer[2][3072];
static char format[16];
char *ptr,*arg, *dest = *buffer;
char *src = fo_getargstr(amx, 0,parm++);
int numparam = fo_numargs(amx);
while(*src) {
if (*src=='%'&&*(src+1)) {
ptr = format;
*ptr++ = *src++;
if (*src=='%'){
*dest++=*src++;
continue;
}
while (!isalpha(*ptr++=*src++))
;
*ptr='\0';
if (numparam < parm) continue;
arg = buffer[1];
switch(*(ptr-1)){
case 's': sprintf(arg,format,fo_getargstr(amx,1, parm++)); break;
case 'f': case 'g': sprintf(arg,format,fo_getargfloat(amx, parm++)); break;
default: sprintf(arg,format,fo_getargnum(amx, parm++));
}
while(*arg) *dest++=*arg++;
continue;
}
*dest++=*src++;
}
*dest='\0';
len = dest - *buffer;
return *buffer;
}
static cell AMX_NATIVE_CALL format_args(AMX *amx, cell *params)
{
int len;
int pos = params[3];
if (pos < 0){
amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0;
}
char* string = format_arguments(amx, pos ,len); // indexed from 0
return set_amxstring(amx,params[1],string,params[2]);
}
static cell AMX_NATIVE_CALL is_digit(AMX *amx, cell *params)
{
return isdigit( params[1] );
}
static cell AMX_NATIVE_CALL is_alnum(AMX *amx, cell *params)
{
return isalnum( params[1] );
}
static cell AMX_NATIVE_CALL is_space(AMX *amx, cell *params)
{
return isspace( params[1] );
}
static cell AMX_NATIVE_CALL is_alpha(AMX *amx, cell *params)
{
return isalpha( params[1] );
}
AMX_NATIVE_INFO string_Natives[] = {
{ "add", add },
{ "contain", contain },
{ "containi", containi },
{ "copy", copy },
{ "copyc", copyc },
{ "equal", equal },
{ "equali", equali },
{ "format", format },
{ "format_args", format_args },
{ "isdigit", is_digit },
{ "isalnum", is_alnum },
{ "isspace", is_space },
{ "isalpha", is_alpha },
{ "numtostr", numtostr },
{ "num_to_str", numtostr },
{ "parse", parse },
{ "replace", replace },
{ "setc", setc },
{ "strtolower", strtolower },
{ "strtonum", strtonum },
{ "strtoupper", strtoupper },
{ "str_to_num", strtonum },
{ NULL, NULL }
};

398
amxmodx/strptime.cpp Executable file
View File

@ -0,0 +1,398 @@
/** strptime.c **********************************************************
Locales' support for DOS / Win31 / Win32.
Copyright (c) 1995-1997 by Timofei Bondarenko <tim@ipi.ac.ru>
Localized strptime().
*-----------------------------------------------------------------------*/
//#include "config.h"
#include <time.h>
#include <ctype.h>
#include <string.h>
#ifdef __linux__
#define strnicmp strncasecmp
#endif
const char *_lc_Wday_ [2][ 7],
*_lc_Month_[2][12],
*_lc_AmPm_ [2][ 2];
const char *_lc_fmt_c_[2],
*_lc_fmt_xD[2],
*_lc_fmt_XT[2];
int _lc_Txt_, /* 0="C", 1="Local Win"/"Rus DOS" Wday, Months, AmPm */
_lc_Fmt_; /* 0="C", 1="Local", for formats %c %x %X */
//#include "_locale.h"
struct tm_int
{
int qS, /* Seconds (0...61) */
qM, /* Minutes (0...59) */
qH, /* Hour (0...23) */
qI, /* Hour (1...12) */
qp, /* 0 = AM, 1 = PM */
qd, /* Day of month (1...31)=>[0...30] */
qm, /* Month (1...12)=>[0...11] */
qY, /* Year (0...9999) */
qy, /* year (0...99) */
qC, /* Century (0...99) */
qw, /* Weekday (0...6; Sunday = 0) */
qj, /* Day of year (1..366)=>[0...365] */
qZ, /* 0 = STD, 1 = DST */
qU, /* week in year (0...53) */
qV; /* week in year mode: 'U', 'W', 'V' */
};
/* skips spaces in `strp`. Returns 0 if no spaces skipped */
static void skip_sp(const unsigned char **strp)
{
while(isspace(**strp)) (*strp)++;
}
/* scans no more decimal digits than contained in `max` as an integer,
sign isn't allowed. Returns -1 if 0 digits scanned or
if the scanned number is greater than `max`. */
static int scan_int(const unsigned char **strp, int max)
{
int cc, val, pos;
skip_sp(strp);
for(val = pos = 0; pos < max && isdigit(cc = **strp); (*strp)++)
{
pos = pos * 10 + 9;
if ((val = val * 10 + (cc - '0')) > max) return -1;
/*val = val * 10 + (cc - '0');*/
}
return pos? val: -1;
}
static int scan_int2(const unsigned char **strp)
{
int cc, val, pos;
skip_sp(strp);
for(val = pos = 0; isdigit(cc = **strp); (*strp)++)
{
pos = pos * 10 + 9;
val = val * 10 + (cc - '0');
}
return pos? val: -1;
}
/* scans one word which is equivalence (case insensitive) to a
word from list `n_full` or from list `n_short` or when
n_short is NULL to first 3 characters from a word from `n_full`.
`max` is number of words in each list `n_full` or `n_short`.
Returns the index in a list >= 0 and < `max`, or -1 if no word found. */
static int scan_word_(const unsigned char **strp,
int max, const char *const *n_full
#if USE_ABBR_NAMES
, const char *const *n_short
#endif
)
{
int ix, l_max = 100;
int found, found_len;
const char *const *word_list;
found = found_len = -1;
skip_sp(strp); /* Required? Or Not? */
Scan0:
word_list = n_full;
/*Scan1:*/
for(ix = 0; ix < max; word_list++, ix++)
{
int len;
const char *word = *word_list;
skip_sp((const unsigned char**)&word);
if (l_max < (len = strlen(word))) len = l_max;
if (found_len < len && /* search for maximal lenth */
(!len || /* at least "" always founded */
!strnicmp((const char*)*strp, word, len))) /* found */
found_len = len, found = ix;
}
if (l_max >= 100) /* first pass: full names */
{ /* go to second pass: short names */
#if USE_ABBR_NAMES
if (n_short)
{
l_max--; word_list = n_short; goto Scan1;
}
#endif
l_max = 3; goto Scan0;
}
if (found_len > 0) (*strp) += found_len;
return found; /* -1 or index or first "" */
}
#if USE_ABBR_NAMES
#define scan_word scan_word_ /* pass all arguments as is */
#else
#define scan_word(str,max,n_full,n_short) scan_word_(str,max,n_full)
#endif
static int time_int(struct tm_int *ti,
const unsigned char **buf, const char *fmt, short addthem)
{
int ii;
for(; (ii = (unsigned char)*fmt); fmt++)
if (ii != '%')
{
Other:
if (isspace(ii))
{
/*SkipSp:*/ fmt++; skip_sp((const unsigned char **)&fmt);
fmt--; skip_sp(buf);
} /* toupper(ii) != toupper(**buf) */
/*else if (_lc_igncase[ii] != _lc_igncase[**buf]) return -1;*/
else (*buf)++;
}
else
{
const char *fs;
/*Fmt:*/ switch(ii = (unsigned char)*++fmt)
{
case 0 : goto FmtEnd;
case 'a':
case 'A':
ti->qw = ii = scan_word(buf, 7,
_lc_Wday_[_lc_Txt_],
_lc_Txt_? _lc_WdayS: NULL); break;
case 'h': /* STRFTIME_EXT */
case 'b':
case 'B':
ti->qm = ii = scan_word(buf, 12,
_lc_Month_[_lc_Txt_],
_lc_Txt_? _lc_MonthS: NULL); break;
case 'c':
fs = _lc_fmt_c_[_lc_Fmt_];
strpt: ii = time_int(ti, buf, fs, addthem); break;
#if STRFTIME_EXT
case 'C': /* STRFTIME_EXT */
ti->qC = ii = addthem ? scan_int2(buf) : scan_int(buf,99);
if (ti->qy >= 0) goto SetYear;
else if (ti->qY >= 0)
{
ti->qY = ti->qY % 100 + ii * 100;
goto CleanCy;
}
break;
case 'e': /* STRFTIME_EXT */
#endif
case 'd':
ti->qd = ii = (addthem ? scan_int2(buf) : scan_int(buf, 31)) - 1; break;
#if STRFTIME_EXT
case 'D': /* STRFTIME_EXT */
fs = _lc_fmt_xD[0]; goto strpt;
/* case 'E': STRFTIME_EXT "Era specefic" see %'O' */
/* case 'h': STRFTIME_EXT see %'b' */
#endif
case 'H':
ti->qH = ii = addthem ? scan_int2(buf) : scan_int(buf, 23);
CleanIp: ti->qI = ti->qp = -1; break;
case 'I':
ti->qI =
ti->qH = ii = addthem ? scan_int2(buf) : scan_int(buf, 23);
if (ii == 0 || ii > 12) goto CleanIp;
else ti->qH = -1;
break;
case 'j':
ti->qj = ii = (addthem ? scan_int2(buf) : scan_int(buf, 366)) - 1;
ti->qU = -1; break;
case 'm':
ti->qm = ii = (addthem ? scan_int2(buf) : scan_int(buf, 12)) - 1; break;
case 'M':
ti->qM = ii = addthem ? scan_int2(buf) : scan_int(buf, 59); break;
#if STRFTIME_EXT
case 'n': /* STRFTIME_EXT */
case 't': /* STRFTIME_EXT */ goto SkipSp;
case 'N': /* STRFTIME_EXT */
fs = _lc_fmt_N_; goto strpt;
case 'E': /* STRFTIME_EXT "Era specefic" */
#endif
#if STRFTIME_EXT | STRFTIME_WIN
case 'O': /* STRFTIME_EXT "Alternate digits" */
goto Fmt;
#endif
case 'p':
ti->qp = /*ii =*/ scan_word(buf, 2, _lc_AmPm_[_lc_Txt_], NULL);
break;
#if STRFTIME_EXT
case 'r': /* STRFTIME_EXT */
fs = _lc_fmt_rI; goto strpt;
case 'R': /* STRFTIME_EXT */
fs = _lc_fmt_RH; goto strpt;
#endif
case 'S':
ti->qS = ii = addthem ? scan_int2(buf) : scan_int(buf, 61); break;
#if STRFTIME_EXT
case 'T': /* STRFTIME_EXT */
fs = _lc_fmt_XT[0]; goto strpt;
case 'u': /* STRFTIME_EXT */
ti->qw = ii = addthem ? scan_int2(buf) : scan_int(buf, 7);
if (ii == 7) ti->qw = 0;
else if (!ii) ii--;
break;
#endif
#if STRFTIME_EXT && 0
case 'V': /* STRFTIME_EXT 0 = Wednesday ?(Thursday) */
#endif
case 'U':
case 'W':
ti->qV = ii;
ti->qU = ii = addthem ? scan_int2(buf) : scan_int(buf, 53); break;
case 'w':
ti->qw = ii = addthem ? scan_int2(buf) : scan_int(buf, 6); break;
case 'x':
fs = _lc_fmt_xD[_lc_Fmt_]; goto strpt;
case 'X':
fs = _lc_fmt_XT[_lc_Fmt_]; goto strpt;
case 'y':
ti->qy = ii = addthem ? scan_int2(buf) : scan_int(buf, 99);
#if STRFTIME_EXT
if (ti->qC >= 0)
{
SetYear: ti->qY = ti->qC * 100 + ti->qy;
goto CleanCy;
}
#endif
if (ti->qY >= 0)
{
ti->qY = ti->qY - ti->qY % 100 + ii;
goto CleanCy;
}
break;
case 'Y':
ti->qY = ii = addthem ? scan_int2(buf) : scan_int(buf, 9999);
CleanCy: ti->qC = ti->qy = -1; break;
#if STRFTIME_EXT
case 'Z': /* STRFTIME_EXT */
ti->qZ = ii = scan_word(buf, /*!daylight? 1:*/ 2, tzname, NULL) +1;
if (!ii)
while((ii = **buf) && !isspace(ii)
/*&& !isdigit(ii) && !strchr("+-,", ii)*/
) (*buf)++;
break;
#endif
/* case '%': */
default: /**************************/ goto Other;
} /* end of switch() */
if (ii < 0) return -1;
} /* end of else, for() */
FmtEnd:
return 0;
}
typedef void (*specoper)(int* one, int two);
void justreplace(int* one, int two){
*one = two;
}
void justadd(int* one, int two){
*one += two;
}
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem)
{
specoper defoper = addthem ? justadd : justreplace;
struct tm_int ti;
ti.qS = /* Seconds (0...61) */
ti.qM = /* Minutes (0...59) */
ti.qH = /* Hour (0...23) */
ti.qI = /* Hour (1...12) */
ti.qp = /* 0 = AM, 1 = PM */
ti.qd = /* Day of month (1...31)=>[0...30] */
ti.qm = /* Month (1...12)=>[0...11] */
ti.qY = /* Year (0...9999) */
ti.qy = /* year (0...99) */
ti.qC = /* Century (0...99) */
ti.qw = /* Weekday (0...6; Sunday = 0) */
ti.qj = /* Day of year (1..366)=>[0...365] */
ti.qZ = /* 0 = STD, 1 = DST */
ti.qU = /* week in year (0...53) */
ti.qV = -1; /* week in year mode: 0=U, 1=W, 2=V */
if (0 > time_int(&ti, (const unsigned char **)&buf, fmt, addthem)) buf = NULL;
if (0 <= ti.qS) (*defoper) ( &tm->tm_sec , ti.qS );
if (0 <= ti.qM) (*defoper) ( &tm->tm_min , ti.qM ); //tm->tm_min = ti.qM;
if (0 <= ti.qI)
if (0 <= ti.qp) ti.qH = ti.qI % 12 + ti.qp * 12;
else (*defoper) ( &tm->tm_hour , ti.qI ); //tm->tm_hour = ti.qI;
if (0 <= ti.qH) (*defoper) ( &tm->tm_hour , ti.qH ); //tm->tm_hour = ti.qH;
if (0 <= ti.qZ) (*defoper) ( &tm->tm_isdst , ti.qZ - 1 ); //tm->tm_isdst = ti.qZ - 1;
if (0 <= ti.qy) ti.qY = ti.qy;
if (0 <= ti.qY) (*defoper) ( &tm->tm_year ,
ti.qY +=
(ti.qY > 99? -1900:
(ti.qY < 70? 100: 0)) );
/*tm->tm_year = ti.qY +=
(ti.qY > 99? -1900:
(ti.qY < 70? 100: 0));*/
/* ti.qC = %C = Century without an Year - ignored */
if (70 <= ti.qY && ti.qY < 200) /* a representable year */
{
/* 01-01-70 was Thursday, 1968 was leap */
int day = (((ti.qY - 69) >> 2) + ti.qY - 70 + 4) % 7;
/* 2100 wrongly assumed as leap!
if (ti.qY > 200 && --day < 0) day = 6; */
if (0 <= ti.qU && 0 <= ti.qw && 0 > ti.qj)
{
ti.qj = ti.qU * 7;
switch(ti.qV)
{
case 'U': /* %U Sun first */
ti.qj += ti.qw - (day == 0 ? 7: day);
break;
case 'W': /* %W Mon first */
ti.qj += (ti.qw + 6) % 7
- (day == 1 ? 7: (day + 6) % 7);
break;
#if STRFTIME_EXT && 0
case 'V': /* %V >= 4 day */
if (ti.qU == 53) ti.qj = 0;
/* Sun first: */
ti.qj += ti.qw - (day < 4 ? 7: 0) - day;
/* Mon first:
ti.qj += (ti.qw + 6) % 7
- ((day + 6) % 7 < 5 ? 7: 0)
- (day + 6) % 7; */
break;
#endif
default: break;
}
}
#if 0 /* Advanced validating for yday<>m/d/y */
if (0 <= ti.qj)
{
static int m_days[12] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
int mon = (ti.qj + day) % 7;
if (0 > ti.qw) ti.qw = mon;
else if (ti.qw != mon) return NULL;
for(mon = 11; 0 > (day = /* not for 2100: && ti.qY != 200 */
ti.qj - (m_days[mon] + (mon > 1 && !(ti.qY & 3))))
; mon--);
if (0 > ti.qd) ti.qd = day;
else if (ti.qd != day) return NULL;
if (0 > ti.qm) ti.qm = mon;
else if (ti.qm != mon) return NULL;
}
#endif
}
if (0 <= ti.qd) (*defoper) ( &tm->tm_mday , ti.qd + 1 ); //tm->tm_mday = ti.qd + 1;
if (0 <= ti.qm) (*defoper) ( &tm->tm_mon , ti.qm ); //tm->tm_mon = ti.qm;
if (0 <= ti.qw) (*defoper) ( &tm->tm_wday , ti.qw ); //tm->tm_wday = ti.qw;
if (0 <= ti.qj) (*defoper) ( &tm->tm_yday , ti.qj ); //tm->tm_yday = ti.qj;
return (char*)buf;
}
/* end of strftime.c */

271
amxmodx/util.cpp Executable file
View File

@ -0,0 +1,271 @@
/*
* 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"
int UTIL_ReadFlags(const char* c)
{
int flags = 0;
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
return flags;
}
void UTIL_GetFlags(char* f,int a)
{
for(int i='a';i<='z';++i){
if ( a & 1 ) *f++ = i;
a >>= 1;
}
*f = 0;
}
/* warning - don't pass here const string */
void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
{
char *n = menu;
char c = 0;
int a;
while ( *n ) {
a = mlen;
if ( a > 175 ) a = 175;
mlen -= a;
c = *(n+=a);
*n = 0;
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
WRITE_SHORT( slots );
WRITE_CHAR( time );
WRITE_BYTE( c ? TRUE : FALSE);
WRITE_STRING( menu );
MESSAGE_END();
*n = c;
menu = n;
}
}
/* warning - don't pass here const string */
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
{
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
WRITE_STRING(name);
MESSAGE_END();
char *n = motd;
char c = 0;
int a;
while ( *n ) {
a = mlen;
if ( a > 175 ) a = 175;
mlen -= a;
c = *(n+=a);
*n = 0;
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
WRITE_BYTE( c ? FALSE : TRUE );
WRITE_STRING( motd );
MESSAGE_END();
*n = c;
motd = n;
}
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
WRITE_STRING( hostname->string );
MESSAGE_END();
}
void UTIL_IntToString(int value, char *output)
{
static const char *words[] = {"zero ","one ","two ","three ","four ",
"five ", "six ","seven ","eight ","nine ","ten ",
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
"sixteen ","seventeen ","eighteen ","nineteen ",
"twenty ","thirty ","fourty ", "fifty ","sixty ",
"seventy ","eighty ","ninety ",
"hundred ","thousand "};
*output = 0;
if (value < 0) value = -value;
int tho = value / 1000;
int aaa = 0;
if (tho){
aaa += sprintf(&output[aaa], words[ tho ] );
aaa += sprintf(&output[aaa], words[29] );
value = value % 1000;
}
int hun = value / 100;
if (hun) {
aaa += sprintf(&output[aaa], words[ hun ] );
aaa += sprintf(&output[aaa], words[28] );
value = value % 100;
}
int ten = value / 10;
int unit = value % 10;
if ( ten )
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
sprintf(&output[aaa], words[ unit ] );
}
char* UTIL_SplitHudMessage(const char *src)
{
static char message[512];
short b = 0, d = 0, e = 0, c = -1;
while ( src[ d ] && e < 480 ) {
if ( src[ d ] == ' ' ) {
c = e;
}
else if ( src[ d ] == '\n' ) {
c = -1;
b = 0;
}
message[ e++ ] = src[ d++ ];
if ( ++b == 69 ) {
if ( c == -1 ) {
message[ e++ ] = '\n';
b = 0;
}
else {
message[ c ] = '\n';
b = e - c - 1;
c = -1;
}
}
}
message[ e ] = 0;
return message;
}
unsigned short FixedUnsigned16( float value, float scale )
{
int output = value * scale;
if ( output < 0 )
output = 0;
else if ( output > 0xFFFF )
output = 0xFFFF;
return (unsigned short)output;
}
short FixedSigned16( float value, float scale )
{
int output = value * scale;
if ( output > 32767 )
output = 32767;
else if ( output < -32768 )
output = -32768;
return (short)output;
}
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
{
if ( pEntity )
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
else
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
WRITE_BYTE(29);
WRITE_BYTE(textparms.channel & 0xFF);
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) ));
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) ));
WRITE_BYTE(textparms.effect);
WRITE_BYTE(textparms.r1);
WRITE_BYTE(textparms.g1);
WRITE_BYTE(textparms.b1);
WRITE_BYTE(0);
WRITE_BYTE(255);
WRITE_BYTE(255);
WRITE_BYTE(250);
WRITE_BYTE(0);
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
if (textparms.effect==2)
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
WRITE_STRING(pMessage);
MESSAGE_END();
}
/* warning - buffer of msg must be longer than 190 chars!
(here in AMX it is always longer) */
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg )
{
char c = msg[190];
msg[190] = 0; // truncate without checking with strlen()
if ( pEntity )
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
else
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
WRITE_BYTE( msg_dest );
WRITE_STRING( msg );
MESSAGE_END();
msg[190] = c;
}
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2) {
if (!cmd) return;
//strncpy(g_fakecmd.argv[0], cmd, 127 );
//g_fakecmd.argv[0][ 127 ] = 0;
g_fakecmd.argv[0] = cmd;
if (arg2){
g_fakecmd.argc = 3;
g_fakecmd.argv[1] = arg1;
g_fakecmd.argv[2] = arg2;
snprintf( g_fakecmd.args ,255 , "%s %s",arg1,arg2 );
g_fakecmd.args[255] = 0;
//strncpy(g_fakecmd.argv[1], arg1 , 127 );
//g_fakecmd.argv[1][ 127 ] = 0;
//strncpy(g_fakecmd.argv[2], arg2 , 127 );
//g_fakecmd.argv[2][ 127 ] = 0;
//snprintf(g_fakecmd.args, 255 , "%s %s",arg1,arg2);
//g_fakecmd.args[255] = 0;
}
else if (arg1){
g_fakecmd.argc = 2;
g_fakecmd.argv[1] = arg1;
snprintf( g_fakecmd.args ,255 , "%s" , arg1 );
g_fakecmd.args[255] = 0;
//strncpy(g_fakecmd.argv[1], arg1, 127 );
//g_fakecmd.argv[1][ 127 ] = 0;
//*g_fakecmd.argv[2] = 0;
//snprintf(g_fakecmd.args, 255 ,"%s",arg1);
//g_fakecmd.args[255] = 0;
}
else
g_fakecmd.argc = 1;
g_fakecmd.fake = true;
MDLL_ClientCommand(pEdict);
g_fakecmd.fake = false;
}

85
amxmodx/vault.cpp Executable file
View File

@ -0,0 +1,85 @@
/*
* 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 "CVault.h"
#include "amxmod.h"
Vault g_vault;
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx,cell *params)
{
int iLen;
g_vault.put( get_amxstring(amx,params[1],0,iLen) , get_amxstring(amx,params[2],1,iLen) );
g_vault.saveVault();
return 1;
}
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx,cell *params)
{
int iLen;
const char* key = get_amxstring(amx,params[1],0,iLen);
if ( params[3] )
return set_amxstring( amx , params[2] , g_vault.get( key ) , params[3] );
return g_vault.get_number( key );
}
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx,cell *params)
{
int iLen;
g_vault.remove( get_amxstring(amx,params[1],0,iLen) );
g_vault.saveVault();
return 1;
}
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx,cell *params)
{
int iLen;
return g_vault.exists( get_amxstring(amx,params[1],0,iLen) ) ? 1 : 0;
}
AMX_NATIVE_INFO vault_Natives[] = {
{ "set_vaultdata", set_vaultdata },
{ "get_vaultdata", get_vaultdata },
{ "remove_vaultdata", remove_vaultdata },
{ "delete_vaultdata", remove_vaultdata },
{ "vaultdata_exists", vaultdata_exists },
{ 0, 0 }
};