Compare commits
139 Commits
amxmodx-1.
...
amxmodx-1.
Author | SHA1 | Date | |
---|---|---|---|
5f34f1baaa | |||
dc5e458d9e | |||
4feaa1449f | |||
25002f559a | |||
41f38424ee | |||
862ee2029a | |||
cd30fb0c1c | |||
59ad6c49e3 | |||
2d255829a6 | |||
be762580b7 | |||
ae8bf10746 | |||
324f4c58a8 | |||
a816767abb | |||
164a47bde4 | |||
545769e241 | |||
dcf39196d5 | |||
58dd553d00 | |||
f64ca6a827 | |||
ebd4974c75 | |||
4b1769f457 | |||
f58c0f4508 | |||
4d7bdcde47 | |||
c7a620424e | |||
24260137ec | |||
315e69797d | |||
dddc693369 | |||
13e654aafe | |||
f02c73f94c | |||
92f79ffe88 | |||
db33e50f92 | |||
2ad557024e | |||
ddf3b6df32 | |||
12bf140931 | |||
0d65bb64f9 | |||
c6e265b414 | |||
9ba597b5c1 | |||
b6a4514bd0 | |||
a6daebe7d4 | |||
471ba0adbf | |||
7225aa3cc0 | |||
88b833f879 | |||
6f8816c13f | |||
95ccd6078c | |||
2e5c71f771 | |||
eeb77395cd | |||
e3afe22a48 | |||
73d70aff29 | |||
120c849e4b | |||
138b732e75 | |||
760e29e531 | |||
401ee3c97f | |||
6e52ce7678 | |||
89aab62549 | |||
468d99ff70 | |||
2d787f43de | |||
f0c5e44985 | |||
76760b221d | |||
612a86dbef | |||
369ece2d56 | |||
cc37f479aa | |||
deaaf20713 | |||
e566413224 | |||
368856f122 | |||
52cc204787 | |||
52b1d67ca2 | |||
16ad8739e7 | |||
e67457440d | |||
fc955009da | |||
0dc2ba85e8 | |||
de65e65854 | |||
d95f2cba37 | |||
e2a521583a | |||
f8aac5e88d | |||
4738c92b8e | |||
7ce59966fc | |||
afa1337e62 | |||
cc34f468f0 | |||
3f9598fcbb | |||
97b5391118 | |||
227c13d12c | |||
729932476b | |||
7c21deb0f2 | |||
80048eba61 | |||
0552e5ef58 | |||
ce881a7d30 | |||
80dd7f034d | |||
5fac746feb | |||
67f012b74a | |||
5705e69abb | |||
bece1e6d0c | |||
f2527ecc86 | |||
66b95f64a5 | |||
af79fe8e20 | |||
d3e2bad4e7 | |||
6bebf37f1a | |||
2f27b7da8d | |||
824caab2c5 | |||
a105bc7402 | |||
81ab33d794 | |||
e90364c17b | |||
ac4014ff5a | |||
ad634924fa | |||
2d5f9ba181 | |||
aa0e4e121e | |||
f8227a09b4 | |||
46130a6754 | |||
58c006a9c8 | |||
ea1d72401c | |||
fdbe0e2064 | |||
e239801671 | |||
4be88a5015 | |||
ee02d0b13d | |||
2ec084ffa3 | |||
6636c20336 | |||
27c80b00f8 | |||
6bcb72952c | |||
8c17be27dd | |||
0232b0abee | |||
12fd7a9f0d | |||
71c6e70706 | |||
c5cc94ba98 | |||
8220cc4c01 | |||
57ce74c4c7 | |||
5d6c72bf42 | |||
63b2bbc67e | |||
12f628e3d7 | |||
cd8d800eb7 | |||
160ab3572b | |||
dc57ef1e0c | |||
ca1544564c | |||
462916d00f | |||
e15761b79a | |||
270d898f82 | |||
2a2d5697b8 | |||
b17f277a1b | |||
c15ed5741a | |||
9e035dc744 | |||
ac279b37e4 | |||
974fdc950e |
193
amxmodx/CCmd.cpp
193
amxmodx/CCmd.cpp
@ -35,8 +35,10 @@
|
||||
// *****************************************************
|
||||
// class CmdMngr
|
||||
// *****************************************************
|
||||
CmdMngr::CmdMngr() {
|
||||
memset(sortedlists,0,sizeof(sortedlists));
|
||||
|
||||
CmdMngr::CmdMngr()
|
||||
{
|
||||
memset(sortedlists, 0, sizeof(sortedlists));
|
||||
srvcmdlist = 0;
|
||||
clcmdlist = 0;
|
||||
prefixHead = 0;
|
||||
@ -49,13 +51,12 @@ CmdMngr::CmdMngr() {
|
||||
|
||||
}
|
||||
|
||||
CmdMngr::Command::Command( CPluginMngr::CPlugin* pplugin,const char* pcmd,
|
||||
const char* pinfo , int pflags , int pfunc,
|
||||
bool pviewable, CmdMngr* pparent ) : commandline(pcmd) , info(pinfo) {
|
||||
|
||||
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);
|
||||
*szCmd = 0; *szArg = 0;
|
||||
sscanf(pcmd, "%s %s", szCmd, szArg);
|
||||
command.assign(szCmd);
|
||||
argument.assign(szArg);
|
||||
plugin = pplugin;
|
||||
@ -73,95 +74,88 @@ CmdMngr::Command::~Command()
|
||||
++uniqueid;
|
||||
}
|
||||
|
||||
CmdMngr::Command* CmdMngr::registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable )
|
||||
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;
|
||||
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 )
|
||||
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 )
|
||||
//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) )
|
||||
if ((id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype))
|
||||
{
|
||||
buf_cmdptr = begin( type );
|
||||
buf_cmdptr = begin(type);
|
||||
buf_cmdaccess = access;
|
||||
buf_cmdtype = type;
|
||||
buf_cmdid = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int a = id;
|
||||
id -= buf_cmdid;
|
||||
buf_cmdid = a;
|
||||
}
|
||||
|
||||
while ( buf_cmdptr )
|
||||
while (buf_cmdptr)
|
||||
{
|
||||
|
||||
if ( (*buf_cmdptr).gotAccess( access ) &&
|
||||
(*buf_cmdptr).getPlugin()->isExecutable( (*buf_cmdptr).getFunction() )
|
||||
&& (*buf_cmdptr).isViewable() )
|
||||
if ((*buf_cmdptr).gotAccess(access) && (*buf_cmdptr).getPlugin()->isExecutable((*buf_cmdptr).getFunction()) && (*buf_cmdptr).isViewable())
|
||||
{
|
||||
|
||||
if ( id-- == 0 )
|
||||
if (id-- == 0)
|
||||
return &(*buf_cmdptr);
|
||||
|
||||
}
|
||||
|
||||
++buf_cmdptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdMngr::getCmdNum( int type, int access )
|
||||
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
|
||||
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 );
|
||||
CmdMngr::iterator a = begin(type);
|
||||
|
||||
while ( a )
|
||||
while (a)
|
||||
{
|
||||
|
||||
if ( (*a).gotAccess( access ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() )
|
||||
&& (*a).isViewable() )
|
||||
++buf_num;
|
||||
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 )
|
||||
void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
|
||||
{
|
||||
CmdLink* np = new CmdLink( c );
|
||||
CmdLink* np = new CmdLink(c);
|
||||
|
||||
if ( np == 0 ) return;
|
||||
if (np == 0) return;
|
||||
|
||||
if ( sorted )
|
||||
if (sorted)
|
||||
{
|
||||
while( *a )
|
||||
while (*a)
|
||||
{
|
||||
int i = strcmp(c->getCommand(),(*a)->cmd->getCommand() );
|
||||
int i = strcmp(c->getCommand(), (*a)->cmd->getCommand());
|
||||
|
||||
if ( (i<0) || (i==0) && ( strcmp( c->getArgument() , (*a)->cmd->getArgument() ) < 0 ) )
|
||||
if ((i < 0) || (i == 0) && (strcmp(c->getArgument(), (*a)->cmd->getArgument()) < 0))
|
||||
break;
|
||||
|
||||
a = &(*a)->next;
|
||||
@ -169,84 +163,101 @@ void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
|
||||
|
||||
np->next = *a;
|
||||
*a = np;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( *a ) a = &(*a)->next;
|
||||
} else {
|
||||
while (*a) a = &(*a)->next;
|
||||
*a = np;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CmdMngr::clearCmdLink( CmdLink** phead, bool pclear )
|
||||
void CmdMngr::clearCmdLink(CmdLink** phead, bool pclear)
|
||||
{
|
||||
while( *phead ){
|
||||
while (*phead)
|
||||
{
|
||||
CmdLink* pp = (*phead)->next;
|
||||
if ( pclear ) delete (*phead)->cmd;
|
||||
|
||||
if (pclear) delete (*phead)->cmd;
|
||||
delete *phead;
|
||||
*phead = pp;
|
||||
}
|
||||
}
|
||||
|
||||
void CmdMngr::Command::setCmdType( int a )
|
||||
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;
|
||||
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 & 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 );
|
||||
|
||||
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";
|
||||
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 )
|
||||
bool CmdMngr::registerCmdPrefix(Command* cc)
|
||||
{
|
||||
CmdPrefix** b = findPrefix( cc->getCommand() );
|
||||
if (*b){
|
||||
setCmdLink( &(*b)->list , cc , false );
|
||||
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 )
|
||||
void CmdMngr::registerPrefix(const char* nn)
|
||||
{
|
||||
if ( *nn == 0 ) return;
|
||||
CmdPrefix** b = findPrefix( nn );
|
||||
if (*nn == 0) return;
|
||||
CmdPrefix** b = findPrefix(nn);
|
||||
|
||||
if (*b) return;
|
||||
*b = new CmdPrefix( nn , this );
|
||||
*b = new CmdPrefix(nn, this);
|
||||
}
|
||||
|
||||
CmdMngr::CmdPrefix** CmdMngr::findPrefix( const char* nn ){
|
||||
CmdMngr::CmdPrefix** CmdMngr::findPrefix(const char* nn)
|
||||
{
|
||||
CmdPrefix** aa = &prefixHead;
|
||||
while(*aa){
|
||||
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
|
||||
|
||||
while (*aa)
|
||||
{
|
||||
if (!strncmp((*aa)->name.c_str(), nn, (*aa)->name.size()))
|
||||
break;
|
||||
aa=&(*aa)->next;
|
||||
aa = &(*aa)->next;
|
||||
}
|
||||
|
||||
return aa;
|
||||
}
|
||||
|
||||
void CmdMngr::clearPrefix(){
|
||||
while(prefixHead){
|
||||
void CmdMngr::clearPrefix()
|
||||
{
|
||||
while (prefixHead)
|
||||
{
|
||||
CmdPrefix* a = prefixHead->next;
|
||||
delete prefixHead;
|
||||
prefixHead = a;
|
||||
@ -264,7 +275,8 @@ void CmdMngr::clear()
|
||||
clearBufforedInfo();
|
||||
}
|
||||
|
||||
void CmdMngr::clearBufforedInfo() {
|
||||
void CmdMngr::clearBufforedInfo()
|
||||
{
|
||||
buf_type = -1;
|
||||
buf_access = 0;
|
||||
buf_id = -1;
|
||||
@ -274,4 +286,3 @@ void CmdMngr::clearBufforedInfo() {
|
||||
}
|
||||
|
||||
int CmdMngr::Command::uniqueid = 0;
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
// class CmdMngr
|
||||
// *****************************************************
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CMD_ConsoleCommand,
|
||||
CMD_ClientCommand,
|
||||
CMD_ServerCommand
|
||||
@ -48,14 +49,17 @@ public:
|
||||
class Command;
|
||||
friend class Command;
|
||||
|
||||
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;
|
||||
@ -63,33 +67,33 @@ public:
|
||||
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(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags, int pfunc, bool pviewable, CmdMngr* pparent);
|
||||
~Command();
|
||||
public:
|
||||
|
||||
inline const char* getCommand() { return command.c_str(); }
|
||||
inline const char* getArgument() { return argument.c_str(); }
|
||||
inline const char* getCmdInfo() { return info.c_str(); }
|
||||
inline const char* getCmdLine() { return commandline.c_str(); }
|
||||
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.c_str()+prefix, cmd+prefix ) && (argument.empty() || !stricmp(argument.c_str() , arg ))); }
|
||||
inline bool matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd )); }
|
||||
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.c_str() + prefix, cmd + prefix) && (argument.empty() || !stricmp(argument.c_str(), arg))); }
|
||||
inline bool matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd)); }
|
||||
inline int getFunction() const { return function; }
|
||||
inline bool gotAccess(int f) const { return (!flags||((flags & f)==flags)); }
|
||||
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 );
|
||||
|
||||
const char* getCmdType() const;
|
||||
void setCmdType(int a);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct CmdPrefix;
|
||||
friend struct CmdPrefix;
|
||||
|
||||
struct CmdLink {
|
||||
struct CmdLink
|
||||
{
|
||||
Command* cmd;
|
||||
CmdLink* next;
|
||||
CmdLink(Command* c): cmd(c), next(0) {}
|
||||
@ -99,36 +103,40 @@ private:
|
||||
CmdLink* srvcmdlist;
|
||||
CmdLink* clcmdlist;
|
||||
|
||||
struct CmdPrefix {
|
||||
struct CmdPrefix
|
||||
{
|
||||
String name;
|
||||
CmdMngr* parent;
|
||||
CmdLink* list;
|
||||
CmdPrefix* next;
|
||||
CmdPrefix( const char* nn , CmdMngr* pp) : name(nn),parent(pp),list(0),next(0){}
|
||||
~CmdPrefix(){ parent->clearCmdLink(&list); }
|
||||
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 );
|
||||
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 );
|
||||
void setCmdLink(CmdLink** a, Command* c, bool sorted = true);
|
||||
void clearCmdLink(CmdLink** phead, bool pclear = false);
|
||||
|
||||
public:
|
||||
CmdMngr();
|
||||
~CmdMngr() {clear();}
|
||||
~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 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 {
|
||||
class iterator
|
||||
{
|
||||
CmdLink *a;
|
||||
public:
|
||||
iterator(CmdLink*aa = 0) : a(aa) {}
|
||||
@ -138,28 +146,30 @@ public:
|
||||
operator bool () const { return a ? true : false; }
|
||||
Command& operator*() { return *a->cmd; }
|
||||
};
|
||||
inline iterator clcmdprefixbegin(const char* nn){
|
||||
|
||||
inline iterator clcmdprefixbegin(const char* nn)
|
||||
{
|
||||
CmdPrefix* a = *findPrefix(nn);
|
||||
return iterator( a ? a->list : 0 );
|
||||
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 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
|
||||
#endif //COMMANDS_H
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
// class ClEvent
|
||||
// *****************************************************
|
||||
|
||||
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||
{
|
||||
m_Plugin = plugin;
|
||||
m_Func = func;
|
||||
@ -45,13 +45,14 @@ EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||
m_FlagAlive = true;
|
||||
m_FlagDead = true;
|
||||
|
||||
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||
|
||||
if (flags & 24)
|
||||
{
|
||||
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||
}
|
||||
|
||||
m_Stamp = 0.0f;
|
||||
@ -64,12 +65,14 @@ EventsMngr::ClEvent::~ClEvent()
|
||||
{
|
||||
cond_t *tmp1 = m_Conditions;
|
||||
cond_t *tmp2 = NULL;
|
||||
|
||||
while (tmp1)
|
||||
{
|
||||
tmp2 = tmp1->next;
|
||||
delete tmp1;
|
||||
tmp1 = tmp2;
|
||||
}
|
||||
|
||||
m_Conditions = NULL;
|
||||
}
|
||||
|
||||
@ -82,14 +85,17 @@ void EventsMngr::NextParam()
|
||||
|
||||
MsgDataEntry *tmp = NULL;
|
||||
int tmpSize = 0;
|
||||
|
||||
if (m_ParseVault)
|
||||
{
|
||||
// copy to tmp
|
||||
tmp = new MsgDataEntry[m_ParseVaultSize];
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
return; // :TODO: Error report !!
|
||||
}
|
||||
|
||||
memcpy(tmp, m_ParseVault, m_ParseVaultSize * sizeof(MsgDataEntry));
|
||||
tmpSize = m_ParseVaultSize;
|
||||
delete [] m_ParseVault;
|
||||
@ -102,6 +108,7 @@ void EventsMngr::NextParam()
|
||||
m_ParseVaultSize = INITIAL_PARSEVAULT_SIZE;
|
||||
|
||||
m_ParseVault = new MsgDataEntry[m_ParseVaultSize];
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
memcpy(m_ParseVault, tmp, tmpSize * sizeof(MsgDataEntry));
|
||||
@ -128,7 +135,6 @@ EventsMngr::~EventsMngr()
|
||||
clearEvents();
|
||||
}
|
||||
|
||||
|
||||
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
|
||||
{
|
||||
return m_Plugin;
|
||||
@ -170,7 +176,7 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
|
||||
|
||||
// rest of line
|
||||
tmpCond->sValue.assign(value);
|
||||
tmpCond->fValue = atof(value);
|
||||
tmpCond->fValue = static_cast<float>(atof(value));
|
||||
tmpCond->iValue = atoi(value);
|
||||
|
||||
tmpCond->next = NULL;
|
||||
@ -178,10 +184,11 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
|
||||
if (m_Conditions)
|
||||
{
|
||||
cond_t *tmp = m_Conditions;
|
||||
|
||||
while (tmp->next)
|
||||
tmp = tmp->next;
|
||||
tmp->next = tmpCond;
|
||||
|
||||
tmp->next = tmpCond;
|
||||
}
|
||||
else
|
||||
m_Conditions = tmpCond;
|
||||
@ -194,6 +201,7 @@ EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int
|
||||
return NULL;
|
||||
|
||||
ClEvent *event = new ClEvent(plugin, func, flags);
|
||||
|
||||
if (!event)
|
||||
return NULL;
|
||||
|
||||
@ -216,12 +224,11 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
||||
if (!m_Events[msg_type].size())
|
||||
return;
|
||||
|
||||
for(ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter)
|
||||
for (ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter).m_Done)
|
||||
continue;
|
||||
|
||||
|
||||
if (!(*iter).m_Plugin->isExecutable((*iter).m_Func))
|
||||
{
|
||||
(*iter).m_Done = true;
|
||||
@ -230,7 +237,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
||||
|
||||
if (pPlayer)
|
||||
{
|
||||
if (!(*iter).m_FlagPlayer || (pPlayer->IsAlive() ? !(*iter).m_FlagAlive : !(*iter).m_FlagDead ) )
|
||||
if (!(*iter).m_FlagPlayer || (pPlayer->IsAlive() ? !(*iter).m_FlagAlive : !(*iter).m_FlagDead))
|
||||
{
|
||||
(*iter).m_Done = true;
|
||||
continue;
|
||||
@ -247,6 +254,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
||||
(*iter).m_Done = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_ParseNotDone = true;
|
||||
}
|
||||
|
||||
@ -257,6 +265,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
||||
m_ParseVault[0].type = MSG_INTEGER;
|
||||
m_ParseVault[0].iValue = index;
|
||||
}
|
||||
|
||||
m_ParseFun = &m_Events[msg_type];
|
||||
}
|
||||
|
||||
@ -266,7 +275,6 @@ void EventsMngr::parseValue(int iValue)
|
||||
if (!m_ParseNotDone || !m_ParseFun)
|
||||
return;
|
||||
|
||||
|
||||
// grow if needed
|
||||
++m_ParsePos;
|
||||
NextParam();
|
||||
@ -284,23 +292,25 @@ void EventsMngr::parseValue(int iValue)
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
anyConditions = true;
|
||||
switch(condIter->type)
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (condIter->iValue == iValue) execute=true; break;
|
||||
case '!': if (condIter->iValue != iValue) execute=true; break;
|
||||
case '&': if (iValue & condIter->iValue) execute=true; break;
|
||||
case '<': if (iValue < condIter->iValue) execute=true; break;
|
||||
case '>': if (iValue > condIter->iValue) execute=true; break;
|
||||
case '=': if (condIter->iValue == iValue) execute = true; break;
|
||||
case '!': if (condIter->iValue != iValue) execute = true; break;
|
||||
case '&': if (iValue & condIter->iValue) execute = true; break;
|
||||
case '<': if (iValue < condIter->iValue) execute = true; break;
|
||||
case '>': if (iValue > condIter->iValue) execute = true; break;
|
||||
}
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
@ -312,7 +322,6 @@ void EventsMngr::parseValue(float fValue)
|
||||
if (!m_ParseNotDone || !m_ParseFun)
|
||||
return;
|
||||
|
||||
|
||||
// grow if needed
|
||||
++m_ParsePos;
|
||||
NextParam();
|
||||
@ -330,22 +339,25 @@ void EventsMngr::parseValue(float fValue)
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
anyConditions = true;
|
||||
switch(condIter->type)
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (condIter->fValue == fValue) execute=true; break;
|
||||
case '!': if (condIter->fValue != fValue) execute=true; break;
|
||||
case '<': if (fValue < condIter->fValue) execute=true; break;
|
||||
case '>': if (fValue > condIter->fValue) execute=true; break;
|
||||
case '=': if (condIter->fValue == fValue) execute = true; break;
|
||||
case '!': if (condIter->fValue != fValue) execute = true; break;
|
||||
case '<': if (fValue < condIter->fValue) execute = true; break;
|
||||
case '>': if (fValue > condIter->fValue) execute = true; break;
|
||||
}
|
||||
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
@ -374,21 +386,24 @@ void EventsMngr::parseValue(const char *sz)
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
anyConditions = true;
|
||||
switch(condIter->type)
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute=true; break;
|
||||
case '!': if (strcmp(sz, condIter->sValue.c_str())) execute=true; break;
|
||||
case '&': if (strstr(sz, condIter->sValue.c_str())) execute=true; break;
|
||||
case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
case '!': if (strcmp(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
case '&': if (strstr(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
}
|
||||
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
@ -403,11 +418,12 @@ void EventsMngr::executeEvents()
|
||||
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
if ( (*iter).m_Done )
|
||||
if ((*iter).m_Done)
|
||||
{
|
||||
(*iter).m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
||||
}
|
||||
@ -423,53 +439,53 @@ int EventsMngr::getArgNum() const
|
||||
|
||||
const char* EventsMngr::getArgString(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return "";
|
||||
|
||||
static char var[32];
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
sprintf( var, "%d", m_ParseVault[a].iValue );
|
||||
return var;
|
||||
case MSG_STRING:
|
||||
return m_ParseVault[a].sValue;
|
||||
default:
|
||||
sprintf( var, "%g", m_ParseVault[a].fValue );
|
||||
return var;
|
||||
case MSG_INTEGER:
|
||||
sprintf(var, "%d", m_ParseVault[a].iValue);
|
||||
return var;
|
||||
case MSG_STRING:
|
||||
return m_ParseVault[a].sValue;
|
||||
default:
|
||||
sprintf(var, "%g", m_ParseVault[a].fValue);
|
||||
return var;
|
||||
}
|
||||
}
|
||||
|
||||
int EventsMngr::getArgInteger(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return 0;
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atoi(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return (int)m_ParseVault[a].fValue;
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atoi(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return (int)m_ParseVault[a].fValue;
|
||||
}
|
||||
}
|
||||
|
||||
float EventsMngr::getArgFloat(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return 0.0f;
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atof(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return m_ParseVault[a].fValue;
|
||||
case MSG_INTEGER:
|
||||
return static_cast<float>(m_ParseVault[a].iValue);
|
||||
case MSG_STRING:
|
||||
return static_cast<float>(atof(m_ParseVault[a].sValue));
|
||||
default:
|
||||
return m_ParseVault[a].fValue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,6 +495,7 @@ void EventsMngr::clearEvents(void)
|
||||
{
|
||||
m_Events[i].clear();
|
||||
}
|
||||
|
||||
// delete parsevault
|
||||
if (m_ParseVault)
|
||||
{
|
||||
@ -497,25 +514,26 @@ int EventsMngr::getEventId(const char* msg)
|
||||
CS_EventsIds id;
|
||||
} table[] =
|
||||
{
|
||||
{ "CS_DeathMsg" , CS_DeathMsg },
|
||||
// { "CS_RoundEnd" , CS_RoundEnd },
|
||||
// { "CS_RoundStart" , CS_RoundStart },
|
||||
// { "CS_Restart" , CS_Restart },
|
||||
{ "" , CS_Null }
|
||||
{"CS_DeathMsg", CS_DeathMsg},
|
||||
// {"CS_RoundEnd", CS_RoundEnd},
|
||||
// {"CS_RoundStart", CS_RoundStart},
|
||||
// {"CS_Restart", CS_Restart},
|
||||
{"", CS_Null}
|
||||
};
|
||||
|
||||
// if msg is a number, return it
|
||||
int pos = atoi(msg);
|
||||
|
||||
if (pos != 0)
|
||||
return pos;
|
||||
|
||||
// try to find in table first
|
||||
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
|
||||
if ( !strcmp( table[ pos ].name , msg ) )
|
||||
return table[ pos ].id;
|
||||
for (pos = 0; table[pos].id != CS_Null; ++pos)
|
||||
if (!strcmp(table[pos].name, msg))
|
||||
return table[pos].id;
|
||||
|
||||
// find the id of the message
|
||||
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
|
||||
return pos = GET_USER_MSG_ID(PLID, msg, 0);
|
||||
}
|
||||
|
||||
int EventsMngr::getCurrentMsgType()
|
||||
|
@ -32,9 +32,10 @@
|
||||
#ifndef __CEVENTS_H__
|
||||
#define __CEVENTS_H__
|
||||
|
||||
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
|
||||
#define MAX_AMX_REG_MSG MAX_REG_MSGS + 16
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CS_DEATHMSG = MAX_REG_MSGS,
|
||||
// CS_ROUNDEND,
|
||||
// CS_ROUNDSTART,
|
||||
@ -67,7 +68,7 @@ public:
|
||||
|
||||
class ClEvent
|
||||
{
|
||||
friend class EventsMngr; // events manager may access our private members
|
||||
friend class EventsMngr; // events manager may access our private members
|
||||
|
||||
int m_Func; // function to be executed
|
||||
CPluginMngr::CPlugin *m_Plugin; // the plugin this ClEvent class is assigned to
|
||||
@ -100,7 +101,7 @@ public:
|
||||
|
||||
public:
|
||||
// constructors & destructors
|
||||
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||
~ClEvent();
|
||||
|
||||
inline CPluginMngr::CPlugin* getPlugin();
|
||||
@ -116,21 +117,22 @@ private:
|
||||
const char* sValue;
|
||||
MsgParamType type;
|
||||
};
|
||||
|
||||
MsgDataEntry *m_ParseVault;
|
||||
int m_ParseVaultSize;
|
||||
void NextParam(); // make sure a new parameter can be added
|
||||
void NextParam(); // make sure a new parameter can be added
|
||||
|
||||
typedef CList<ClEvent> ClEventVec;
|
||||
typedef ClEventVec::iterator ClEventVecIter;
|
||||
|
||||
ClEventVec m_Events[MAX_AMX_REG_MSG];
|
||||
ClEventVec *m_ParseFun; // current Event vector
|
||||
ClEventVec *m_ParseFun; // current Event vector
|
||||
|
||||
bool m_ParseNotDone;
|
||||
int m_ParsePos; // is args. num. - 1
|
||||
float* m_Timer;
|
||||
|
||||
ClEvent* getValidEvent(ClEvent* a );
|
||||
ClEvent* getValidEvent(ClEvent* a);
|
||||
|
||||
int m_CurrentMsgType;
|
||||
public:
|
||||
@ -140,20 +142,20 @@ public:
|
||||
// Interface
|
||||
|
||||
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
|
||||
|
||||
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
|
||||
void parseValue(int iValue);
|
||||
void parseValue(float fValue);
|
||||
void parseValue(const char *sz);
|
||||
void executeEvents();
|
||||
int getArgNum() const; //{ return (parsePos+1); }
|
||||
|
||||
int getArgNum() const; //{ return (parsePos + 1); }
|
||||
const char* getArgString(int a) const;
|
||||
int getArgInteger(int a) const;
|
||||
float getArgFloat(int a) const;
|
||||
void clearEvents(void);
|
||||
static int getEventId( const char* msg );
|
||||
static int getEventId(const char* msg);
|
||||
int getCurrentMsgType();
|
||||
};
|
||||
|
||||
#endif // #ifdef __CEVENTS_H__
|
||||
|
||||
|
||||
#endif //__CEVENTS_H__
|
||||
|
@ -36,91 +36,91 @@
|
||||
// *****************************************************
|
||||
// class File
|
||||
// *****************************************************
|
||||
File::File( const char* n, const char* m )
|
||||
|
||||
File::File(const char* n, const char* m)
|
||||
{
|
||||
fp = fopen( n , m );
|
||||
fp = fopen(n, m);
|
||||
}
|
||||
|
||||
File::~File( )
|
||||
File::~File()
|
||||
{
|
||||
if ( fp )
|
||||
fclose( fp );
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
File::operator bool ( ) const
|
||||
File::operator bool () const
|
||||
{
|
||||
return fp && !feof(fp);
|
||||
return fp && !feof(fp);
|
||||
}
|
||||
|
||||
File& operator<<( File& f, const String& n )
|
||||
File& operator<<(File& f, const String& n)
|
||||
{
|
||||
if ( f ) fputs( n.c_str() , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputs(n.c_str(), f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator<<( File& f, const char* n )
|
||||
File& operator<<(File& f, const char* n)
|
||||
{
|
||||
if ( f ) fputs( n , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputs(n, f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator<<( File& f, int n )
|
||||
File& operator<<(File& f, int n)
|
||||
{
|
||||
if ( f ) fprintf( f.fp , "%d" , n ) ;
|
||||
return f;
|
||||
if (f) fprintf(f.fp, "%d", n);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
File& operator<<( File& f, const char& c )
|
||||
File& operator<<(File& f, const char& c)
|
||||
{
|
||||
if ( f ) fputc( c , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputc(c, f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator>>( File& f, String& n )
|
||||
File& operator>>(File& f, String& n)
|
||||
{
|
||||
if ( !f ) return f;
|
||||
char temp[1024];
|
||||
fscanf( f.fp , "%s", temp );
|
||||
n.assign(temp);
|
||||
return f;
|
||||
if (!f) return f;
|
||||
char temp[1024];
|
||||
fscanf(f.fp, "%s", temp);
|
||||
n.assign(temp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator>>( File& f, char* n )
|
||||
File& operator>>(File& f, char* n)
|
||||
{
|
||||
if ( f ) fscanf( f.fp , "%s", n );
|
||||
return f;
|
||||
if (f) fscanf(f.fp, "%s", n);
|
||||
return f;
|
||||
}
|
||||
|
||||
int File::getline( char* buf, int sz )
|
||||
int File::getline(char* buf, int sz)
|
||||
{
|
||||
int a = sz;
|
||||
char *origBuf = buf;
|
||||
if ( *this )
|
||||
{
|
||||
int c;
|
||||
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
|
||||
*buf++ = c;
|
||||
*buf = 0;
|
||||
}
|
||||
int a = sz;
|
||||
char *origBuf = buf;
|
||||
|
||||
// trim 0x0a and 0x0d characters at the end
|
||||
while (buf != origBuf)
|
||||
{
|
||||
if (*buf == 0x0a || *buf == 0x0d)
|
||||
if (*this)
|
||||
{
|
||||
int c;
|
||||
while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
|
||||
*buf++ = c;
|
||||
*buf = 0;
|
||||
--buf;
|
||||
}
|
||||
}
|
||||
|
||||
return a - sz;
|
||||
// trim 0x0a and 0x0d characters at the end
|
||||
while (buf != origBuf)
|
||||
{
|
||||
if (*buf == 0x0a || *buf == 0x0d)
|
||||
*buf = 0;
|
||||
--buf;
|
||||
}
|
||||
|
||||
return a - sz;
|
||||
}
|
||||
|
||||
File& File::skipWs( )
|
||||
File& File::skipWs()
|
||||
{
|
||||
if ( !*this ) return *this;
|
||||
int c;
|
||||
while( isspace( c = getc( fp ) ) ){};
|
||||
ungetc( c , fp );
|
||||
return *this;
|
||||
if (!*this) return *this;
|
||||
int c;
|
||||
while (isspace(c = getc(fp))) {};
|
||||
ungetc(c, fp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -41,18 +41,19 @@ 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( );
|
||||
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();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -30,19 +30,21 @@
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
void AMXAPI amxx_InvalidateTrace(AMX *amx);
|
||||
#include "debugger.h"
|
||||
|
||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
m_FuncName = name;
|
||||
m_ExecType = et;
|
||||
m_NumParams = numParams;
|
||||
|
||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||
|
||||
// find funcs
|
||||
int func;
|
||||
AMXForward *tmp = NULL;
|
||||
m_Funcs.clear();
|
||||
|
||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
||||
@ -74,67 +76,73 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
{
|
||||
// Get debug info
|
||||
AMX *amx = (*iter).pPlugin->getAMX();
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||
if (pInfo)
|
||||
pInfo->error = AMX_ERR_NONE;
|
||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
|
||||
// handle strings & arrays
|
||||
int i, ax=0;
|
||||
int i, ax = 0;
|
||||
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(iter->pPlugin->getAMX(),
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(amx, preparedArrays[params[i]].size,
|
||||
&realParams[i], &tmp);
|
||||
amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
||||
physAddrs[i] = tmp;
|
||||
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
|
||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||
for (i = m_NumParams-1; i >= 0; i--)
|
||||
{
|
||||
amx_Push(amx, realParams[i]);
|
||||
}
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
int err = amx_Exec(amx, &retVal, iter->func);
|
||||
|
||||
// log runtime error, if any
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||
if (pDebugger && pDebugger->ErrorExists())
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
} else {
|
||||
}
|
||||
else if (err != -1)
|
||||
{
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(amx, err, "");
|
||||
LogError(amx, err, NULL);
|
||||
}
|
||||
}
|
||||
amxx_InvalidateTrace(amx);
|
||||
|
||||
amx->error = AMX_ERR_NONE;
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->EndExec();
|
||||
|
||||
// cleanup strings & arrays
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
@ -157,10 +165,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||
}
|
||||
@ -172,24 +179,25 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
// decide what to do (based on exectype and retval)
|
||||
switch (m_ExecType)
|
||||
{
|
||||
case ET_IGNORE:
|
||||
break;
|
||||
case ET_STOP:
|
||||
if (retVal > 0)
|
||||
return retVal;
|
||||
case ET_STOP2:
|
||||
if (retVal == 1)
|
||||
return 1;
|
||||
else if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
case ET_CONTINUE:
|
||||
if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
case ET_IGNORE:
|
||||
break;
|
||||
case ET_STOP:
|
||||
if (retVal > 0)
|
||||
return retVal;
|
||||
case ET_STOP2:
|
||||
if (retVal == 1)
|
||||
return 1;
|
||||
else if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
case ET_CONTINUE:
|
||||
if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return globRetVal;
|
||||
}
|
||||
|
||||
@ -229,62 +237,66 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
if (!pPlugin->isExecutable(m_Func))
|
||||
return 0;
|
||||
|
||||
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]);
|
||||
if (pInfo)
|
||||
pInfo->error = AMX_ERR_NONE;
|
||||
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
|
||||
// handle strings & arrays
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(m_Amx,
|
||||
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||
&realParams[i], &tmp);
|
||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(m_Amx, preparedArrays[params[i]].size,
|
||||
&realParams[i], &tmp);
|
||||
amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
||||
physAddrs[i] = tmp;
|
||||
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
for (i=m_NumParams-1; i>=0; i--)
|
||||
|
||||
for (i = m_NumParams - 1; i >= 0; i--)
|
||||
amx_Push(m_Amx, realParams[i]);
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||
if (pDebugger && pDebugger->ErrorExists())
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
} else {
|
||||
}
|
||||
else if (err != -1)
|
||||
{
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(m_Amx, err, "");
|
||||
LogError(m_Amx, err, NULL);
|
||||
}
|
||||
}
|
||||
amxx_InvalidateTrace(m_Amx);
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->EndExec();
|
||||
|
||||
m_Amx->error = AMX_ERR_NONE;
|
||||
|
||||
// cleanup strings & arrays
|
||||
@ -309,10 +321,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||
}
|
||||
@ -328,9 +339,12 @@ int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int
|
||||
{
|
||||
int retVal = m_Forwards.size() << 1;
|
||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
||||
|
||||
if (!tmp)
|
||||
return -1; // should be invalid
|
||||
|
||||
m_Forwards.push_back(tmp);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -338,22 +352,26 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
|
||||
{
|
||||
int retVal = -1;
|
||||
CSPForward *pForward;
|
||||
|
||||
if (!m_FreeSPForwards.empty())
|
||||
{
|
||||
retVal = m_FreeSPForwards.front();
|
||||
pForward = m_SPForwards[retVal >> 1];
|
||||
pForward->Set(func, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
return -1;
|
||||
|
||||
m_FreeSPForwards.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
retVal = (m_SPForwards.size() << 1) | 1;
|
||||
pForward = new CSPForward();
|
||||
|
||||
if (!pForward)
|
||||
return -1;
|
||||
|
||||
pForward->Set(func, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
{
|
||||
return -1;
|
||||
@ -362,6 +380,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
|
||||
|
||||
m_SPForwards.push_back(pForward);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -369,56 +388,58 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
|
||||
{
|
||||
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||
CSPForward *pForward;
|
||||
|
||||
if (!m_FreeSPForwards.empty())
|
||||
{
|
||||
retVal = m_FreeSPForwards.front();
|
||||
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
|
||||
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
|
||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
return -1;
|
||||
|
||||
m_FreeSPForwards.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pForward = new CSPForward();
|
||||
|
||||
if (!pForward)
|
||||
return -1;
|
||||
|
||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
{
|
||||
delete pForward;
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_SPForwards.push_back(pForward);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool CForwardMngr::isIdValid(int id) const
|
||||
{
|
||||
return (id >= 0) && ((id & 1) ?
|
||||
(static_cast<size_t>(id >> 1) < m_SPForwards.size()) :
|
||||
(static_cast<size_t>(id >> 1) < m_Forwards.size()));
|
||||
return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
|
||||
}
|
||||
|
||||
cell CForwardMngr::executeForwards(int id, cell *params)
|
||||
{
|
||||
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) :
|
||||
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||
m_TmpArraysNum = 0;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int CForwardMngr::getParamsNum(int id) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() :
|
||||
m_Forwards[id >> 1]->getParamsNum();
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
|
||||
}
|
||||
|
||||
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) :
|
||||
m_Forwards[id >> 1]->getParamType(paramNum);
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
||||
}
|
||||
|
||||
void CForwardMngr::clear()
|
||||
@ -427,7 +448,9 @@ void CForwardMngr::clear()
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
SPForwardVec::iterator spIter;
|
||||
|
||||
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
||||
{
|
||||
delete (*spIter);
|
||||
@ -435,8 +458,10 @@ void CForwardMngr::clear()
|
||||
|
||||
m_Forwards.clear();
|
||||
m_SPForwards.clear();
|
||||
|
||||
while (!m_FreeSPForwards.empty())
|
||||
m_FreeSPForwards.pop();
|
||||
|
||||
m_TmpArraysNum = 0;
|
||||
}
|
||||
|
||||
@ -448,74 +473,97 @@ bool CForwardMngr::isSPForward(int id) const
|
||||
void CForwardMngr::unregisterSPForward(int id)
|
||||
{
|
||||
//make sure the id is valid
|
||||
if ( !isIdValid(id) || m_SPForwards.at(id >> 1)->isFree )
|
||||
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
||||
return;
|
||||
|
||||
m_SPForwards.at(id >> 1)->isFree = true;
|
||||
|
||||
m_FreeSPForwards.push(id);
|
||||
}
|
||||
|
||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, et);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerForward(funcName, et, curParam, params);
|
||||
}
|
||||
|
||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, funcName);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
||||
}
|
||||
|
||||
int registerSPForward(AMX *amx, int func, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, func);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerSPForward(func, amx, curParam, params);
|
||||
}
|
||||
|
||||
@ -525,9 +573,12 @@ cell executeForwards(int id, ...)
|
||||
return -1;
|
||||
|
||||
cell params[FORWARD_MAX_PARAMS];
|
||||
|
||||
int paramsNum = g_forwards.getParamsNum(id);
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, id);
|
||||
|
||||
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
||||
{
|
||||
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
||||
@ -538,7 +589,9 @@ cell executeForwards(int id, ...)
|
||||
else
|
||||
params[i] = (cell)va_arg(argptr, cell);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.executeForwards(id, params);
|
||||
}
|
||||
|
||||
@ -546,13 +599,16 @@ cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemTy
|
||||
{
|
||||
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
||||
{
|
||||
#ifdef MEMORY_TEST
|
||||
#ifdef MEMORY_TEST
|
||||
m_validateAllAllocUnits();
|
||||
#endif // MEMORY_TEST
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
||||
m_TmpArraysNum = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
||||
m_TmpArrays[m_TmpArraysNum].size = size;
|
||||
m_TmpArrays[m_TmpArraysNum].type = type;
|
||||
|
@ -77,7 +77,9 @@ enum ForwardArrayElemType
|
||||
struct ForwardPreparedArray
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ForwardArrayElemType type;
|
||||
|
||||
unsigned int size;
|
||||
bool copyBack;
|
||||
};
|
||||
@ -88,31 +90,39 @@ class CForward
|
||||
const char *m_FuncName;
|
||||
ForwardExecType m_ExecType;
|
||||
int m_NumParams;
|
||||
|
||||
struct AMXForward
|
||||
{
|
||||
CPluginMngr::CPlugin *pPlugin;
|
||||
int func;
|
||||
};
|
||||
|
||||
typedef CVector<AMXForward> AMXForwardList;
|
||||
|
||||
AMXForwardList m_Funcs;
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
|
||||
public:
|
||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
|
||||
CForward()
|
||||
{ } // leaves everything unitialized'
|
||||
CForward() {} // leaves everything unitialized'
|
||||
|
||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||
|
||||
int getParamsNum() const
|
||||
{
|
||||
return m_NumParams;
|
||||
}
|
||||
|
||||
int getFuncsNum() const
|
||||
{
|
||||
return m_Funcs.size();
|
||||
}
|
||||
|
||||
ForwardParam getParamType(int paramId) const
|
||||
{
|
||||
if (paramId < 0 || paramId >= m_NumParams)
|
||||
return FP_DONE;
|
||||
|
||||
return m_ParamTypes[paramId];
|
||||
}
|
||||
};
|
||||
@ -122,10 +132,13 @@ class CSPForward
|
||||
{
|
||||
const char *m_FuncName;
|
||||
int m_NumParams;
|
||||
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
AMX *m_Amx;
|
||||
|
||||
int m_Func;
|
||||
bool m_HasFunc;
|
||||
|
||||
public:
|
||||
bool isFree;
|
||||
public:
|
||||
@ -134,18 +147,22 @@ public:
|
||||
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
|
||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||
|
||||
int getParamsNum() const
|
||||
{
|
||||
return m_NumParams;
|
||||
}
|
||||
|
||||
int getFuncsNum() const
|
||||
{
|
||||
return (m_HasFunc) ? 1 : 0;
|
||||
}
|
||||
|
||||
ForwardParam getParamType(int paramId) const
|
||||
{
|
||||
if (paramId < 0 || paramId >= m_NumParams)
|
||||
return FP_DONE;
|
||||
|
||||
return m_ParamTypes[paramId];
|
||||
}
|
||||
};
|
||||
@ -154,21 +171,20 @@ class CForwardMngr
|
||||
{
|
||||
typedef CVector<CForward*> ForwardVec;
|
||||
typedef CVector<CSPForward*> SPForwardVec;
|
||||
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
||||
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
||||
|
||||
ForwardVec m_Forwards;
|
||||
|
||||
SPForwardVec m_SPForwards;
|
||||
FreeSPVec m_FreeSPForwards; // so we don't have to free memory
|
||||
|
||||
ForwardPreparedArray m_TmpArrays[FORWARD_MAX_PARAMS]; // used by prepareArray
|
||||
ForwardPreparedArray m_TmpArrays[FORWARD_MAX_PARAMS]; // used by prepareArray
|
||||
int m_TmpArraysNum;
|
||||
public:
|
||||
|
||||
CForwardMngr()
|
||||
{ m_TmpArraysNum = 0; }
|
||||
~CForwardMngr()
|
||||
{ }
|
||||
~CForwardMngr() {}
|
||||
|
||||
// Interface
|
||||
// Register normal forward
|
||||
@ -176,18 +192,21 @@ public:
|
||||
// Register single plugin forward
|
||||
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
|
||||
// Unregister single plugin forward
|
||||
void unregisterSPForward(int id);
|
||||
|
||||
// execute forward
|
||||
cell executeForwards(int id, cell *params);
|
||||
void clear(); // delete all forwards
|
||||
void clear(); // delete all forwards
|
||||
|
||||
bool isIdValid(int id) const; // check whether forward id is valid
|
||||
bool isSPForward(int id) const; // check whether forward is single plugin
|
||||
int getParamsNum(int id) const; // get num of params of a forward
|
||||
int getFuncsNum(int id) const; // get num of found functions of a forward
|
||||
|
||||
ForwardParam getParamType(int id, int paramId) const;
|
||||
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type,
|
||||
bool copyBack); // prepare array
|
||||
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
|
||||
};
|
||||
|
||||
// (un)register forward
|
||||
@ -202,5 +221,4 @@ cell executeForwards(int id, ...);
|
||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
|
||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
|
||||
|
||||
#endif
|
||||
|
||||
#endif //FORWARD_H
|
||||
|
@ -157,7 +157,7 @@ size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
|
||||
int flag = 0;
|
||||
size_t strln = strlen(str);
|
||||
|
||||
for (i=strln-1; i>=0; i--)
|
||||
for (i = strln - 1; i >= 0; i--)
|
||||
{
|
||||
if (str[i] == '\n' || str[i] == ' ' || str[i] == '\t')
|
||||
{
|
||||
@ -184,6 +184,7 @@ size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
|
||||
}
|
||||
|
||||
newstr[pos] = 0;
|
||||
|
||||
return ptr - str + 1;
|
||||
}
|
||||
|
||||
@ -279,7 +280,7 @@ CLangMngr::CLang::CLang(const char *lang)
|
||||
{
|
||||
m_LookUpTable.clear();
|
||||
strncpy(m_LanguageName, lang, 2);
|
||||
m_LanguageName[2]=0;
|
||||
m_LanguageName[2] = 0;
|
||||
}
|
||||
|
||||
CLangMngr::CLang::LangEntry *CLangMngr::CLang::AddEntry(int pKey, uint32_t defHash, const char *def, bool cache)
|
||||
@ -300,11 +301,12 @@ CLangMngr::CLang::~CLang()
|
||||
|
||||
void CLangMngr::CLang::Clear()
|
||||
{
|
||||
for (unsigned int i=0; i<m_LookUpTable.size(); i++)
|
||||
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
|
||||
{
|
||||
if (m_LookUpTable[i])
|
||||
delete m_LookUpTable[i];
|
||||
}
|
||||
|
||||
m_LookUpTable.clear();
|
||||
}
|
||||
|
||||
@ -312,7 +314,7 @@ CLangMngr::CLang::LangEntry * CLangMngr::CLang::GetEntry(int pkey)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<m_LookUpTable.size(); i++)
|
||||
for (i = 0; i < m_LookUpTable.size(); i++)
|
||||
{
|
||||
if (m_LookUpTable[i]->GetKey() == pkey)
|
||||
{
|
||||
@ -332,11 +334,13 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
|
||||
{
|
||||
const char *def = 0;
|
||||
int key = -1;
|
||||
|
||||
while (!vec.empty())
|
||||
{
|
||||
key = vec.front()->key;
|
||||
def = vec.front()->def->c_str();
|
||||
LangEntry *entry = GetEntry(key);
|
||||
|
||||
if (entry->GetDefHash() != MakeHash(def))
|
||||
{
|
||||
if (entry->GetCache())
|
||||
@ -348,6 +352,7 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
|
||||
//AMXXLOG_Log("[AMXX] Language key %s[%s] defined twice", m_LMan->GetKey(key), m_LanguageName);
|
||||
}
|
||||
}
|
||||
|
||||
delete vec.front();
|
||||
vec.pop();
|
||||
}
|
||||
@ -357,20 +362,22 @@ const char * CLangMngr::CLang::GetDef(const char *key)
|
||||
{
|
||||
static char nfind[1024] = "ML_NOTFOUND(KEY)";
|
||||
int ikey = m_LMan->GetKeyEntry(key);
|
||||
|
||||
if (ikey == -1)
|
||||
{
|
||||
sprintf(nfind, "ML_NOTFOUND: %s", key);
|
||||
return nfind;
|
||||
}
|
||||
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
||||
|
||||
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
|
||||
{
|
||||
if (m_LookUpTable[i]->GetKey() == ikey)
|
||||
return m_LookUpTable[i]->GetDef();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct OffsetPair
|
||||
{
|
||||
uint32_t defOffset;
|
||||
@ -381,7 +388,8 @@ struct OffsetPair
|
||||
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
|
||||
{
|
||||
unsigned short defLen = 0;
|
||||
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
||||
|
||||
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
|
||||
{
|
||||
defLen = m_LookUpTable[i]->GetDefLength();
|
||||
fwrite((void *)&defLen, sizeof(unsigned short), 1, fp);
|
||||
@ -403,7 +411,7 @@ bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
|
||||
fwrite((void*)&size, sizeof(uint32_t), 1, fp);
|
||||
curOffset += sizeof(uint32_t);
|
||||
|
||||
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
||||
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
|
||||
{
|
||||
keynum = m_LookUpTable[i]->GetKey();
|
||||
defhash = m_LookUpTable[i]->GetDefHash();
|
||||
@ -423,7 +431,6 @@ bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
|
||||
// assumes fp is set to the right position
|
||||
bool CLangMngr::CLang::Load(FILE *fp)
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -461,9 +468,10 @@ int CLangMngr::GetKeyEntry(const char *key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i<KeyList.size(); i++)
|
||||
for (i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
cmpKey = KeyList[i]->hash;
|
||||
|
||||
if (hKey == cmpKey)
|
||||
{
|
||||
return i;
|
||||
@ -490,7 +498,7 @@ int CLangMngr::GetKeyEntry(String &key)
|
||||
uint32_t hKey = MakeHash(key.c_str(), true);
|
||||
unsigned int i = 0;
|
||||
|
||||
for (i = 0; i<KeyList.size(); i++)
|
||||
for (i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
if (hKey == KeyList[i]->hash)
|
||||
{
|
||||
@ -521,6 +529,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
{
|
||||
// number of parameters ( for NEXT_PARAM macro )
|
||||
int paramCount = *params / sizeof(cell);
|
||||
|
||||
// the output buffer
|
||||
static char outbuf[4096];
|
||||
char *outptr = outbuf;
|
||||
@ -531,13 +540,14 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
if (*src == '%')
|
||||
{
|
||||
++src;
|
||||
if (*src=='L')
|
||||
if (*src == 'L')
|
||||
{
|
||||
cell langName = params[parm]; // "en" case (langName contains the address to the string)
|
||||
NEXT_PARAM();
|
||||
cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases
|
||||
const char *cpLangName=NULL;
|
||||
// Handle player ids (1-32) and server language
|
||||
|
||||
if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER
|
||||
{
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
||||
@ -546,9 +556,13 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
} else {
|
||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
|
||||
}
|
||||
} else if (*pAmxLangName == LANG_SERVER) { // LANG_SERVER
|
||||
}
|
||||
else if (*pAmxLangName == LANG_SERVER) // LANG_SERVER
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) { // Direct Client Id
|
||||
}
|
||||
else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) // Direct Client Id
|
||||
{
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
@ -559,30 +573,34 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
int tmplen = 0;
|
||||
cpLangName = get_amxstring(amx, langName, 2, tmplen);
|
||||
}
|
||||
|
||||
if (!cpLangName || strlen(cpLangName) < 1)
|
||||
cpLangName = "en";
|
||||
|
||||
int tmplen = 0;
|
||||
NEXT_PARAM();
|
||||
char *key = get_amxstring(amx, params[parm++], 1, tmplen);
|
||||
const char *def = GetDef(cpLangName, key);
|
||||
|
||||
if (def == NULL)
|
||||
{
|
||||
if (*pAmxLangName != LANG_SERVER)
|
||||
{
|
||||
def = GetDef(g_vault.get("server_language"), key);
|
||||
}
|
||||
if (strcmp(cpLangName, "en")!=0 && strcmp(g_vault.get("server_language"), "en")!=0)
|
||||
if (strcmp(cpLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0)
|
||||
{
|
||||
def = GetDef("en", key);
|
||||
}
|
||||
if (!def)
|
||||
{
|
||||
static char buf[512];
|
||||
CHECK_PTR((char*)(buf+17+strlen(key)), buf, sizeof(buf));
|
||||
CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
|
||||
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
||||
def = buf;
|
||||
}
|
||||
}
|
||||
|
||||
while (*def)
|
||||
{
|
||||
if (*def == '%')
|
||||
@ -592,159 +610,159 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
{
|
||||
*outptr++ = '%';
|
||||
++def;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
static char format[32];
|
||||
format[0] = '%';
|
||||
char *ptr = format+1;
|
||||
char *ptr = format + 1;
|
||||
|
||||
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
||||
/*nothing*/;
|
||||
ZEROTERM(format);
|
||||
|
||||
*ptr = 0;
|
||||
switch ( *(ptr-1) )
|
||||
|
||||
switch (*(ptr - 1))
|
||||
{
|
||||
case 's':
|
||||
case 's':
|
||||
{
|
||||
static char tmpString[4096];
|
||||
char *tmpPtr = tmpString;
|
||||
NEXT_PARAM();
|
||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||
while (tmpPtr-tmpString < sizeof(tmpString) && *tmpCell)
|
||||
*tmpPtr++ = *tmpCell++;
|
||||
|
||||
*tmpPtr++ = static_cast<char>(*tmpCell++);
|
||||
*tmpPtr = 0;
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
case 'g':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'f':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'c':
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'c':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
default:
|
||||
{
|
||||
CHECK_OUTPTR(strlen(format)+1);
|
||||
CHECK_OUTPTR(strlen(format) + 1);
|
||||
strcpy(outptr, format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
outptr += strlen(outptr);
|
||||
}
|
||||
}
|
||||
else if (*def == '^')
|
||||
{
|
||||
++def;
|
||||
|
||||
switch (*def)
|
||||
{
|
||||
case 'n':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\t';
|
||||
break;
|
||||
case '^':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '^';
|
||||
break;
|
||||
default:
|
||||
CHECK_OUTPTR(2);
|
||||
*outptr++ = '^';
|
||||
*outptr++ = *def;
|
||||
break;
|
||||
case 'n':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\t';
|
||||
break;
|
||||
case '^':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '^';
|
||||
break;
|
||||
default:
|
||||
CHECK_OUTPTR(2);
|
||||
*outptr++ = '^';
|
||||
*outptr++ = *def;
|
||||
break;
|
||||
}
|
||||
|
||||
++def;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = *def++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
static char tmpString[4096];
|
||||
char *tmpPtr = tmpString;
|
||||
int tmpLen = 0;
|
||||
static char format[32] = {'%'};
|
||||
char *ptr = format+1;
|
||||
char *ptr = format + 1;
|
||||
|
||||
if (*src != '%')
|
||||
{
|
||||
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = *src++))
|
||||
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = static_cast<char>(*src++)))
|
||||
/*nothing*/;
|
||||
*ptr = 0;
|
||||
ZEROTERM(format);
|
||||
--src;
|
||||
switch ( *(ptr-1) )
|
||||
|
||||
switch (*(ptr - 1))
|
||||
{
|
||||
case 's':
|
||||
case 's':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||
while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell)
|
||||
*tmpPtr++ = *tmpCell++;
|
||||
*tmpPtr++ = static_cast<char>(*tmpCell++);
|
||||
*tmpPtr = 0;
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
||||
ZEROTERM(outbuf);
|
||||
break;
|
||||
}
|
||||
case 'g':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'f':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'c':
|
||||
case 'i':
|
||||
case 'd':
|
||||
case 'c':
|
||||
{
|
||||
NEXT_PARAM();
|
||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
default:
|
||||
{
|
||||
CHECK_OUTPTR(strlen(format)+1);
|
||||
CHECK_OUTPTR(strlen(format) + 1);
|
||||
strcpy(outptr, format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
outptr += strlen(outptr);
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = *src;
|
||||
*outptr++ = static_cast<char>(*src);
|
||||
}
|
||||
++src;
|
||||
}
|
||||
|
||||
len = outptr - outbuf;
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = 0;
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
@ -754,6 +772,7 @@ const char *CLangMngr::Format(const char *fmt, ...)
|
||||
va_start(ap, fmt);
|
||||
const char *retVal = FormatString(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -782,12 +801,13 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
if (*src == '%')
|
||||
{
|
||||
++src;
|
||||
if (*src=='L')
|
||||
if (*src == 'L')
|
||||
{
|
||||
NEXT_PARAM();
|
||||
const char *pAmxLangName = va_arg(ap, const char*);
|
||||
const char *cpLangName=NULL;
|
||||
// Handle player ids (1-32) and server language
|
||||
|
||||
if (pAmxLangName == (const char *)LANG_PLAYER) // LANG_PLAYER
|
||||
{
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||
@ -796,9 +816,13 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
} else {
|
||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
|
||||
}
|
||||
} else if (pAmxLangName == (const char *)LANG_SERVER) { // LANG_SERVER
|
||||
}
|
||||
else if (pAmxLangName == (const char *)LANG_SERVER) // LANG_SERVER
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
} else if (pAmxLangName >= (const char *)1 && pAmxLangName <= (const char *)32) { // Direct Client Id
|
||||
}
|
||||
else if (pAmxLangName >= (const char *)1 && pAmxLangName <= (const char *)32) // Direct Client Id
|
||||
{
|
||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||
{
|
||||
cpLangName = g_vault.get("server_language");
|
||||
@ -809,29 +833,33 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
int tmplen = 0;
|
||||
cpLangName = pAmxLangName;
|
||||
}
|
||||
|
||||
if (!cpLangName || strlen(cpLangName) < 1)
|
||||
cpLangName = "en";
|
||||
|
||||
int tmplen = 0;
|
||||
const char *key = va_arg(ap, const char *);
|
||||
const char *def = GetDef(cpLangName, key);
|
||||
|
||||
if (def == NULL)
|
||||
{
|
||||
if (pAmxLangName != LANG_SERVER)
|
||||
{
|
||||
def = GetDef(g_vault.get("server_language"), key);
|
||||
}
|
||||
if (strcmp(cpLangName, "en")!=0 && strcmp(g_vault.get("server_language"), "en")!=0)
|
||||
if (strcmp(cpLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0)
|
||||
{
|
||||
def = GetDef("en", key);
|
||||
}
|
||||
if (!def)
|
||||
{
|
||||
static char buf[512];
|
||||
CHECK_PTR((char*)(buf+17+strlen(key)), buf, sizeof(buf));
|
||||
CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
|
||||
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
||||
def = buf;
|
||||
}
|
||||
}
|
||||
|
||||
while (*def)
|
||||
{
|
||||
if (*def == '%')
|
||||
@ -839,7 +867,7 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
++def;
|
||||
static char format[32];
|
||||
format[0] = '%';
|
||||
char *ptr = format+1;
|
||||
char *ptr = format + 1;
|
||||
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
||||
/*nothing*/;
|
||||
ZEROTERM(format);
|
||||
@ -847,8 +875,72 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
*ptr = 0;
|
||||
vsprintf(outptr, format, ap);
|
||||
// vsprintf doesnt alter the ap, increment here
|
||||
switch (*(ptr-1))
|
||||
|
||||
switch (*(ptr - 1))
|
||||
{
|
||||
case 'f':
|
||||
va_arg(ap, double);
|
||||
break;
|
||||
case 's':
|
||||
va_arg(ap, char *);
|
||||
break;
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'i':
|
||||
default: // default: assume int-like parameter
|
||||
va_arg(ap, int);
|
||||
break;
|
||||
}
|
||||
|
||||
outptr += strlen(outptr);
|
||||
}
|
||||
else if (*def == '^')
|
||||
{
|
||||
++def;
|
||||
|
||||
switch (*def)
|
||||
{
|
||||
case 'n':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\t';
|
||||
break;
|
||||
case '^':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '^';
|
||||
break;
|
||||
default:
|
||||
CHECK_OUTPTR(2);
|
||||
*outptr++ = '^';
|
||||
*outptr++ = *def;
|
||||
break;
|
||||
}
|
||||
|
||||
++def;
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = *def++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
static char format[32] = {'%'};
|
||||
char *ptr = format + 1;
|
||||
|
||||
if (*src != '%')
|
||||
{
|
||||
while (*src != 0 && ptr-format < sizeof(format) && !isalpha(*ptr++ = *src++))
|
||||
/*nothing*/;
|
||||
*ptr = 0;
|
||||
ZEROTERM(format);
|
||||
--src;
|
||||
vsprintf(outptr, format, ap);
|
||||
// vsprintf doesnt alter the ap, increment here
|
||||
|
||||
switch (*(ptr - 1))
|
||||
{
|
||||
case 'f':
|
||||
va_arg(ap, double);
|
||||
break;
|
||||
@ -861,87 +953,27 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
||||
default: // default: assume int-like parameter
|
||||
va_arg(ap, int);
|
||||
break;
|
||||
}
|
||||
outptr += strlen(outptr);
|
||||
}
|
||||
else if (*def == '^')
|
||||
{
|
||||
++def;
|
||||
switch (*def)
|
||||
{
|
||||
case 'n':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\n';
|
||||
break;
|
||||
case 't':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '\t';
|
||||
break;
|
||||
case '^':
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '^';
|
||||
break;
|
||||
default:
|
||||
CHECK_OUTPTR(2);
|
||||
*outptr++ = '^';
|
||||
*outptr++ = *def;
|
||||
break;
|
||||
}
|
||||
++def;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = *def++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static char format[32] = {'%'};
|
||||
char *ptr = format+1;
|
||||
if (*src != '%')
|
||||
{
|
||||
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = *src++))
|
||||
/*nothing*/;
|
||||
*ptr = 0;
|
||||
ZEROTERM(format);
|
||||
--src;
|
||||
vsprintf(outptr, format, ap);
|
||||
// vsprintf doesnt alter the ap, increment here
|
||||
switch (*(ptr-1))
|
||||
{
|
||||
case 'f':
|
||||
va_arg(ap, double);
|
||||
break;
|
||||
case 's':
|
||||
va_arg(ap, char *);
|
||||
break;
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'i':
|
||||
default: // default: assume int-like parameter
|
||||
va_arg(ap, int);
|
||||
break;
|
||||
}
|
||||
|
||||
outptr += strlen(outptr);
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = *src;
|
||||
}
|
||||
++src;
|
||||
}
|
||||
|
||||
CHECK_OUTPTR(1);
|
||||
*outptr++ = 0;
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef*> &tmpVec)
|
||||
{
|
||||
CLang * language = GetLang(lang);
|
||||
@ -957,9 +989,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
if (!fp)
|
||||
{
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
for (iter=FileList.begin(); iter!=FileList.end(); ++iter)
|
||||
for (iter = FileList.begin(); iter != FileList.end(); ++iter)
|
||||
{
|
||||
if ( (*iter)->file.compare(file) == 0 )
|
||||
if ((*iter)->file.compare(file) == 0)
|
||||
{
|
||||
char buf[33] = {0};
|
||||
(*iter)->val.assign(buf);
|
||||
@ -969,19 +1001,20 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
md5.update(fp); // closes for us
|
||||
md5.update(fp); // closes for us
|
||||
md5.finalize();
|
||||
char md5buffer[33];
|
||||
md5.hex_digest(md5buffer);
|
||||
bool foundFlag = false;
|
||||
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
for (iter=FileList.begin(); iter!=FileList.end(); ++iter)
|
||||
for (iter = FileList.begin(); iter != FileList.end(); ++iter)
|
||||
{
|
||||
if ( (*iter)->file.compare(file) == 0 )
|
||||
if ((*iter)->file.compare(file) == 0)
|
||||
{
|
||||
if ( (*iter)->val.compare(md5buffer) == 0 )
|
||||
if ((*iter)->val.compare(md5buffer) == 0)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
@ -1022,6 +1055,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
buf.trim();
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
if ((buf[0] == ';') || (buf[0] == '/' && buf[1] == '/'))
|
||||
continue;
|
||||
|
||||
if (buf[0] == '[' && buf.size() >= 3)
|
||||
{
|
||||
if (multiline)
|
||||
@ -1031,10 +1067,12 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
delete tmpEntry;
|
||||
tmpEntry = 0;
|
||||
}
|
||||
|
||||
if (!Defq.empty())
|
||||
{
|
||||
MergeDefinitions(language, Defq);
|
||||
}
|
||||
|
||||
language[0] = buf[1];
|
||||
language[1] = buf[2];
|
||||
language[2] = 0;
|
||||
@ -1042,13 +1080,14 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
if (!multiline)
|
||||
{
|
||||
pos = buf.find('=');
|
||||
|
||||
if (pos > String::npos)
|
||||
{
|
||||
tmpEntry = new sKeyDef;
|
||||
String key;
|
||||
key.assign(buf.substr(0, pos).c_str());
|
||||
String def;
|
||||
def.assign(buf.substr(pos+1).c_str());
|
||||
def.assign(buf.substr(pos + 1).c_str());
|
||||
key.trim();
|
||||
key.toLower();
|
||||
int iKey = GetKeyEntry(key);
|
||||
@ -1062,6 +1101,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
tmpEntry = 0;
|
||||
} else {
|
||||
pos = buf.find(':');
|
||||
|
||||
if (pos > String::npos)
|
||||
{
|
||||
tmpEntry = new sKeyDef;
|
||||
@ -1092,6 +1132,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
} // if !multiline
|
||||
} //if - main
|
||||
}
|
||||
|
||||
// merge last section
|
||||
if (!Defq.empty())
|
||||
{
|
||||
@ -1105,9 +1146,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
CLangMngr::CLang * CLangMngr::GetLang(const char *name)
|
||||
{
|
||||
LangVecIter iter;
|
||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if ( strcmp((*iter)->GetName(), name)==0 )
|
||||
if (strcmp((*iter)->GetName(), name) == 0)
|
||||
return (*iter);
|
||||
}
|
||||
|
||||
@ -1122,9 +1163,9 @@ CLangMngr::CLang * CLangMngr::GetLang(const char *name)
|
||||
CLangMngr::CLang * CLangMngr::GetLangR(const char *name)
|
||||
{
|
||||
LangVecIter iter;
|
||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if ( strcmp((*iter)->GetName(), name)==0 )
|
||||
if (strcmp((*iter)->GetName(), name) == 0)
|
||||
return (*iter);
|
||||
}
|
||||
|
||||
@ -1136,6 +1177,7 @@ const char *CLangMngr::GetDef(const char *langName, const char *key)
|
||||
CLang *lang = GetLangR(langName);
|
||||
if (lang)
|
||||
return lang->GetDef(key);
|
||||
|
||||
return "ML_NOTFOUND(LANG)";
|
||||
}
|
||||
|
||||
@ -1166,7 +1208,7 @@ bool CLangMngr::Save(const char *filename)
|
||||
curOffset += sizeof(uint32_t);
|
||||
|
||||
uint32_t langOffset = curOffset + ktbSize + ltbSize;
|
||||
for (unsigned int i = 0; i<m_Languages.size(); i++)
|
||||
for (unsigned int i = 0; i < m_Languages.size(); i++)
|
||||
{
|
||||
langName = m_Languages[i]->GetName();
|
||||
fwrite(langName, sizeof(char), 2, fp);
|
||||
@ -1179,7 +1221,7 @@ bool CLangMngr::Save(const char *filename)
|
||||
//Note - langOffset now points to the start of key lookup table
|
||||
uint32_t keyHash = 0;
|
||||
uint32_t keyOffset = langOffset;
|
||||
for (unsigned int i = 0; i<KeyList.size(); i++)
|
||||
for (unsigned int i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
keyHash = KeyList[i]->hash;
|
||||
fwrite((void*)&keyHash, sizeof(uint32_t), 1, fp);
|
||||
@ -1192,7 +1234,7 @@ bool CLangMngr::Save(const char *filename)
|
||||
|
||||
//Note - now keyOffset points toward the start of the def table
|
||||
int defOffset = keyOffset;
|
||||
for (unsigned int i = 0; i<m_Languages.size(); i++)
|
||||
for (unsigned int i = 0; i < m_Languages.size(); i++)
|
||||
{
|
||||
m_Languages[i]->Save(fp, defOffset, curOffset);
|
||||
}
|
||||
@ -1200,7 +1242,7 @@ bool CLangMngr::Save(const char *filename)
|
||||
//Now, defOffset points toward the END of the file
|
||||
//curoffset should point toward the key table, so...
|
||||
unsigned char keyLen = 0;
|
||||
for (unsigned int i = 0; i<KeyList.size(); i++)
|
||||
for (unsigned int i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
keyLen = KeyList[i]->key.size();
|
||||
fwrite((void*)&keyLen, sizeof(unsigned char), 1, fp);
|
||||
@ -1211,7 +1253,7 @@ bool CLangMngr::Save(const char *filename)
|
||||
|
||||
//Finally, write the def table
|
||||
// It's assumed no orders changed...
|
||||
for (unsigned int i = 0; i<m_Languages.size(); i++)
|
||||
for (unsigned int i = 0; i < m_Languages.size(); i++)
|
||||
{
|
||||
m_Languages[i]->SaveDefinitions(fp, curOffset);
|
||||
}
|
||||
@ -1236,7 +1278,7 @@ bool CLangMngr::SaveCache(const char *filename)
|
||||
|
||||
fwrite((void *)&dictCount, sizeof(short), 1, fp);
|
||||
|
||||
for (i=FileList.begin(); i!=FileList.end(); i++)
|
||||
for (i = FileList.begin(); i != FileList.end(); i++)
|
||||
{
|
||||
len = (*i)->file.size();
|
||||
fwrite((void *)&len, sizeof(char), 1, fp);
|
||||
@ -1264,8 +1306,7 @@ bool CLangMngr::LoadCache(const char *filename)
|
||||
fread((void*)&dictCount, sizeof(short), 1, fp);
|
||||
md5Pair *p = 0;
|
||||
|
||||
|
||||
for (int i=1; i<=dictCount; i++)
|
||||
for (int i = 1; i <= dictCount; i++)
|
||||
{
|
||||
fread((void*)&len, sizeof(char), 1, fp);
|
||||
fread(buf, sizeof(char), len, fp);
|
||||
@ -1311,7 +1352,8 @@ bool CLangMngr::Load(const char *filename)
|
||||
|
||||
uint32_t *LangOffsets = new uint32_t[langCount];
|
||||
char langname[3];
|
||||
for (unsigned int i=0; i<langCount; i++)
|
||||
|
||||
for (unsigned int i = 0; i < langCount; i++)
|
||||
{
|
||||
fread(langname, sizeof(char), 2, fp);
|
||||
langname[2] = 0;
|
||||
@ -1324,7 +1366,8 @@ bool CLangMngr::Load(const char *filename)
|
||||
keyEntry *e = 0;
|
||||
unsigned char keylen;
|
||||
uint32_t keyoffset, save;
|
||||
for (unsigned i=0; i<keycount; i++)
|
||||
|
||||
for (unsigned i = 0; i < keycount; i++)
|
||||
{
|
||||
e = new keyEntry;
|
||||
fread((void*)&(e->hash), sizeof(uint32_t), 1, fp);
|
||||
@ -1332,7 +1375,7 @@ bool CLangMngr::Load(const char *filename)
|
||||
save = ftell(fp);
|
||||
fseek(fp, keyoffset, SEEK_SET);
|
||||
fread((void*)&keylen, sizeof(char), 1, fp);
|
||||
char *data = new char[keylen+1];
|
||||
char *data = new char[keylen + 1];
|
||||
fread(data, sizeof(char), keylen, fp);
|
||||
data[keylen] = 0;
|
||||
e->key.assign(data);
|
||||
@ -1347,10 +1390,12 @@ bool CLangMngr::Load(const char *filename)
|
||||
uint32_t defhash;
|
||||
uint32_t defoffset;
|
||||
unsigned short deflen;
|
||||
for (unsigned int i=0; i<langCount; i++)
|
||||
|
||||
for (unsigned int i = 0; i < langCount; i++)
|
||||
{
|
||||
fread((void*)&numentries, sizeof(uint32_t), 1, fp);
|
||||
for (unsigned int j=0; j<numentries; j++)
|
||||
|
||||
for (unsigned int j = 0; j < numentries; j++)
|
||||
{
|
||||
fread((void *)&keynum, sizeof(uint32_t), 1, fp);
|
||||
fread((void *)&defhash, sizeof(uint32_t), 1, fp);
|
||||
@ -1358,7 +1403,7 @@ bool CLangMngr::Load(const char *filename)
|
||||
save = ftell(fp);
|
||||
fseek(fp, defoffset, SEEK_SET);
|
||||
fread((void *)&deflen, sizeof(unsigned short), 1, fp);
|
||||
char *data = new char[deflen+1];
|
||||
char *data = new char[deflen + 1];
|
||||
fread(data, sizeof(char), deflen, fp);
|
||||
data[deflen] = 0;
|
||||
m_Languages[i]->AddEntry(keynum, defhash, data, true);
|
||||
@ -1383,19 +1428,20 @@ CLangMngr::~CLangMngr()
|
||||
void CLangMngr::Clear()
|
||||
{
|
||||
unsigned int i = 0;
|
||||
for (i=0; i<m_Languages.size(); i++)
|
||||
|
||||
for (i = 0; i < m_Languages.size(); i++)
|
||||
{
|
||||
if (m_Languages[i])
|
||||
delete m_Languages[i];
|
||||
}
|
||||
|
||||
for (i=0; i<FileList.size(); i++)
|
||||
for (i = 0; i < FileList.size(); i++)
|
||||
{
|
||||
if (FileList[i])
|
||||
delete FileList[i];
|
||||
}
|
||||
|
||||
for (i=0; i<KeyList.size(); i++)
|
||||
for (i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
if (KeyList[i])
|
||||
delete KeyList[i];
|
||||
@ -1415,7 +1461,8 @@ const char *CLangMngr::GetLangName(int langId)
|
||||
{
|
||||
int i = 0;
|
||||
LangVecIter iter;
|
||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if (i == langId)
|
||||
{
|
||||
@ -1423,13 +1470,15 @@ const char *CLangMngr::GetLangName(int langId)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool CLangMngr::LangExists(const char *langName)
|
||||
{
|
||||
char buf[3] = { 0 };
|
||||
char buf[3] = {0};
|
||||
int i = 0;
|
||||
|
||||
while (buf[i] = tolower(*langName++))
|
||||
{
|
||||
if (++i == 2)
|
||||
@ -1437,11 +1486,13 @@ bool CLangMngr::LangExists(const char *langName)
|
||||
}
|
||||
|
||||
LangVecIter iter;
|
||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if ( strcmp((*iter)->GetName(), buf)==0 )
|
||||
if (strcmp((*iter)->GetName(), buf) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ struct sKeyDef
|
||||
{
|
||||
sKeyDef() { key = -1; def = 0; }
|
||||
~sKeyDef() { if (def) delete def; }
|
||||
|
||||
int key;
|
||||
String *def;
|
||||
};
|
||||
@ -77,8 +78,9 @@ class CLangMngr
|
||||
// compare this language to a language name
|
||||
friend bool operator == (const CLang &left, const char *right)
|
||||
{
|
||||
return strcmp(left.m_LanguageName, right)==0 ? true : false;
|
||||
return strcmp(left.m_LanguageName, right) == 0 ? true : false;
|
||||
}
|
||||
|
||||
// Get language name
|
||||
const char *GetName() { return m_LanguageName; }
|
||||
// Save to file
|
||||
@ -91,8 +93,8 @@ class CLangMngr
|
||||
int Entries() { return m_LookUpTable.size(); }
|
||||
// Make a hash from a string; convert to lowercase first if needed
|
||||
static uint32_t MakeHash(const char *src, bool makeLower = false);
|
||||
protected:
|
||||
|
||||
protected:
|
||||
// An entry in the language
|
||||
class LangEntry
|
||||
{
|
||||
@ -145,7 +147,7 @@ class CLangMngr
|
||||
// Merge definitions into a language
|
||||
void MergeDefinitions(const char *lang, CQueue <sKeyDef*> &tmpVec);
|
||||
// strip lowercase; make lower if needed
|
||||
static size_t strip(char *str, char *newstr, bool makelower=false);
|
||||
static size_t strip(char *str, char *newstr, bool makelower = false);
|
||||
|
||||
typedef CVector<CLang*> LangVec;
|
||||
typedef CVector<CLang*>::iterator LangVecIter;
|
||||
|
@ -35,6 +35,7 @@
|
||||
// *****************************************************
|
||||
// class CList
|
||||
// *****************************************************
|
||||
|
||||
// Linked list
|
||||
template <typename T, typename F = char* >
|
||||
class CList
|
||||
@ -65,8 +66,10 @@ private:
|
||||
~CElement()
|
||||
{
|
||||
delete m_pObject;
|
||||
|
||||
if (m_pNext)
|
||||
m_pNext->m_pPrev = m_pPrev;
|
||||
|
||||
if (m_pPrev)
|
||||
m_pPrev->m_pNext = m_pNext;
|
||||
}
|
||||
@ -102,15 +105,16 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// CList<T,F> class
|
||||
// CList<T, F> class
|
||||
CElement *m_pHead; // head of the linked list
|
||||
CElement *m_pTail; // tail of the linked list
|
||||
public:
|
||||
// iterator class
|
||||
class iterator
|
||||
{
|
||||
friend class CList<T,F>;
|
||||
CList<T,F> *m_pList; // The list that created this iterator
|
||||
friend class CList<T, F>;
|
||||
|
||||
CList<T, F> *m_pList; // The list that created this iterator
|
||||
CElement *m_CurPos; // Current position in the list
|
||||
public:
|
||||
iterator()
|
||||
@ -120,7 +124,7 @@ public:
|
||||
}
|
||||
|
||||
// constructor based on list, element
|
||||
iterator(CList<T,F> *pList, CElement *startPos)
|
||||
iterator(CList<T, F> *pList, CElement *startPos)
|
||||
{
|
||||
m_pList = pList;
|
||||
m_CurPos = startPos;
|
||||
@ -147,7 +151,7 @@ public:
|
||||
// validity check operator
|
||||
inline operator bool () const
|
||||
{
|
||||
return m_pList!=NULL && m_CurPos!=NULL && m_CurPos->GetObj()!=NULL;
|
||||
return m_pList != NULL && m_CurPos != NULL && m_CurPos->GetObj() != NULL;
|
||||
}
|
||||
|
||||
// pre increment operator
|
||||
@ -162,6 +166,7 @@ public:
|
||||
{
|
||||
iterator tmp(*this);
|
||||
m_CurPos = m_CurPos->next;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -176,18 +181,20 @@ public:
|
||||
{
|
||||
return m_pList->remove(*this);
|
||||
}
|
||||
|
||||
iterator put(T *obj)
|
||||
{
|
||||
return m_pList->put(obj, *this);
|
||||
}
|
||||
};
|
||||
|
||||
CList<T,F>()
|
||||
CList<T, F>()
|
||||
{
|
||||
m_pHead = NULL;
|
||||
m_pTail = NULL;
|
||||
}
|
||||
~CList<T,F>()
|
||||
|
||||
~CList<T, F>()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
@ -198,12 +205,16 @@ public:
|
||||
iterator remove(iterator &where)
|
||||
{
|
||||
iterator tmp(where.GetNext());
|
||||
|
||||
if (where.m_CurPos == m_pHead)
|
||||
m_pHead = where.m_CurPos->GetNext();
|
||||
|
||||
if (where.m_CurPos == m_pTail)
|
||||
m_pTail = where.m_CurPos->GetPrev();
|
||||
|
||||
delete where.m_CurPos;
|
||||
where = tmp;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -212,36 +223,36 @@ public:
|
||||
iterator put_back(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pTmp->SetNext(NULL);
|
||||
pTmp->SetPrev(m_pTail);
|
||||
m_pTail->SetNext(pTmp);
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
iterator put_front(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pTmp->SetNext(m_pHead);
|
||||
pTmp->SetPrev(NULL);
|
||||
m_pHead->SetPrev(pTmp);
|
||||
m_pHead = pTmp;
|
||||
}
|
||||
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
@ -257,6 +268,7 @@ public:
|
||||
iterator put(T *pObj, iterator &where)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (where.m_CurPos->GetNext())
|
||||
where.m_CurPos->GetNext()->SetPrev(pTmp);
|
||||
else // where = tail
|
||||
@ -266,6 +278,7 @@ public:
|
||||
pTmp->SetNext(where.m_CurPos->GetNext());
|
||||
|
||||
where.m_CurPos->SetNext(pTmp);
|
||||
|
||||
return ++where;
|
||||
}
|
||||
|
||||
@ -283,12 +296,13 @@ public:
|
||||
iterator find(iterator startOn, const F &desc)
|
||||
{
|
||||
iterator iter = startOn;
|
||||
while(iter)
|
||||
while (iter)
|
||||
{
|
||||
if (*iter == desc)
|
||||
break;
|
||||
++iter;
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
@ -300,14 +314,16 @@ public:
|
||||
int size()
|
||||
{
|
||||
iterator iter = begin();
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
while (iter)
|
||||
{
|
||||
++i;
|
||||
++iter;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //CLIST_H
|
||||
|
@ -35,135 +35,192 @@
|
||||
// *****************************************************
|
||||
// class LogEventsMngr
|
||||
// *****************************************************
|
||||
LogEventsMngr::LogEventsMngr() {
|
||||
logCurrent = logCounter = 0;
|
||||
logcmplist = 0;
|
||||
arelogevents = false;
|
||||
memset( logevents, 0, sizeof(logevents) );
|
||||
|
||||
LogEventsMngr::LogEventsMngr()
|
||||
{
|
||||
logCurrent = logCounter = 0;
|
||||
logcmplist = 0;
|
||||
arelogevents = false;
|
||||
memset(logevents, 0, sizeof(logevents));
|
||||
}
|
||||
|
||||
LogEventsMngr::~LogEventsMngr() {
|
||||
clearLogEvents();
|
||||
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.c_str() ) ? 0 : 1;
|
||||
return result = strcmp(string,text.c_str());
|
||||
int LogEventsMngr::CLogCmp::compareCondition(const char* string)
|
||||
{
|
||||
if (logid == parent->logCounter)
|
||||
return result;
|
||||
|
||||
logid = parent->logCounter;
|
||||
|
||||
if (in)
|
||||
return result = strstr(string, text.c_str()) ? 0 : 1;
|
||||
|
||||
return result = strcmp(string,text.c_str());
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter){
|
||||
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter)
|
||||
{
|
||||
char* temp = filter;
|
||||
// expand "1=message"
|
||||
while ( isdigit(*filter) )
|
||||
|
||||
while (isdigit(*filter))
|
||||
++filter;
|
||||
bool in = (*filter=='&');
|
||||
*filter++ = 0;
|
||||
int pos = atoi(temp);
|
||||
if ( pos < 0 || pos >= MAX_LOGARGS) pos = 0;
|
||||
|
||||
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.c_str(), filter))
|
||||
|
||||
while (c)
|
||||
{
|
||||
if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.c_str(), filter))
|
||||
return c;
|
||||
c = c->next;
|
||||
}
|
||||
return logcmplist = new CLogCmp( filter , in , pos , logcmplist,this );
|
||||
|
||||
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 );
|
||||
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 );
|
||||
|
||||
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 ) {
|
||||
void LogEventsMngr::setLogString(char* frmt, va_list& vaptr)
|
||||
{
|
||||
++logCounter;
|
||||
int len = vsnprintf (logString, 255 , frmt, vaptr );
|
||||
if ( len == - 1) {
|
||||
int len = vsnprintf(logString, 255, frmt, vaptr);
|
||||
|
||||
if (len == - 1)
|
||||
{
|
||||
len = 255;
|
||||
logString[len] = 0;
|
||||
}
|
||||
if ( len ) logString[--len] = 0;
|
||||
|
||||
if (len)
|
||||
logString[--len] = 0;
|
||||
|
||||
logArgc = 0;
|
||||
}
|
||||
|
||||
void LogEventsMngr::setLogString( char* frmt, ... ) {
|
||||
void LogEventsMngr::setLogString(char* frmt, ...)
|
||||
{
|
||||
++logCounter;
|
||||
va_list logArgPtr;
|
||||
va_start ( logArgPtr , frmt );
|
||||
int len = vsnprintf(logString, 255 , frmt, logArgPtr );
|
||||
if ( len == - 1) {
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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 )
|
||||
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 );
|
||||
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()
|
||||
{
|
||||
bool valid;
|
||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
||||
bool valid;
|
||||
|
||||
for (CLogEvent* a = logevents[logArgc]; a; a = a->next)
|
||||
{
|
||||
valid = true;
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next)
|
||||
|
||||
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 ){
|
||||
|
||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
||||
{
|
||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
break;
|
||||
}
|
||||
@ -172,67 +229,90 @@ void LogEventsMngr::executeLogEvents()
|
||||
{
|
||||
executeForwards(a->func);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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::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;
|
||||
}
|
||||
void LogEventsMngr::clearConditions()
|
||||
{
|
||||
while (logcmplist)
|
||||
{
|
||||
CLogCmp* a = logcmplist->next;
|
||||
delete logcmplist;
|
||||
logcmplist = a;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
|
||||
while( list ) {
|
||||
LogEventsMngr::CLogEvent::LogCond::~LogCond()
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
LogCondEle* cc = list->next;
|
||||
delete list;
|
||||
list = cc;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent::~CLogEvent() {
|
||||
while( filters ) {
|
||||
LogEventsMngr::CLogEvent::~CLogEvent()
|
||||
{
|
||||
while (filters)
|
||||
{
|
||||
LogCond* cc = filters->next;
|
||||
delete filters;
|
||||
filters = cc;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent( CLogEvent * a )
|
||||
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent(CLogEvent * a)
|
||||
{
|
||||
bool valid;
|
||||
while(a){
|
||||
|
||||
while (a)
|
||||
{
|
||||
valid = true;
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||
|
||||
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 ){
|
||||
|
||||
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){
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,126 +40,139 @@
|
||||
// class LogEventsMngr
|
||||
// *****************************************************
|
||||
|
||||
class LogEventsMngr {
|
||||
|
||||
char logString[256];
|
||||
char logArgs[MAX_LOGARGS][128];
|
||||
int logArgc;
|
||||
int logCounter;
|
||||
int logCurrent;
|
||||
bool arelogevents;
|
||||
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;
|
||||
class CLogCmp;
|
||||
class iterator;
|
||||
class CLogEvent;
|
||||
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 CLogCmp;
|
||||
friend class iterator;
|
||||
struct LogCondEle {
|
||||
CLogCmp *cmp;
|
||||
LogCondEle *next;
|
||||
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
|
||||
|
||||
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);
|
||||
};
|
||||
struct LogCond {
|
||||
int argnum;
|
||||
LogCondEle *list;
|
||||
LogCond *next;
|
||||
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
|
||||
~LogCond();
|
||||
};
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
int func;
|
||||
LogCond *filters;
|
||||
LogEventsMngr* parent;
|
||||
CLogEvent *next;
|
||||
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
|
||||
~CLogEvent();
|
||||
public:
|
||||
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
|
||||
void registerFilter( char* filter );
|
||||
inline int getFunction() { return func; }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CLogEvent *logevents[MAX_LOGARGS+1];
|
||||
CLogEvent *getValidLogEvent( CLogEvent * a );
|
||||
CLogCmp* registerCondition(char* filter);
|
||||
void clearConditions();
|
||||
|
||||
CLogCmp *logcmplist;
|
||||
public:
|
||||
|
||||
LogEventsMngr();
|
||||
~LogEventsMngr();
|
||||
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
|
||||
{
|
||||
int argnum;
|
||||
|
||||
LogCondEle *list;
|
||||
LogCond *next;
|
||||
LogCond(int a, LogCondEle* ee, LogCond* n) : argnum(a), list(ee), next(n) {}
|
||||
~LogCond();
|
||||
};
|
||||
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
|
||||
int func;
|
||||
|
||||
LogCond *filters;
|
||||
LogEventsMngr* parent;
|
||||
|
||||
CLogEvent *next;
|
||||
CLogEvent(CPluginMngr::CPlugin *p, int f, LogEventsMngr* ppp) : plugin(p), func(f), filters(0), parent(ppp), next(0) {}
|
||||
~CLogEvent();
|
||||
public:
|
||||
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
|
||||
void registerFilter(char* filter);
|
||||
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();
|
||||
|
||||
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();
|
||||
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
|
||||
{
|
||||
CLogEvent* a;
|
||||
LogEventsMngr* b;
|
||||
|
||||
class iterator {
|
||||
CLogEvent* a;
|
||||
LogEventsMngr* b;
|
||||
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); }
|
||||
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
|
||||
|
||||
|
||||
#endif //LOGEVENTS_H
|
||||
|
@ -35,7 +35,8 @@
|
||||
// *****************************************************
|
||||
// class MenuMngr
|
||||
// *****************************************************
|
||||
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
|
||||
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
|
||||
{
|
||||
plugin = a;
|
||||
keys = k;
|
||||
menuid = mi;
|
||||
@ -50,45 +51,52 @@ MenuMngr::~MenuMngr()
|
||||
|
||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||
{
|
||||
for( MenuIdEle* b = headid; b ; b = b->next) {
|
||||
if ( (!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||
return b->id;
|
||||
}
|
||||
return 0;
|
||||
for (MenuIdEle* b = headid; b; b = b->next)
|
||||
{
|
||||
if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
|
||||
return b->id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MenuMngr::registerMenuId(const char* n, AMX* a )
|
||||
int MenuMngr::registerMenuId(const char* n, AMX* a)
|
||||
{
|
||||
int id = findMenuId( n, a );
|
||||
if (id) return id;
|
||||
headid = new MenuIdEle( n, a , headid );
|
||||
if (!headid)
|
||||
return 0; // :TODO: Better error report
|
||||
return headid->id;
|
||||
int id = findMenuId(n, a);
|
||||
|
||||
if (id)
|
||||
return id;
|
||||
|
||||
headid = new MenuIdEle(n, a, headid);
|
||||
|
||||
if (!headid)
|
||||
return 0; // :TODO: Better error report
|
||||
|
||||
return headid->id;
|
||||
}
|
||||
|
||||
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
|
||||
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);
|
||||
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 (headid)
|
||||
{
|
||||
MenuIdEle* a = headid->next;
|
||||
delete headid;
|
||||
headid = a;
|
||||
}
|
||||
|
||||
while (headcmd)
|
||||
{
|
||||
MenuCommand* a = headcmd->next;
|
||||
delete headcmd;
|
||||
headcmd = a;
|
||||
}
|
||||
while (headcmd)
|
||||
{
|
||||
MenuCommand* a = headcmd->next;
|
||||
delete headcmd;
|
||||
headcmd = a;
|
||||
}
|
||||
}
|
||||
|
||||
int MenuMngr::MenuIdEle::uniqueid = 0;
|
@ -38,55 +38,58 @@
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
class iterator;
|
||||
private:
|
||||
|
||||
class MenuCommand
|
||||
{
|
||||
friend class iterator;
|
||||
friend class MenuMngr;
|
||||
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;
|
||||
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() { headid = 0; headcmd = 0; }
|
||||
~MenuMngr();
|
||||
|
||||
// Interface
|
||||
|
||||
|
||||
int findMenuId(const char* name, AMX* a = 0);
|
||||
int registerMenuId(const char* n, AMX* a );
|
||||
int registerMenuId(const char* n, AMX* a);
|
||||
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
class iterator
|
||||
{
|
||||
MenuCommand* a;
|
||||
public:
|
||||
iterator(MenuCommand*aa) : a(aa) {}
|
||||
@ -96,8 +99,9 @@ public:
|
||||
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
|
||||
#endif //MENUS_H
|
||||
|
@ -33,7 +33,7 @@
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
|
||||
void CPlayer::Init( edict_t* e , int i )
|
||||
void CPlayer::Init(edict_t* e, int i)
|
||||
{
|
||||
index = i;
|
||||
pEdict = e;
|
||||
@ -55,178 +55,224 @@ void CPlayer::Init( edict_t* e , int i )
|
||||
team.clear();
|
||||
}
|
||||
|
||||
void CPlayer::Disconnect() {
|
||||
ingame = false;
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
bot = 0;
|
||||
void CPlayer::Disconnect()
|
||||
{
|
||||
ingame = false;
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
|
||||
while (!cvarQueryQueue.empty())
|
||||
{
|
||||
ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
|
||||
unregisterSPForward(pQuery->resultFwd);
|
||||
|
||||
if (pQuery->params)
|
||||
delete [] pQuery->params;
|
||||
|
||||
delete pQuery;
|
||||
cvarQueryQueue.pop();
|
||||
}
|
||||
|
||||
bot = 0;
|
||||
}
|
||||
|
||||
void CPlayer::PutInServer() {
|
||||
playtime = gpGlobals->time;
|
||||
ingame = true;
|
||||
}
|
||||
bool CPlayer::Connect(const char* connectname,const char* ipaddress) {
|
||||
name.assign(connectname);
|
||||
ip.assign(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;
|
||||
void CPlayer::PutInServer()
|
||||
{
|
||||
playtime = gpGlobals->time;
|
||||
ingame = true;
|
||||
}
|
||||
|
||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
||||
{
|
||||
name.assign(connectname);
|
||||
ip.assign(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 )
|
||||
|
||||
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;
|
||||
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 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;
|
||||
bool found = false;
|
||||
Obj** a = &head;
|
||||
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
a = &(*a)->next;
|
||||
}
|
||||
return found;
|
||||
return found;
|
||||
}
|
||||
|
||||
void Grenades::clear()
|
||||
{
|
||||
while(head){
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
while (head)
|
||||
{
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class XVars
|
||||
// *****************************************************
|
||||
void XVars::clear() {
|
||||
|
||||
void XVars::clear()
|
||||
{
|
||||
delete[] head;
|
||||
head = 0;
|
||||
num = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
int XVars::put( AMX* p, cell* v )
|
||||
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;
|
||||
}
|
||||
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;
|
||||
if ((num >= size) && realloc_array(size ? (size * 2) : 8))
|
||||
return -1;
|
||||
|
||||
head[num].value = v;
|
||||
head[num].amx = p;
|
||||
return num++;
|
||||
head[num].value = v;
|
||||
head[num].amx = p;
|
||||
|
||||
return num++;
|
||||
}
|
||||
|
||||
int XVars::realloc_array( int nsize )
|
||||
int XVars::realloc_array(int nsize)
|
||||
{
|
||||
XVarEle* me = new XVarEle[nsize];
|
||||
if ( me ){
|
||||
for(int a = 0 ; a < num; ++a)
|
||||
|
||||
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 ) {
|
||||
|
||||
TeamIds::~TeamIds()
|
||||
{
|
||||
while (head)
|
||||
{
|
||||
TeamEle* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeamIds::registerTeam( const char* n ,int s )
|
||||
void TeamIds::registerTeam(const char* n, int s)
|
||||
{
|
||||
TeamEle** a = &head;
|
||||
while( *a ){
|
||||
if ( strcmp((*a)->name.c_str(),n) == 0 ){
|
||||
if (s != -1){
|
||||
TeamEle** a = &head;
|
||||
|
||||
while (*a)
|
||||
{
|
||||
if (strcmp((*a)->name.c_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);
|
||||
}
|
||||
|
||||
*a = new TeamEle(n, s);
|
||||
|
||||
if (*a == 0)
|
||||
return;
|
||||
|
||||
newTeam |= (1<<(*a)->tid);
|
||||
}
|
||||
|
||||
int TeamIds::findTeamId( const char* n )
|
||||
int TeamIds::findTeamId(const char* n)
|
||||
{
|
||||
TeamEle* a = head;
|
||||
while( a ){
|
||||
if ( !stricmp(a->name.c_str(),n) )
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (!stricmp(a->name.c_str(), n))
|
||||
return a->id;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TeamIds::findTeamIdCase( const char* n)
|
||||
int TeamIds::findTeamIdCase(const char* n)
|
||||
{
|
||||
TeamEle* a = head;
|
||||
while( a ){
|
||||
if ( !strcmp(a->name.c_str(), n) )
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (!strcmp(a->name.c_str(), n))
|
||||
return a->id;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char TeamIds::TeamEle::uid = 0;
|
||||
|
||||
|
205
amxmodx/CMisc.h
205
amxmodx/CMisc.h
@ -37,34 +37,44 @@
|
||||
// *****************************************************
|
||||
// class CCVar
|
||||
// *****************************************************
|
||||
|
||||
class CCVar
|
||||
{
|
||||
cvar_t cvar;
|
||||
String name;
|
||||
String plugin;
|
||||
cvar_t cvar;
|
||||
String name;
|
||||
String plugin;
|
||||
|
||||
public:
|
||||
CCVar( const char* pname, const char* pplugin,
|
||||
int pflags, float pvalue ) : name(pname) , plugin(pplugin ) {
|
||||
CCVar(const char* pname, const char* pplugin, int pflags, float pvalue) : name(pname), plugin(pplugin)
|
||||
{
|
||||
cvar.name = (char*)name.c_str();
|
||||
cvar.flags = pflags;
|
||||
cvar.string = "";
|
||||
cvar.value = pvalue;
|
||||
}
|
||||
}
|
||||
|
||||
inline cvar_t* getCvar() { return &cvar; }
|
||||
inline const char* getPluginName() { return plugin.c_str(); }
|
||||
inline const char* getName() { return name.c_str(); }
|
||||
inline bool operator == ( const char* string ) { return (strcmp(name.c_str(),string)==0); }
|
||||
inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
|
||||
struct ClientCvarQuery_Info
|
||||
{
|
||||
bool querying; // Are we actually waiting for a response at the moment?
|
||||
String cvarName;
|
||||
int resultFwd;
|
||||
|
||||
int paramLen;
|
||||
cell *params;
|
||||
};
|
||||
|
||||
class CPlayer
|
||||
{
|
||||
|
||||
public:
|
||||
edict_t* pEdict;
|
||||
|
||||
@ -80,7 +90,8 @@ public:
|
||||
float time;
|
||||
float playtime;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
int ammo;
|
||||
int clip;
|
||||
} weapons[MAX_WEAPONS];
|
||||
@ -106,17 +117,22 @@ public:
|
||||
Vector thisTrace;
|
||||
Vector lastHit;
|
||||
|
||||
void Init( edict_t* e , int i );
|
||||
CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
|
||||
|
||||
void Init(edict_t* e, int i);
|
||||
void Disconnect();
|
||||
void PutInServer();
|
||||
bool Connect(const char* connectname,const char* ipaddress);
|
||||
|
||||
inline bool IsBot(){
|
||||
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
|
||||
bool Connect(const char* connectname, const char* ipaddress);
|
||||
|
||||
inline bool IsBot()
|
||||
{
|
||||
return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
|
||||
}
|
||||
|
||||
inline bool IsAlive(){
|
||||
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
|
||||
inline bool IsAlive()
|
||||
{
|
||||
return ((pEdict->v.deadflag == DEAD_NO) && (pEdict->v.health > 0));
|
||||
}
|
||||
|
||||
inline void Authorize() { authorized = true; }
|
||||
@ -129,40 +145,44 @@ public:
|
||||
|
||||
class Grenades
|
||||
{
|
||||
struct Obj
|
||||
{
|
||||
CPlayer* player;
|
||||
edict_t* grenade;
|
||||
float time;
|
||||
int type;
|
||||
Obj* next;
|
||||
} *head;
|
||||
|
||||
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();
|
||||
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 {
|
||||
String filename;
|
||||
FORCE_TYPE type;
|
||||
Vector mins;
|
||||
Vector maxs;
|
||||
AMX* amx;
|
||||
|
||||
class ForceObject
|
||||
{
|
||||
String filename;
|
||||
FORCE_TYPE type;
|
||||
Vector mins;
|
||||
Vector maxs;
|
||||
AMX* amx;
|
||||
public:
|
||||
ForceObject(const char* n, FORCE_TYPE c,Vector& mi, Vector& ma, AMX* a) :
|
||||
filename(n) , type(c), mins(mi), maxs(ma), amx(a) {}
|
||||
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.c_str(); }
|
||||
inline AMX* getAMX() { return amx; }
|
||||
|
||||
Vector& getMin() { return mins; }
|
||||
Vector& getMax() { return maxs; }
|
||||
|
||||
inline FORCE_TYPE getForceType() { return type; }
|
||||
};
|
||||
|
||||
@ -172,81 +192,92 @@ public:
|
||||
|
||||
class XVars
|
||||
{
|
||||
struct XVarEle {
|
||||
AMX* amx;
|
||||
cell* value;
|
||||
};
|
||||
struct XVarEle
|
||||
{
|
||||
AMX* amx;
|
||||
cell* value;
|
||||
};
|
||||
|
||||
XVarEle* head;
|
||||
int size;
|
||||
int num;
|
||||
XVarEle* head;
|
||||
|
||||
int realloc_array( int nsize );
|
||||
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;
|
||||
}
|
||||
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){}
|
||||
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.c_str(); }
|
||||
inline bool operator==( void* a ) { return (amx == (AMX*)a); }
|
||||
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;
|
||||
struct TeamEle
|
||||
{
|
||||
String name;
|
||||
int id;
|
||||
char tid;
|
||||
static char uid;
|
||||
TeamEle* next;
|
||||
|
||||
int newTeam;
|
||||
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; }
|
||||
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
|
||||
|
||||
|
||||
|
||||
#endif //CMISC_H
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifndef FAR
|
||||
#define FAR
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
// New
|
||||
@ -55,7 +55,7 @@ CModule::CModule(const char* fname)
|
||||
CModule::~CModule()
|
||||
{
|
||||
// old & new
|
||||
if ( m_Handle )
|
||||
if (m_Handle)
|
||||
DLFREE(m_Handle);
|
||||
|
||||
clear();
|
||||
@ -67,6 +67,7 @@ void CModule::clear(bool clearFilename)
|
||||
m_Metamod = false;
|
||||
m_Handle = NULL;
|
||||
m_Status = MODULE_NONE;
|
||||
|
||||
if (clearFilename)
|
||||
m_Filename.assign("unknown");
|
||||
|
||||
@ -114,6 +115,7 @@ bool CModule::attachModule()
|
||||
|
||||
if (!AttachFunc_New)
|
||||
return false;
|
||||
|
||||
g_ModuleCallReason = ModuleCall_Attach;
|
||||
g_CurrentlyCalledModule = this;
|
||||
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
||||
@ -122,21 +124,21 @@ bool CModule::attachModule()
|
||||
|
||||
switch (retVal)
|
||||
{
|
||||
case AMXX_OK:
|
||||
m_Status = MODULE_LOADED;
|
||||
return true;
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_FUNC_NOT_PRESENT:
|
||||
m_Status = MODULE_FUNCNOTPRESENT;
|
||||
m_MissingFunc = g_LastRequestedFunc;
|
||||
return false;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
case AMXX_OK:
|
||||
m_Status = MODULE_LOADED;
|
||||
return true;
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_FUNC_NOT_PRESENT:
|
||||
m_Status = MODULE_FUNCNOTPRESENT;
|
||||
m_MissingFunc = g_LastRequestedFunc;
|
||||
return false;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
m_Status = MODULE_BADLOAD;
|
||||
@ -147,7 +149,7 @@ bool CModule::attachModule()
|
||||
|
||||
bool CModule::queryModule()
|
||||
{
|
||||
if (m_Status != MODULE_NONE) // don't check if already queried
|
||||
if (m_Status != MODULE_NONE) // don't check if already queried
|
||||
return false;
|
||||
|
||||
m_Handle = DLLOAD(m_Filename.c_str()); // load file
|
||||
@ -163,6 +165,7 @@ bool CModule::queryModule()
|
||||
|
||||
// Try new interface first
|
||||
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
|
||||
|
||||
if (queryFunc_New)
|
||||
{
|
||||
m_Amxx = true;
|
||||
@ -172,24 +175,25 @@ bool CModule::queryModule()
|
||||
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||
g_CurrentlyCalledModule = NULL;
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
|
||||
switch (retVal)
|
||||
{
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_IFVERS:
|
||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||
m_Status = MODULE_OLD;
|
||||
else
|
||||
m_Status = MODULE_NEWER;
|
||||
return false;
|
||||
case AMXX_OK:
|
||||
break;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_IFVERS:
|
||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||
m_Status = MODULE_OLD;
|
||||
else
|
||||
m_Status = MODULE_NEWER;
|
||||
return false;
|
||||
case AMXX_OK:
|
||||
break;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for attach
|
||||
@ -201,9 +205,7 @@ bool CModule::queryModule()
|
||||
|
||||
m_Status = MODULE_QUERY;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
m_Status = MODULE_NOQUERY;
|
||||
m_Amxx = false;
|
||||
return false;
|
||||
@ -218,6 +220,7 @@ bool CModule::detachModule()
|
||||
if (m_Amxx)
|
||||
{
|
||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||
|
||||
if (detachFunc_New)
|
||||
{
|
||||
g_ModuleCallReason = ModuleCall_Detach;
|
||||
@ -227,14 +230,17 @@ bool CModule::detachModule()
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FAKEMETA
|
||||
if (IsMetamod())
|
||||
{
|
||||
UnloadMetamodPlugin(m_Handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
DLFREE(m_Handle);
|
||||
clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -247,28 +253,31 @@ void CModule::CallPluginsLoaded()
|
||||
return;
|
||||
|
||||
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
const char* CModule::getStatus() const
|
||||
{
|
||||
switch(m_Status)
|
||||
switch (m_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";
|
||||
case MODULE_FUNCNOTPRESENT:
|
||||
case MODULE_NEWER: return "newer";
|
||||
case MODULE_INTERROR: return "internal err";
|
||||
case MODULE_NOT64BIT: return "not 64bit";
|
||||
default: break;
|
||||
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";
|
||||
case MODULE_FUNCNOTPRESENT:
|
||||
case MODULE_NEWER: return "newer";
|
||||
case MODULE_INTERROR: return "internal err";
|
||||
case MODULE_NOT64BIT: return "not 64bit";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
@ -36,19 +36,20 @@
|
||||
#ifndef CMODULE_H
|
||||
#define CMODULE_H
|
||||
|
||||
enum MODULE_STATUS {
|
||||
MODULE_NONE, // No module loaded
|
||||
MODULE_QUERY, // Query failed
|
||||
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
|
||||
MODULE_LOADED, // Loaded
|
||||
MODULE_NOINFO, // No info
|
||||
MODULE_NOQUERY, // No query function present
|
||||
MODULE_NOATTACH, // No attach function present
|
||||
MODULE_OLD, // Old interface
|
||||
MODULE_NEWER, // newer interface
|
||||
MODULE_INTERROR, // Internal error
|
||||
MODULE_FUNCNOTPRESENT, // Function not present
|
||||
MODULE_NOT64BIT // Not 64 bit compatible
|
||||
enum MODULE_STATUS
|
||||
{
|
||||
MODULE_NONE, // No module loaded
|
||||
MODULE_QUERY, // Query failed
|
||||
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
|
||||
MODULE_LOADED, // Loaded
|
||||
MODULE_NOINFO, // No info
|
||||
MODULE_NOQUERY, // No query function present
|
||||
MODULE_NOATTACH, // No attach function present
|
||||
MODULE_OLD, // Old interface
|
||||
MODULE_NEWER, // newer interface
|
||||
MODULE_INTERROR, // Internal error
|
||||
MODULE_FUNCNOTPRESENT, // Function not present
|
||||
MODULE_NOT64BIT // Not 64 bit compatible
|
||||
};
|
||||
|
||||
struct amxx_module_info_s
|
||||
@ -60,7 +61,6 @@ struct amxx_module_info_s
|
||||
const char *logtag; //added in version 2
|
||||
};
|
||||
|
||||
|
||||
#define AMXX_OK 0 /* no error */
|
||||
#define AMXX_IFVERS 1 /* interface version */
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
@ -71,8 +71,10 @@ struct amxx_module_info_s
|
||||
class CModule
|
||||
{
|
||||
String m_Filename; // Filename
|
||||
|
||||
bool m_Metamod; // Using metamod?
|
||||
bool m_Amxx; // Using new module interface?
|
||||
|
||||
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||
DLHANDLE m_Handle; // handle
|
||||
MODULE_STATUS m_Status; // status
|
||||
@ -84,12 +86,15 @@ public:
|
||||
~CModule();
|
||||
|
||||
// Interface
|
||||
|
||||
bool attachModule();
|
||||
bool queryModule();
|
||||
bool detachModule();
|
||||
|
||||
#ifndef FAKEMETA
|
||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
||||
#endif
|
||||
|
||||
const char* getStatus() const;
|
||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
||||
inline const char* getAuthor() const { return m_InfoNew.author; }
|
||||
@ -97,18 +102,16 @@ public:
|
||||
inline const char* getName() const { return m_InfoNew.name; }
|
||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||
inline int getStatusValue() { return m_Status; }
|
||||
inline bool operator==( const char* fname ) { return !strcmp( m_Filename.c_str() , fname ); }
|
||||
inline bool operator==(const char* fname) { return !strcmp(m_Filename.c_str(), fname); }
|
||||
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
|
||||
inline bool isAmxx() const { return m_Amxx; }
|
||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||
inline bool IsMetamod() { return m_Metamod; }
|
||||
|
||||
void CModule::CallPluginsLoaded();
|
||||
|
||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif //CMODULE_H
|
||||
|
@ -35,17 +35,24 @@
|
||||
#include "CFile.h"
|
||||
#include "amx.h"
|
||||
#include "natives.h"
|
||||
#include "debugger.h"
|
||||
|
||||
extern const char *no_function;
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) {
|
||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
|
||||
{
|
||||
CPlugin** a = &head;
|
||||
while( *a ) a = &(*a)->next;
|
||||
*a = new CPlugin( pCounter++ ,path,name,error, debug);
|
||||
|
||||
while (*a)
|
||||
a = &(*a)->next;
|
||||
|
||||
*a = new CPlugin(pCounter++, path, name, error, debug);
|
||||
|
||||
return (*a);
|
||||
}
|
||||
|
||||
void CPluginMngr::unloadPlugin( CPlugin** a ) {
|
||||
void CPluginMngr::unloadPlugin(CPlugin** a)
|
||||
{
|
||||
CPlugin* next = (*a)->next;
|
||||
delete *a;
|
||||
*a = next;
|
||||
@ -56,9 +63,10 @@ void CPluginMngr::Finalize()
|
||||
{
|
||||
if (m_Finalized)
|
||||
return;
|
||||
pNatives = BuildNativeTable();
|
||||
|
||||
pNatives = BuildNativeTable();
|
||||
CPlugin *a = head;
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (a->getStatusCode() == ps_running)
|
||||
@ -66,19 +74,20 @@ void CPluginMngr::Finalize()
|
||||
amx_Register(a->getAMX(), pNatives, -1);
|
||||
a->Finalize();
|
||||
}
|
||||
a=a->next;
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
m_Finalized = true;
|
||||
}
|
||||
|
||||
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
{
|
||||
char file[256];
|
||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file)-1, "%s",filename) , "rt");
|
||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
|
||||
|
||||
if ( !fp )
|
||||
if (!fp)
|
||||
{
|
||||
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename);
|
||||
AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -89,22 +98,26 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
|
||||
String line;
|
||||
|
||||
while ( !feof(fp) )
|
||||
while (!feof(fp))
|
||||
{
|
||||
pluginName[0] = '\0';
|
||||
|
||||
debug[0] = '\0';
|
||||
debugFlag = 0;
|
||||
|
||||
line.clear();
|
||||
line._fread(fp);
|
||||
sscanf(line.c_str(),"%s %s",pluginName, debug);
|
||||
if (!isalnum(*pluginName)) continue;
|
||||
sscanf(line.c_str(), "%s %s", pluginName, debug);
|
||||
|
||||
if (!isalnum(*pluginName))
|
||||
continue;
|
||||
|
||||
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
||||
{
|
||||
debugFlag = 1;
|
||||
}
|
||||
|
||||
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error, debugFlag);
|
||||
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
|
||||
|
||||
if (plugin->getStatusCode() == ps_bad_load)
|
||||
{
|
||||
@ -120,11 +133,15 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
return pCounter;
|
||||
}
|
||||
|
||||
void CPluginMngr::clear() {
|
||||
void CPluginMngr::clear()
|
||||
{
|
||||
CPlugin**a = &head;
|
||||
while ( *a )
|
||||
|
||||
while (*a)
|
||||
unloadPlugin(a);
|
||||
|
||||
m_Finalized = false;
|
||||
|
||||
if (pNatives)
|
||||
{
|
||||
delete [] pNatives;
|
||||
@ -134,77 +151,101 @@ void CPluginMngr::clear() {
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||
{
|
||||
return (CPlugin*)(amx->userdata[3]);
|
||||
return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
|
||||
{
|
||||
CPlugin*a = head;
|
||||
while ( a && &a->amx != amx )
|
||||
a=a->next;
|
||||
|
||||
while (a && &a->amx != amx)
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index)
|
||||
{
|
||||
CPlugin*a = head;
|
||||
while ( a && index--)
|
||||
a=a->next;
|
||||
|
||||
while (a && index--)
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) {
|
||||
if (!name) return 0;
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
|
||||
{
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
int len = strlen(name);
|
||||
if (!len) return 0;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
CPlugin*a = head;
|
||||
while( a && strncmp(a->name.c_str(), name,len) )
|
||||
a=a->next;
|
||||
|
||||
while (a && strncmp(a->name.c_str(), name, len))
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
const char* CPluginMngr::CPlugin::getStatus() const {
|
||||
switch(status){
|
||||
case ps_running:
|
||||
const char* CPluginMngr::CPlugin::getStatus() const
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ps_running:
|
||||
{
|
||||
if (m_Debug)
|
||||
{
|
||||
if (m_Debug)
|
||||
{
|
||||
return "debug";
|
||||
} else {
|
||||
return "running";
|
||||
}
|
||||
break;
|
||||
return "debug";
|
||||
} else {
|
||||
return "running";
|
||||
}
|
||||
case ps_paused: return "paused";
|
||||
case ps_bad_load: return "bad load";
|
||||
case ps_stopped: return "stopped";
|
||||
case ps_locked: return "locked";
|
||||
break;
|
||||
}
|
||||
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, int d) : name(n), title(n) {
|
||||
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n)
|
||||
{
|
||||
const char* unk = "unknown";
|
||||
|
||||
title.assign(unk);
|
||||
author.assign(unk);
|
||||
version.assign(unk);
|
||||
|
||||
char file[256];
|
||||
char* path = build_pathname_r(file, sizeof(file)-1, "%s/%s",p,n);
|
||||
char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
|
||||
code = 0;
|
||||
memset(&amx, 0, sizeof(AMX));
|
||||
int err = load_amxscript(&amx,&code,path,e, d);
|
||||
if ( err == AMX_ERR_NONE )
|
||||
int err = load_amxscript(&amx, &code, path, e, d);
|
||||
|
||||
if (err == AMX_ERR_NONE)
|
||||
{
|
||||
status = ps_running;
|
||||
} else {
|
||||
status = ps_bad_load;
|
||||
}
|
||||
amx.userdata[3] = this;
|
||||
|
||||
amx.userdata[UD_FINDPLUGIN] = this;
|
||||
paused_fun = 0;
|
||||
next = 0;
|
||||
id = i;
|
||||
|
||||
if (status == ps_running)
|
||||
{
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||
|
||||
if (amx.flags & AMX_FLAG_DEBUG)
|
||||
{
|
||||
m_Debug = true;
|
||||
@ -214,45 +255,108 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
|
||||
}
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin::~CPlugin( )
|
||||
CPluginMngr::CPlugin::~CPlugin()
|
||||
{
|
||||
unload_amxscript( &amx, &code );
|
||||
unload_amxscript(&amx, &code);
|
||||
}
|
||||
|
||||
int AMXAPI native_handler(AMX *amx, int index)
|
||||
{
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
char name[sNAMEMAX + 1];
|
||||
amx_GetNative(amx, index, name);
|
||||
|
||||
return pHandler->HandleNative(name, index, 0);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
||||
{
|
||||
//A script has accidentally called an invalid native! give them a
|
||||
// first chance to block the resulting error.
|
||||
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
//this should never happen
|
||||
if (!pHandler)
|
||||
{
|
||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//this should never happen because this native won't be called
|
||||
// if the plugin isn't filtering.
|
||||
if (!pHandler->IsNativeFiltering())
|
||||
{
|
||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char name[sNAMEMAX + 1];
|
||||
int native = amx->usertags[UT_NATIVE];
|
||||
int err = amx_GetNative(amx, native, name);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
name[0] = '\0';
|
||||
|
||||
//1 - because we're trapping usage
|
||||
if (!pHandler->HandleNative(name, native, 1))
|
||||
{
|
||||
LogError(amx, AMX_ERR_INVNATIVE, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Someday maybe allow native filters to write their own return value?
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::Finalize()
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
int old_status = status;
|
||||
|
||||
if (CheckModules(&amx, buffer))
|
||||
{
|
||||
if ( amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE )
|
||||
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
|
||||
{
|
||||
status = ps_bad_load;
|
||||
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
|
||||
int res = 0;
|
||||
|
||||
if (pHandler->IsNativeFiltering())
|
||||
res = amx_CheckNatives(&amx, native_handler);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
status = ps_bad_load;
|
||||
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
} else {
|
||||
amx_RegisterToAny(&amx, invalid_native);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = ps_bad_load;
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
if (old_status != status)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::pauseFunction( int id )
|
||||
void CPluginMngr::CPlugin::pauseFunction(int id)
|
||||
{
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::unpauseFunction( int id )
|
||||
void CPluginMngr::CPlugin::unpauseFunction(int id)
|
||||
{
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::setStatus( int a ) {
|
||||
void CPluginMngr::CPlugin::setStatus(int a)
|
||||
{
|
||||
status = a;
|
||||
g_commands.clearBufforedInfo(); // ugly way
|
||||
}
|
||||
@ -276,8 +380,8 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
||||
if (isValid())
|
||||
{
|
||||
// set status first so the function will be marked executable
|
||||
|
||||
setStatus(ps_running);
|
||||
|
||||
// call plugin_unpause if provided
|
||||
if (m_UnpauseFwd != -1)
|
||||
executeForwards(m_UnpauseFwd);
|
||||
|
@ -36,18 +36,18 @@
|
||||
// class CPluginMngr
|
||||
// *****************************************************
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
ps_bad_load,
|
||||
ps_error,
|
||||
ps_paused,
|
||||
ps_running,
|
||||
ps_stopped,
|
||||
ps_locked,
|
||||
ps_paused,
|
||||
ps_stopped,
|
||||
ps_running,
|
||||
};
|
||||
|
||||
class CPluginMngr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
class iterator;
|
||||
@ -59,23 +59,25 @@ public:
|
||||
|
||||
AMX amx;
|
||||
void* code;
|
||||
|
||||
String name;
|
||||
String version;
|
||||
String title;
|
||||
String author;
|
||||
String errorMsg;
|
||||
|
||||
int m_PauseFwd;
|
||||
int m_UnpauseFwd;
|
||||
int paused_fun;
|
||||
int status;
|
||||
CPlugin* next;
|
||||
int id;
|
||||
CPlugin(int i , const char* p,const char* n, char* e, int d);
|
||||
~CPlugin( );
|
||||
|
||||
CPlugin(int i, const char* p, const char* n, char* e, int d);
|
||||
~CPlugin();
|
||||
|
||||
bool m_Debug;
|
||||
|
||||
public:
|
||||
|
||||
inline const char* getName() { return name.c_str();}
|
||||
inline const char* getVersion() { return version.c_str();}
|
||||
inline const char* getTitle() { return title.c_str();}
|
||||
@ -85,20 +87,21 @@ public:
|
||||
inline int getId() const { return id; }
|
||||
inline AMX* getAMX() { return &amx; }
|
||||
inline const AMX* getAMX() const { return &amx; }
|
||||
inline void setTitle( const char* n ) { title.assign(n); }
|
||||
inline void setAuthor( const char* n ) { author.assign(n); }
|
||||
inline void setVersion( const char* n ) { version.assign(n); }
|
||||
inline void setError( const char* n ) { errorMsg.assign(n); }
|
||||
inline bool isValid() const { return ((status == ps_running || status == ps_paused)); }
|
||||
inline bool isPaused() const { return ( (status == ps_paused) ); }
|
||||
//inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||
inline void setTitle(const char* n) { title.assign(n); }
|
||||
inline void setAuthor(const char* n) { author.assign(n); }
|
||||
inline void setVersion(const char* n) { version.assign(n); }
|
||||
inline void setError(const char* n) { errorMsg.assign(n); }
|
||||
inline bool isValid() const { return (status >= ps_paused); }
|
||||
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||
|
||||
void Finalize();
|
||||
void pausePlugin();
|
||||
void unpausePlugin();
|
||||
void pauseFunction( int id );
|
||||
void unpauseFunction( int id );
|
||||
void setStatus( int a );
|
||||
void pauseFunction(int id);
|
||||
void unpauseFunction(int id);
|
||||
void setStatus(int a);
|
||||
|
||||
const char* getStatus() const;
|
||||
inline bool isDebug() const { return m_Debug; }
|
||||
};
|
||||
@ -106,8 +109,6 @@ public:
|
||||
private:
|
||||
CPlugin *head;
|
||||
int pCounter;
|
||||
|
||||
|
||||
public:
|
||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||
~CPluginMngr() { clear(); }
|
||||
@ -118,17 +119,20 @@ public:
|
||||
// Interface
|
||||
|
||||
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
||||
void unloadPlugin( CPlugin** a );
|
||||
int loadPluginsFromFile( const char* filename );
|
||||
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 Finalize();
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
class iterator
|
||||
{
|
||||
CPlugin *a;
|
||||
public:
|
||||
iterator(CPlugin*aa) : a(aa) {}
|
||||
@ -138,10 +142,9 @@ public:
|
||||
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
|
||||
|
||||
|
||||
#endif //PLUGIN_H
|
||||
|
@ -45,14 +45,17 @@ public:
|
||||
item = i;
|
||||
next = n;
|
||||
}
|
||||
|
||||
CQueueItem *GetNext()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
T & GetItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
void SetNext(CQueueItem *n)
|
||||
{
|
||||
next = n;
|
||||
@ -71,7 +74,7 @@ public:
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return ((mSize==0)?true:false);
|
||||
return ((mSize == 0) ? true : false);
|
||||
}
|
||||
|
||||
void push(const T &v)
|
||||
@ -119,8 +122,8 @@ public:
|
||||
private:
|
||||
CQueueItem *mFirst;
|
||||
CQueueItem *mLast;
|
||||
|
||||
unsigned int mSize;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CQUEUE_H
|
||||
|
||||
|
@ -43,27 +43,32 @@ public:
|
||||
T item;
|
||||
CStackItem *prev;
|
||||
};
|
||||
|
||||
public:
|
||||
CStack()
|
||||
{
|
||||
mSize = 0;
|
||||
mStack = NULL;
|
||||
}
|
||||
|
||||
~CStack()
|
||||
{
|
||||
CStackItem *p, *t;
|
||||
p = mStack;
|
||||
|
||||
while (p)
|
||||
{
|
||||
t = p->prev;
|
||||
delete p;
|
||||
p = t;
|
||||
}
|
||||
|
||||
mStack = NULL;
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return (mSize==0);
|
||||
return (mSize == 0);
|
||||
}
|
||||
|
||||
void push(const T & v)
|
||||
@ -98,4 +103,3 @@ private:
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CQUEUE_H
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "CTask.h"
|
||||
|
||||
/*********************** CTask ***********************/
|
||||
|
||||
int CTaskMngr::CTask::getTaskId() const
|
||||
{
|
||||
return m_iId;
|
||||
@ -57,12 +58,15 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
||||
{
|
||||
m_bLoop = true;
|
||||
m_iRepeat = -1;
|
||||
} else if (iFlags & 1) {
|
||||
}
|
||||
else if (iFlags & 1)
|
||||
{
|
||||
m_bLoop = true;
|
||||
m_iRepeat = iRepeat;
|
||||
}
|
||||
m_bAfterStart = (iFlags & 4) ? true : false;
|
||||
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
||||
|
||||
m_bAfterStart = (iFlags & 4) ? true : false;
|
||||
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
||||
|
||||
m_fNextExecTime = fCurrentTime + m_fBase;
|
||||
|
||||
@ -98,10 +102,10 @@ void CTaskMngr::CTask::clear()
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
m_bBeforeEnd = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
}
|
||||
@ -123,8 +127,9 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
|
||||
|
||||
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
|
||||
{
|
||||
bool execute=false;
|
||||
bool done=false;
|
||||
bool execute = false;
|
||||
bool done = false;
|
||||
|
||||
if (m_bAfterStart)
|
||||
{
|
||||
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
|
||||
@ -134,14 +139,16 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
||||
{
|
||||
if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase)
|
||||
execute = true;
|
||||
} else if (m_fNextExecTime <= fCurrentTime) {
|
||||
}
|
||||
else if (m_fNextExecTime <= fCurrentTime)
|
||||
{
|
||||
execute = true;
|
||||
}
|
||||
|
||||
if (execute)
|
||||
{
|
||||
//only bother calling if we have something to call
|
||||
if ( !(m_bLoop && !m_iRepeat) )
|
||||
if (!(m_bLoop && !m_iRepeat))
|
||||
{
|
||||
if (m_iParamLen) // call with parameters
|
||||
{
|
||||
@ -182,10 +189,10 @@ CTaskMngr::CTask::CTask()
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
m_bBeforeEnd = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
|
||||
@ -199,6 +206,7 @@ CTaskMngr::CTask::~CTask()
|
||||
}
|
||||
|
||||
/*********************** CTaskMngr ***********************/
|
||||
|
||||
CTaskMngr::CTaskMngr()
|
||||
{
|
||||
m_pTmr_CurrentTime = NULL;
|
||||
@ -222,17 +230,18 @@ void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlag
|
||||
{
|
||||
// first, search for free tasks
|
||||
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
||||
|
||||
if (iter)
|
||||
{
|
||||
// found: reuse it
|
||||
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// not found: make a new one
|
||||
CTask *pTmp = new CTask;
|
||||
|
||||
if (!pTmp)
|
||||
return;
|
||||
|
||||
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||
m_Tasks.put(pTmp);
|
||||
}
|
||||
@ -242,13 +251,15 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
|
||||
{
|
||||
CTaskDescriptor descriptor(iId, pAmx);
|
||||
TaskListIter iter = m_Tasks.find(descriptor);
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
while (iter)
|
||||
{
|
||||
iter->clear();
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
iter->clear();
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -256,14 +267,16 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
|
||||
{
|
||||
CTaskDescriptor descriptor(iId, pAmx);
|
||||
TaskListIter iter = m_Tasks.find(descriptor);
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
while (iter)
|
||||
{
|
||||
iter->changeBase(fNewBase);
|
||||
iter->resetNextExecTime(*m_pTmr_CurrentTime);
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
iter->changeBase(fNewBase);
|
||||
iter->resetNextExecTime(*m_pTmr_CurrentTime);
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -39,34 +39,37 @@ private:
|
||||
class CTask
|
||||
{
|
||||
// task settings
|
||||
|
||||
CPluginMngr::CPlugin *m_pPlugin;
|
||||
int m_iId;
|
||||
int m_iFunc;
|
||||
int m_iRepeat;
|
||||
|
||||
bool m_bLoop;
|
||||
bool m_bAfterStart;
|
||||
bool m_bBeforeEnd;
|
||||
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
|
||||
int m_iParamLen;
|
||||
|
||||
cell *m_pParams;
|
||||
bool m_bFree;
|
||||
|
||||
// execution
|
||||
float m_fNextExecTime;
|
||||
public:
|
||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||
void clear();
|
||||
bool isFree() const;
|
||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||
void clear();
|
||||
bool isFree() const;
|
||||
|
||||
CPluginMngr::CPlugin *getPlugin() const;
|
||||
int getTaskId() const;
|
||||
CPluginMngr::CPlugin *getPlugin() const;
|
||||
int getTaskId() const;
|
||||
|
||||
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
||||
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
||||
|
||||
void changeBase(float fNewBase);
|
||||
void resetNextExecTime(float fCurrentTime);
|
||||
void changeBase(float fNewBase);
|
||||
void resetNextExecTime(float fCurrentTime);
|
||||
|
||||
bool shouldRepeat();
|
||||
bool shouldRepeat();
|
||||
|
||||
CTask();
|
||||
~CTask();
|
||||
@ -91,16 +94,16 @@ private:
|
||||
if (right.m_bFree)
|
||||
return left.isFree();
|
||||
|
||||
return !left.isFree() &&
|
||||
(right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) &&
|
||||
left.getTaskId() == right.m_iId;
|
||||
return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
|
||||
}
|
||||
};
|
||||
|
||||
/*** CTaskMngr priv members ***/
|
||||
typedef CList<CTask, CTaskDescriptor> TaskList;
|
||||
typedef TaskList::iterator TaskListIter;
|
||||
|
||||
TaskList m_Tasks;
|
||||
|
||||
float *m_pTmr_CurrentTime;
|
||||
float *m_pTmr_TimeLimit;
|
||||
float *m_pTmr_TimeLeft;
|
||||
@ -110,13 +113,13 @@ public:
|
||||
|
||||
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
|
||||
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
||||
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
|
||||
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
|
||||
|
||||
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
|
||||
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
|
||||
bool taskExists(int iId, AMX *pAmx);
|
||||
|
||||
void startFrame();
|
||||
void clear();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //CTASK_H
|
||||
|
@ -39,46 +39,47 @@
|
||||
// *****************************************************
|
||||
// class Vault
|
||||
// *****************************************************
|
||||
bool Vault::exists( const char* k )
|
||||
{
|
||||
if ( *k == 0 ) return false;
|
||||
|
||||
return *find( k ) != 0;
|
||||
bool Vault::exists(const char* k)
|
||||
{
|
||||
if (*k == 0) return false;
|
||||
|
||||
return *find(k) != 0;
|
||||
}
|
||||
|
||||
void Vault::put( const char* k, const char* v )
|
||||
void Vault::put(const char* k, const char* v)
|
||||
{
|
||||
if ( *k == 0 ) return;
|
||||
if (*k == 0) return;
|
||||
|
||||
if ( *v == 0 )
|
||||
if (*v == 0)
|
||||
{
|
||||
remove( k );
|
||||
remove(k);
|
||||
return;
|
||||
}
|
||||
|
||||
Obj** a = find( k );
|
||||
Obj** a = find(k);
|
||||
|
||||
if ( *a )
|
||||
if (*a)
|
||||
{
|
||||
(*a)->value.assign(v);
|
||||
(*a)->number = atoi( v );
|
||||
(*a)->number = atoi(v);
|
||||
}
|
||||
else
|
||||
*a = new Obj( k , v );
|
||||
|
||||
*a = new Obj(k, v);
|
||||
}
|
||||
|
||||
Vault::Obj::Obj( const char* k, const char* v): key(k) , value(v) , next(0) {
|
||||
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 )
|
||||
Vault::Obj** Vault::find(const char* n)
|
||||
{
|
||||
Obj** a = &head;
|
||||
|
||||
while( *a )
|
||||
while (*a)
|
||||
{
|
||||
if ( strcmp((*a)->key.c_str(), n) == 0 )
|
||||
if (strcmp((*a)->key.c_str(), n) == 0)
|
||||
return a;
|
||||
|
||||
a = &(*a)->next;
|
||||
@ -88,90 +89,89 @@ Vault::Obj** Vault::find( const char* n )
|
||||
}
|
||||
|
||||
|
||||
int Vault::get_number( const char* n )
|
||||
int Vault::get_number(const char* n)
|
||||
{
|
||||
if ( *n == 0 ) return 0;
|
||||
if (*n == 0) return 0;
|
||||
|
||||
Obj* b = *find( n );
|
||||
Obj* b = *find(n);
|
||||
|
||||
if ( b == 0 ) return 0;
|
||||
if (b == 0) return 0;
|
||||
|
||||
return b->number;
|
||||
}
|
||||
|
||||
const char* Vault::get( const char* n )
|
||||
const char* Vault::get(const char* n)
|
||||
{
|
||||
if ( *n == 0 ) return "";
|
||||
if (*n == 0) return "";
|
||||
|
||||
Obj* b = *find( n );
|
||||
Obj* b = *find(n);
|
||||
|
||||
if ( b == 0 ) return "";
|
||||
if (b == 0) return "";
|
||||
|
||||
return b->value.c_str();
|
||||
}
|
||||
|
||||
void Vault::clear()
|
||||
{
|
||||
while ( head )
|
||||
while (head)
|
||||
{
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
void Vault::remove( const char* n )
|
||||
void Vault::remove(const char* n)
|
||||
{
|
||||
Obj** b = find( n );
|
||||
Obj** b = find(n);
|
||||
|
||||
if ( *b == 0 ) return;
|
||||
if (*b == 0) return;
|
||||
|
||||
Obj* a = (*b)->next;
|
||||
delete *b;
|
||||
*b = a;
|
||||
}
|
||||
|
||||
void Vault::setSource( const char* n )
|
||||
void Vault::setSource(const char* n)
|
||||
{
|
||||
path.assign(n);
|
||||
}
|
||||
|
||||
|
||||
bool Vault::loadVault( )
|
||||
bool Vault::loadVault()
|
||||
{
|
||||
if ( path.empty() ) return false;
|
||||
if (path.empty()) return false;
|
||||
|
||||
clear();
|
||||
|
||||
File a( path.c_str() , "r" );
|
||||
File a(path.c_str(), "r");
|
||||
|
||||
if ( !a ) return false;
|
||||
if (!a) return false;
|
||||
|
||||
const int sz = 512;
|
||||
char value[sz+1];
|
||||
char key[sz+1];
|
||||
char value[sz + 1];
|
||||
char key[sz + 1];
|
||||
|
||||
while ( a >> key && a.skipWs() && a.getline( value , sz ) )
|
||||
while (a >> key && a.skipWs() && a.getline(value, sz))
|
||||
{
|
||||
if ( isalpha ( *key ) )
|
||||
put( key, value );
|
||||
if (isalpha(*key))
|
||||
put(key, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool Vault::saveVault( )
|
||||
bool Vault::saveVault()
|
||||
{
|
||||
if ( path.empty() ) return false;
|
||||
if (path.empty()) return false;
|
||||
|
||||
File a( path.c_str() , "w" );
|
||||
File a(path.c_str(), "w");
|
||||
|
||||
if ( !a ) return false;
|
||||
if (!a) return false;
|
||||
|
||||
a << "; Don't modify!" << '\n';
|
||||
|
||||
for (Obj* b = head; b ;b = b->next)
|
||||
for (Obj* b = head; b; b = b->next)
|
||||
a << b->key << '\t' << b->value << '\n';
|
||||
|
||||
return true;
|
||||
|
@ -41,53 +41,55 @@
|
||||
|
||||
class Vault
|
||||
{
|
||||
struct Obj
|
||||
{
|
||||
String key;
|
||||
String value;
|
||||
int number;
|
||||
Obj *next;
|
||||
Obj( const char* k, const char* v);
|
||||
} *head;
|
||||
struct Obj
|
||||
{
|
||||
String key;
|
||||
String value;
|
||||
|
||||
String path;
|
||||
int number;
|
||||
Obj *next;
|
||||
Obj(const char* k, const char* v);
|
||||
} *head;
|
||||
|
||||
Obj** find( const char* n );
|
||||
String path;
|
||||
|
||||
Obj** find(const char* n);
|
||||
|
||||
public:
|
||||
|
||||
Vault() {head=0;}
|
||||
~Vault() { clear();}
|
||||
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();
|
||||
bool exists(const char* k);
|
||||
|
||||
void put(const char* k, const char* v);
|
||||
void remove(const char* k);
|
||||
|
||||
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; }
|
||||
};
|
||||
const char* get(const char* n);
|
||||
int get_number(const char* n);
|
||||
void setSource(const char* n);
|
||||
|
||||
inline iterator begin() const { return iterator(head); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
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
|
||||
|
||||
|
||||
|
||||
#endif //VAULT_CUSTOM_H
|
||||
|
@ -70,32 +70,58 @@ template <class T> class CVector
|
||||
// change size
|
||||
if (size == m_Size)
|
||||
return true;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
m_Size = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
T *newData = new T[size];
|
||||
if (!newData)
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
size_t end = (m_Size < size) ? (m_Size) : size;
|
||||
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
|
||||
for (size_t i=0; i<end; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
if (m_Size < size)
|
||||
m_CurrentSize = size;
|
||||
m_Data = newData;
|
||||
m_Size = size;
|
||||
if (m_CurrentUsedSize > m_Size)
|
||||
m_CurrentUsedSize = m_Size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeMemIfPossible()
|
||||
{
|
||||
if (!m_Data)
|
||||
return;
|
||||
|
||||
if (!m_CurrentUsedSize)
|
||||
{
|
||||
ChangeSize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t newSize = m_Size;
|
||||
while (m_CurrentUsedSize <= newSize / 2)
|
||||
newSize /= 2;
|
||||
|
||||
if (newSize != m_Size)
|
||||
ChangeSize(newSize);
|
||||
}
|
||||
protected:
|
||||
T *m_Data;
|
||||
size_t m_Size;
|
||||
size_t m_CurrentUsedSize;
|
||||
size_t m_CurrentSize;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
@ -189,7 +215,7 @@ public:
|
||||
|
||||
iterator & operator-=(size_t offset)
|
||||
{
|
||||
m_Ptr += offset;
|
||||
m_Ptr -= offset;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
@ -203,7 +229,7 @@ public:
|
||||
iterator operator-(size_t offset) const
|
||||
{
|
||||
iterator tmp(*this);
|
||||
tmp.m_Ptr += offset;
|
||||
tmp.m_Ptr -= offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -277,12 +303,12 @@ public:
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Data);
|
||||
}
|
||||
|
||||
iterator end()
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Data + m_CurrentUsedSize);
|
||||
}
|
||||
@ -296,7 +322,9 @@ public:
|
||||
|
||||
bool reserve(size_t newSize)
|
||||
{
|
||||
return ChangeSize(newSize);
|
||||
if (newSize > m_Size)
|
||||
return ChangeSize(newSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool push_back(const T & elem)
|
||||
@ -317,14 +345,15 @@ public:
|
||||
--m_CurrentUsedSize;
|
||||
if (m_CurrentUsedSize < 0)
|
||||
m_CurrentUsedSize = 0;
|
||||
// :TODO: free memory sometimes
|
||||
|
||||
FreeMemIfPossible();
|
||||
}
|
||||
|
||||
bool resize(size_t newSize)
|
||||
{
|
||||
if (!ChangeSize(newSize))
|
||||
return false;
|
||||
FreeMemIfPossible();
|
||||
m_CurrentUsedSize = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -397,15 +426,13 @@ public:
|
||||
return m_Data[m_CurrentUsedSize - 1];
|
||||
}
|
||||
|
||||
bool insert(iterator where, const T & value)
|
||||
iterator insert(iterator where, const T & value)
|
||||
{
|
||||
// we have to insert before
|
||||
// if it is begin, don't decrement
|
||||
if (where != m_Data)
|
||||
--where;
|
||||
// validate iter
|
||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||
return false;
|
||||
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
@ -414,33 +441,49 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data));
|
||||
memcpy(where.base(), &value, sizeof(T));
|
||||
return true;
|
||||
where = begin() + ofs;
|
||||
|
||||
// Move subsequent entries
|
||||
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
|
||||
*(ptr + 1) = *ptr;
|
||||
|
||||
*where.base() = value;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
void erase(iterator where)
|
||||
iterator erase(iterator where)
|
||||
{
|
||||
// validate iter
|
||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||
return false;
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
if (m_CurrentUsedSize > 1)
|
||||
{
|
||||
// move
|
||||
memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1);
|
||||
T *theend = m_Data + m_CurrentUsedSize;
|
||||
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
|
||||
*(ptr - 1) = *ptr;
|
||||
}
|
||||
|
||||
--m_CurrentUsedSize;
|
||||
// :TODO: free memory sometimes
|
||||
|
||||
FreeMemIfPossible();
|
||||
|
||||
return begin() + ofs;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_Size = 0;
|
||||
m_CurrentUsedSize = 0;
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -pipe
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = amxmodx_mm
|
||||
@ -15,7 +15,7 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
|
||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
||||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp
|
||||
|
||||
LINK = -lz
|
||||
|
||||
|
116
amxmodx/amx.cpp
116
amxmodx/amx.cpp
@ -425,10 +425,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
AMX_FUNCSTUB *func;
|
||||
AMX_NATIVE f;
|
||||
|
||||
assert(amx!=NULL);
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr!=NULL);
|
||||
assert(hdr->magic==AMX_MAGIC);
|
||||
assert(hdr->natives<=hdr->libraries);
|
||||
#if defined AMX_NATIVETABLE
|
||||
if (index<NULL) {
|
||||
@ -444,34 +441,10 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
#endif
|
||||
assert(f!=NULL);
|
||||
|
||||
/* Now that we have found the function, patch the program so that any
|
||||
* subsequent call will call the function directly (bypassing this
|
||||
* callback).
|
||||
* This trick cannot work in the JIT, because the program would need to
|
||||
* be re-JIT-compiled after patching a P-code instruction.
|
||||
/* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
|
||||
* Otherwise, we'd have no way of knowing the last native to be used.
|
||||
*/
|
||||
#if defined JIT && !defined NDEBUG
|
||||
if ((amx->flags & AMX_FLAG_JITC)!=0)
|
||||
assert(amx->sysreq_d==0);
|
||||
#endif
|
||||
if (amx->sysreq_d!=0) {
|
||||
/* at the point of the call, the CIP pseudo-register points directly
|
||||
* behind the SYSREQ instruction and its parameter.
|
||||
*/
|
||||
unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4;
|
||||
assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod));
|
||||
assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */
|
||||
#if defined __GNUC__ || defined ASM32
|
||||
if (*(cell*)code==index) {
|
||||
#else
|
||||
if (*(cell*)code!=OP_SYSREQ_PRI) {
|
||||
assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C);
|
||||
assert(*(cell*)code==index);
|
||||
#endif
|
||||
*(cell*)(code-sizeof(cell))=amx->sysreq_d;
|
||||
*(cell*)code=(cell)f;
|
||||
} /* if */
|
||||
} /* if */
|
||||
amx->usertags[UT_NATIVE] = (long)index;
|
||||
|
||||
/* Note:
|
||||
* params[0] == number of bytes for the additional parameters passed to the native function
|
||||
@ -480,7 +453,9 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
*/
|
||||
|
||||
amx->error=AMX_ERR_NONE;
|
||||
|
||||
*result = f(amx,params);
|
||||
|
||||
return amx->error;
|
||||
}
|
||||
#endif /* defined AMX_INIT */
|
||||
@ -547,6 +522,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
*/
|
||||
if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell))
|
||||
amx->sysreq_d=opcode_list[OP_SYSREQ_D];
|
||||
amx->userdata[UD_OPCODELIST] = (void *)opcode_list;
|
||||
#else
|
||||
/* ANSI C
|
||||
* to use direct system requests, a function pointer must fit in a cell;
|
||||
@ -554,6 +530,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
*/
|
||||
if (sizeof(AMX_NATIVE)<=sizeof(cell))
|
||||
amx->sysreq_d=OP_SYSREQ_D;
|
||||
amx->userdata[UD_OPCODELIST] = (long)NULL;
|
||||
#endif
|
||||
|
||||
/* start browsing code */
|
||||
@ -1563,6 +1540,61 @@ static AMX_NATIVE findfunction(const char *name, const AMX_NATIVE_INFO *list, in
|
||||
}
|
||||
|
||||
const char *no_function;
|
||||
|
||||
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf)
|
||||
{
|
||||
AMX_FUNCSTUB *func;
|
||||
AMX_HEADER *hdr;
|
||||
int i,numnatives,res=0;
|
||||
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr!=NULL);
|
||||
assert(hdr->magic==AMX_MAGIC);
|
||||
assert(hdr->natives<=hdr->libraries);
|
||||
numnatives=NUMENTRIES(hdr,natives,libraries);
|
||||
|
||||
func=GETENTRY(hdr,natives,0);
|
||||
for (i=0; i<numnatives; i++) {
|
||||
if (func->address==0) {
|
||||
/* this function is not yet located */
|
||||
res=nf(amx,i);
|
||||
if (!res)
|
||||
{
|
||||
no_function = GETENTRYNAME(hdr,func);
|
||||
return 0;
|
||||
}
|
||||
} /* if */
|
||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
||||
} /* for */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f)
|
||||
{
|
||||
AMX_FUNCSTUB *func;
|
||||
AMX_HEADER *hdr;
|
||||
int i,numnatives,err;
|
||||
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr!=NULL);
|
||||
assert(hdr->magic==AMX_MAGIC);
|
||||
assert(hdr->natives<=hdr->libraries);
|
||||
numnatives=NUMENTRIES(hdr,natives,libraries);
|
||||
|
||||
err=AMX_ERR_NONE;
|
||||
func=GETENTRY(hdr,natives,0);
|
||||
for (i=0; i<numnatives; i++) {
|
||||
if (func->address==0) {
|
||||
/* this function is not yet located */
|
||||
func->address=(ucell)f;
|
||||
} /* if */
|
||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
||||
} /* for */
|
||||
if (err==AMX_ERR_NONE)
|
||||
amx->flags|=AMX_FLAG_NTVREG;
|
||||
return err;
|
||||
}
|
||||
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
||||
{
|
||||
AMX_FUNCSTUB *func;
|
||||
@ -1676,7 +1708,13 @@ int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char
|
||||
#define SKIPPARAM(n) ( cip=(cell *)cip+(n) )
|
||||
#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||
#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
||||
#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; }
|
||||
#define ABORT(amx,v) { (amx)->stk=reset_stk; \
|
||||
(amx)->hea=reset_hea; \
|
||||
(amx)->cip=(cell)cip; \
|
||||
(amx)->pri=pri; \
|
||||
(amx)->alt=alt; \
|
||||
return v; \
|
||||
}
|
||||
|
||||
#define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR
|
||||
#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW
|
||||
@ -2471,6 +2509,8 @@ static const void * const amx_opcodelist[] = {
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
if (num==AMX_ERR_SLEEP) {
|
||||
@ -2490,6 +2530,8 @@ static const void * const amx_opcodelist[] = {
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
if (num==AMX_ERR_SLEEP) {
|
||||
@ -2509,6 +2551,8 @@ static const void * const amx_opcodelist[] = {
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
||||
if (amx->error!=AMX_ERR_NONE) {
|
||||
if (amx->error==AMX_ERR_SLEEP) {
|
||||
@ -2578,6 +2622,8 @@ static const void * const amx_opcodelist[] = {
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->hea=hea;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
amx->cip=(cell)((unsigned char*)cip-code);
|
||||
num=amx->debug(amx);
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
@ -3445,6 +3491,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
if (num==AMX_ERR_SLEEP) {
|
||||
@ -3464,6 +3512,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
if (num==AMX_ERR_SLEEP) {
|
||||
@ -3483,6 +3533,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
amx->hea=hea;
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
||||
if (amx->error!=AMX_ERR_NONE) {
|
||||
if (amx->error==AMX_ERR_SLEEP) {
|
||||
@ -3546,6 +3598,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
amx->frm=frm;
|
||||
amx->stk=stk;
|
||||
amx->hea=hea;
|
||||
amx->pri=pri;
|
||||
amx->alt=alt;
|
||||
amx->cip=(cell)((unsigned char*)cip-code);
|
||||
num=amx->debug(amx);
|
||||
if (num!=AMX_ERR_NONE) {
|
||||
|
@ -166,6 +166,7 @@ typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||
cell *result, cell *params);
|
||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
||||
#if !defined _FAR
|
||||
#define _FAR
|
||||
#endif
|
||||
@ -242,6 +243,7 @@ typedef struct tagAMX {
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||
//we're also gonna set userdata[2] to a special debug structure
|
||||
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
@ -300,6 +302,7 @@ enum {
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
AMX_ERR_INVNATIVE, /* invalid native was used */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
@ -335,23 +338,11 @@ enum {
|
||||
#define AMX_COMPACTMARGIN 64
|
||||
#endif
|
||||
|
||||
struct amx_trace
|
||||
{
|
||||
cell frm;
|
||||
amx_trace *prev;
|
||||
amx_trace *next;
|
||||
bool used;
|
||||
};
|
||||
|
||||
struct AMX_DBGINFO
|
||||
{
|
||||
void *pDebug; //Pointer to debug data
|
||||
int error; //non-amx_Exec() error setting
|
||||
amx_trace *pTrace; //Pointer to stack trace
|
||||
amx_trace *pTraceFrm;
|
||||
amx_trace *pTraceEnd;
|
||||
cell frm;
|
||||
};
|
||||
#define UD_FINDPLUGIN 3
|
||||
#define UD_DEBUGGER 2
|
||||
#define UD_OPCODELIST 1
|
||||
#define UD_HANDLER 0
|
||||
#define UT_NATIVE 3
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
@ -385,6 +376,7 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||
#endif
|
||||
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_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf);
|
||||
int AMXAPI amx_Cleanup(AMX *amx);
|
||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||
@ -414,6 +406,7 @@ int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
|
||||
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);
|
||||
|
@ -129,6 +129,28 @@
|
||||
jg near err_stack
|
||||
%endmacro
|
||||
|
||||
;Normal abort, saves pri/alt
|
||||
%macro _ABORT 1
|
||||
mov ebp,amx
|
||||
mov [ebp+_pri], dword eax ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_alt], dword edx ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_error], dword %1
|
||||
jmp _return
|
||||
%endmacro
|
||||
|
||||
;Checked abort, saves nothing and uses a conditional
|
||||
%macro _CHKABORT 1
|
||||
mov ebp,amx
|
||||
mov [ebp+_error], %1
|
||||
cmp %1, AMX_ERR_NONE
|
||||
jne _return
|
||||
%endmacro
|
||||
|
||||
;Fast abort, only aborts, nothing else
|
||||
%macro _FASTABORT 0
|
||||
jmp _return
|
||||
%endmacro
|
||||
|
||||
%macro _CHKHEAP 0
|
||||
mov ebp,amx
|
||||
mov ebp,[ebp+_hlw]
|
||||
@ -1196,8 +1218,7 @@ OP_HALT:
|
||||
mov eax,esi ; EAX=CIP
|
||||
sub eax,code
|
||||
mov [ebp+_cip],eax
|
||||
mov eax,ebx ; return the parameter of the HALT opcode
|
||||
jmp _return
|
||||
_ABORT ebx
|
||||
|
||||
|
||||
OP_BOUNDS:
|
||||
@ -1221,6 +1242,7 @@ OP_SYSREQ_PRI:
|
||||
mov alt,edx ; save ALT
|
||||
|
||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM)
|
||||
;we don't save regs since they're useless after this
|
||||
mov ecx,hea
|
||||
mov ebx,frm
|
||||
mov [ebp+_hea],ecx
|
||||
@ -1251,8 +1273,7 @@ OP_SYSREQ_PRI:
|
||||
pop edi ; restore saved registers
|
||||
pop esi
|
||||
pop ebp
|
||||
cmp eax,AMX_ERR_NONE
|
||||
jne near _return ; return error code, if any
|
||||
_CHKABORT eax ; if result was invalid, leave
|
||||
|
||||
mov eax,pri ; get retval into eax (PRI)
|
||||
mov edx,alt ; restore ALT
|
||||
@ -1293,8 +1314,8 @@ OP_SYSREQ_D: ; (TR)
|
||||
pop edi ; restore saved registers
|
||||
pop esi
|
||||
pop ebp
|
||||
cmp DWORD [ebp+_error],AMX_ERR_NONE
|
||||
jne near _return ; return error code, if any
|
||||
mov eax,[ebp+_error]
|
||||
_CHKABORT eax
|
||||
|
||||
; function result is in eax (PRI)
|
||||
mov edx,alt ; restore ALT
|
||||
@ -1416,7 +1437,7 @@ OP_BREAK:
|
||||
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
||||
_RESTOREREGS ; abort run, but restore stack first
|
||||
mov eax,[ebp+_error] ; get error code in EAX back again
|
||||
jmp _return ; return error code
|
||||
_FASTABORT
|
||||
break_noabort:
|
||||
_RESTOREREGS
|
||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||
@ -1425,43 +1446,34 @@ OP_BREAK:
|
||||
|
||||
|
||||
OP_INVALID:
|
||||
mov eax,AMX_ERR_INVINSTR
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_INVINSTR
|
||||
|
||||
err_call:
|
||||
mov eax,AMX_ERR_CALLBACK
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_CALLBACK
|
||||
|
||||
err_stack:
|
||||
mov eax,AMX_ERR_STACKERR
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_STACKERR
|
||||
|
||||
err_stacklow:
|
||||
mov eax,AMX_ERR_STACKLOW
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_STACKLOW
|
||||
|
||||
err_memaccess:
|
||||
mov eax,AMX_ERR_MEMACCESS
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_MEMACCESS
|
||||
|
||||
err_bounds:
|
||||
mov eax,AMX_ERR_BOUNDS
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_BOUNDS
|
||||
|
||||
err_heaplow:
|
||||
mov eax,AMX_ERR_HEAPLOW
|
||||
jmp _return
|
||||
_ABORT AMX_ERR_HEAPLOW
|
||||
|
||||
err_divide:
|
||||
mov eax,AMX_ERR_DIVIDE
|
||||
jmp _return
|
||||
|
||||
_ABORT AMX_ERR_DIVIDE
|
||||
|
||||
_return:
|
||||
; save a few parameters, mostly for the "sleep"function
|
||||
mov ebp,amx ; get amx into ebp
|
||||
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT)
|
||||
mov [ebp+_cip],esi ; get corrected cip for amxmodx
|
||||
mov eax,[ebp+_error]; get error code
|
||||
|
||||
pop esi ; remove FRM from stack
|
||||
|
||||
|
4004
amxmodx/amxmodx.cpp
4004
amxmodx/amxmodx.cpp
File diff suppressed because it is too large
Load Diff
@ -32,20 +32,19 @@
|
||||
#ifndef AMXMODX_H
|
||||
#define AMXMODX_H
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "sclinux.h"
|
||||
#endif
|
||||
#include <ctype.h> //tolower, etc
|
||||
#include <ctype.h> //tolower, etc
|
||||
#include "string.h"
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "mm_pextensions.h" // metamod-p extensions
|
||||
#include "mm_pextensions.h" // metamod-p extensions
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
@ -69,32 +68,31 @@
|
||||
#include "amxxlog.h"
|
||||
|
||||
#define AMXXLOG_Log g_log.Log
|
||||
#define AMX_VERSION "1.55"
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
extern AMX_NATIVE_INFO power_Natives[];
|
||||
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[];
|
||||
#define AMX_VERSION "1.60"
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
extern AMX_NATIVE_INFO power_Natives[];
|
||||
extern AMX_NATIVE_INFO amxmodx_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 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 DLPROC(m, func) dlsym(m, func)
|
||||
#define DLFREE(m) dlclose(m)
|
||||
#endif
|
||||
|
||||
#ifndef __linux__
|
||||
typedef HINSTANCE DLHANDLE;
|
||||
typedef HINSTANCE DLHANDLE;
|
||||
#else
|
||||
typedef void* DLHANDLE;
|
||||
typedef void* DLHANDLE;
|
||||
#endif
|
||||
|
||||
#ifndef GETPLAYERAUTHID
|
||||
@ -110,32 +108,35 @@ typedef void* DLHANDLE;
|
||||
|
||||
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_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_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 );
|
||||
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);
|
||||
|
||||
char *UTIL_VarArgs(const char *fmt, ...);
|
||||
|
||||
|
||||
#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(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 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;
|
||||
struct fakecmd_t
|
||||
{
|
||||
char args[256];
|
||||
const char *argv[3];
|
||||
int argc;
|
||||
bool fake;
|
||||
};
|
||||
|
||||
extern bool g_IsNewMM;
|
||||
@ -150,7 +151,8 @@ extern CList<CCVar> g_cvars;
|
||||
extern CList<ForceObject> g_forcemodels;
|
||||
extern CList<ForceObject> g_forcesounds;
|
||||
extern CList<ForceObject> g_forcegeneric;
|
||||
extern CList<CModule,const char *> g_modules;
|
||||
extern CList<CModule, const char *> g_modules;
|
||||
extern CList<CScript, AMX*> g_loadedscripts;
|
||||
extern CList<CPlayer*> g_auth;
|
||||
extern EventsMngr g_events;
|
||||
extern Grenades g_grenades;
|
||||
@ -161,7 +163,7 @@ extern String g_log_dir;
|
||||
extern String g_mod_name;
|
||||
extern TeamIds g_teamsIds;
|
||||
extern Vault g_vault;
|
||||
extern CForwardMngr g_forwards;
|
||||
extern CForwardMngr g_forwards;
|
||||
extern WeaponsVault g_weaponsData[MAX_WEAPONS];
|
||||
extern XVars g_xvars;
|
||||
extern bool g_bmod_cstrike;
|
||||
@ -176,6 +178,7 @@ extern float g_game_restarting;
|
||||
extern float g_game_timeleft;
|
||||
extern float g_task_time;
|
||||
extern float g_auth_time;
|
||||
extern bool g_NewDLL_Available;
|
||||
extern hudtextparms_t g_hudset;
|
||||
//extern int g_edict_point;
|
||||
extern int g_players_num;
|
||||
@ -224,14 +227,15 @@ void Client_DeathMsg(void*);
|
||||
void amx_command();
|
||||
void plugin_srvcmd();
|
||||
|
||||
const char* stristr(const char* a,const char* b);
|
||||
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, PLUG_LOADTIME now);
|
||||
void detachModules();
|
||||
void detachReloadModules();
|
||||
|
||||
#ifdef FAKEMETA
|
||||
void attachModules();
|
||||
void attachModules();
|
||||
#endif
|
||||
|
||||
// Count modules
|
||||
@ -245,40 +249,43 @@ enum CountModulesMode
|
||||
int countModules(CountModulesMode mode);
|
||||
void modules_callPluginsLoaded();
|
||||
|
||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||
char* build_pathname(char *fmt, ... );
|
||||
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
||||
char* build_pathname(char *fmt, ...);
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
|
||||
AMX* get_amxscript(int, void**,const char**);
|
||||
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);
|
||||
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 debug);
|
||||
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);
|
||||
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 print_srvconsole(char *fmt, ...);
|
||||
void report_error(int code, char* fmt, ...);
|
||||
void* alloc_amxmemory(void**, int size);
|
||||
void free_amxmemory(void **ptr);
|
||||
// get_localinfo
|
||||
const char* get_localinfo( const char* name , const char* def );
|
||||
const char* get_localinfo(const char* name, const char* def);
|
||||
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
|
||||
void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
|
||||
enum ModuleCallReason
|
||||
{
|
||||
ModuleCall_NotCalled = 0, // nothing
|
||||
ModuleCall_Query, // in Query func
|
||||
ModuleCall_Attach, // in Attach func
|
||||
ModuleCall_Detach, // in Detach func
|
||||
ModuleCall_NotCalled = 0, // nothing
|
||||
ModuleCall_Query, // in Query func
|
||||
ModuleCall_Attach, // in Attach func
|
||||
ModuleCall_Detach, // in Detach func
|
||||
};
|
||||
|
||||
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||
|
||||
void Module_CacheFunctions();
|
||||
void Module_UncacheFunctions();
|
||||
|
||||
@ -301,7 +308,7 @@ extern int FF_ClientAuthorized;
|
||||
extern bool g_coloredmenus;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
#endif
|
||||
|
||||
struct func_s
|
||||
@ -311,4 +318,3 @@ struct func_s
|
||||
};
|
||||
|
||||
#endif // AMXMODX_H
|
||||
|
||||
|
@ -35,19 +35,20 @@
|
||||
/**********************
|
||||
****** AMXXFILE ******
|
||||
**********************/
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if defined __linux__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#else
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct TableEntry
|
||||
@ -73,6 +74,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
{
|
||||
m_Bh.plugins = NULL;
|
||||
m_AmxxFile = false;
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
m_Status = Err_InvalidParam;
|
||||
@ -81,8 +83,8 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
|
||||
m_Status = Err_None;
|
||||
m_CellSize = cellsize;
|
||||
|
||||
m_pFile = fopen(filename, "rb");
|
||||
|
||||
if (!m_pFile)
|
||||
{
|
||||
m_Status = Err_FileOpen;
|
||||
@ -93,28 +95,37 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
DATAREAD(&magic, sizeof(magic), 1);
|
||||
|
||||
m_OldFile = false;
|
||||
if ( magic == 0x524C4542 ) {
|
||||
|
||||
if (magic == 0x524C4542)
|
||||
{
|
||||
//we have an invalid, old, RLEB file
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
} else if ( magic == MAGIC_HEADER2 ) {
|
||||
}
|
||||
else if (magic == MAGIC_HEADER2)
|
||||
{
|
||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
||||
|
||||
if (m_Bh.version != MAGIC_VERSION)
|
||||
{
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_AmxxFile = true;
|
||||
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
||||
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
||||
PluginEntry *pe;
|
||||
m_SectionHdrOffset = 0;
|
||||
m_Entry = -1;
|
||||
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
||||
@ -123,26 +134,32 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->offs, sizeof(int32_t), 1);
|
||||
}
|
||||
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
|
||||
if (pe->cellsize == m_CellSize)
|
||||
{
|
||||
m_Entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Entry == -1)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pe = &(m_Bh.plugins[m_Entry]);
|
||||
m_SectionLength = pe->disksize;
|
||||
} else if (magic == MAGIC_HEADER) {
|
||||
|
||||
}
|
||||
else if (magic == MAGIC_HEADER)
|
||||
{
|
||||
// try to find the section
|
||||
mint8_t numOfPlugins;
|
||||
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
|
||||
@ -151,6 +168,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
|
||||
m_SectionHdrOffset = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
|
||||
{
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
@ -160,6 +178,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SectionHdrOffset)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
@ -169,15 +188,13 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
}
|
||||
|
||||
// compute section length
|
||||
if ((i+1) < static_cast<int>(numOfPlugins))
|
||||
if ((i + 1) < static_cast<int>(numOfPlugins))
|
||||
{
|
||||
// there is a next section
|
||||
TableEntry nextEntry;
|
||||
DATAREAD(&nextEntry, sizeof(nextEntry), 1);
|
||||
m_SectionLength = nextEntry.offset - entry.offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fseek(m_pFile, 0, SEEK_END);
|
||||
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
|
||||
}
|
||||
@ -187,6 +204,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
rewind(m_pFile);
|
||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||
amx_Align16(&hdr.magic);
|
||||
|
||||
if (hdr.magic == AMX_MAGIC)
|
||||
{
|
||||
if (cellsize != 4)
|
||||
@ -194,18 +212,19 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_OldFile = true;
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// no known file format
|
||||
m_Status = Err_FileInvalid;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -218,6 +237,7 @@ CAmxxReader::~CAmxxReader()
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
if (m_Bh.plugins)
|
||||
{
|
||||
delete [] m_Bh.plugins;
|
||||
@ -256,11 +276,16 @@ size_t CAmxxReader::GetBufferSize()
|
||||
AMX_HEADER hdr;
|
||||
DATAREAD(&hdr, sizeof(hdr), 1);
|
||||
fseek(m_pFile, save, SEEK_SET);
|
||||
|
||||
return hdr.stp;
|
||||
} else if (m_AmxxFile) {
|
||||
}
|
||||
else if (m_AmxxFile)
|
||||
{
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
|
||||
if (pe->imagesize > pe->memsize)
|
||||
return pe->imagesize + 1;
|
||||
|
||||
return pe->memsize + 1;
|
||||
}
|
||||
|
||||
@ -269,6 +294,7 @@ size_t CAmxxReader::GetBufferSize()
|
||||
TableEntry entry;
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
fseek(m_pFile, save, SEEK_SET);
|
||||
|
||||
return entry.origSize + 1; // +1 : safe
|
||||
}
|
||||
|
||||
@ -298,22 +324,26 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
||||
rewind(m_pFile);
|
||||
DATAREAD(buffer, 1, filesize);
|
||||
m_Status = Err_None;
|
||||
|
||||
return m_Status;
|
||||
} else if (m_AmxxFile) {
|
||||
}
|
||||
else if (m_AmxxFile)
|
||||
{
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
char *tempBuffer = new char[m_SectionLength + 1];
|
||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
||||
uLongf destLen = GetBufferSize();
|
||||
int result = uncompress((Bytef *)buffer, &destLen,
|
||||
(Bytef *)tempBuffer, m_SectionLength);
|
||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
return Err_Decompress;
|
||||
}
|
||||
|
||||
return Err_None;
|
||||
} else {
|
||||
// new file type: go to the section table entry
|
||||
@ -328,15 +358,17 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||
// decompress
|
||||
int result = uncompress((Bytef *)buffer, &destLen,
|
||||
(Bytef *)tempBuffer, m_SectionLength);
|
||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
|
||||
return Err_Decompress;
|
||||
}
|
||||
|
||||
return Err_None;
|
||||
}
|
||||
}
|
||||
|
@ -95,4 +95,3 @@ public:
|
||||
};
|
||||
|
||||
#endif // __AMXXFILE_H__
|
||||
|
||||
|
@ -36,12 +36,12 @@
|
||||
|
||||
#include <time.h>
|
||||
#ifndef __linux__
|
||||
#include <io.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifndef __linux__
|
||||
#define vsnprintf _vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
CLog::CLog()
|
||||
@ -61,6 +61,7 @@ void CLog::CloseFile()
|
||||
if (!m_LogFile.empty())
|
||||
{
|
||||
FILE *fp = fopen(m_LogFile.c_str(), "r");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
@ -77,6 +78,7 @@ void CLog::CloseFile()
|
||||
fprintf(fp, "L %s: %s\n", date, "Log file closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
m_LogFile.clear();
|
||||
}
|
||||
}
|
||||
@ -84,29 +86,33 @@ void CLog::CloseFile()
|
||||
void CLog::CreateNewFile()
|
||||
{
|
||||
CloseFile();
|
||||
|
||||
// build filename
|
||||
time_t td;
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||
|
||||
if (!pTmpFile)
|
||||
break;
|
||||
|
||||
fclose(pTmpFile);
|
||||
++i;
|
||||
}
|
||||
|
||||
// Log logfile start
|
||||
FILE *fp = fopen(m_LogFile.c_str(), "w");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
|
||||
SET_LOCALINFO("amxx_logging", "0");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
|
||||
fclose(fp);
|
||||
}
|
||||
@ -123,12 +129,13 @@ void CLog::MapChange()
|
||||
// create dir if not existing
|
||||
char file[256];
|
||||
#ifdef __linux
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()), 0700);
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
|
||||
#else
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()));
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
|
||||
#endif
|
||||
|
||||
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
|
||||
|
||||
if (m_LogType < 0 || m_LogType > 3)
|
||||
{
|
||||
SET_LOCALINFO("amxx_logging", "1");
|
||||
@ -143,7 +150,7 @@ void CLog::MapChange()
|
||||
}
|
||||
else if (m_LogType == 1)
|
||||
{
|
||||
Log("-------- Mapchange --------");
|
||||
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
|
||||
}
|
||||
else
|
||||
return;
|
||||
@ -152,6 +159,7 @@ void CLog::MapChange()
|
||||
void CLog::Log(const char *fmt, ...)
|
||||
{
|
||||
static char file[256];
|
||||
|
||||
if (m_LogType == 1 || m_LogType == 2)
|
||||
{
|
||||
// get time
|
||||
@ -178,6 +186,7 @@ void CLog::Log(const char *fmt, ...)
|
||||
{
|
||||
CreateNewFile();
|
||||
pF = fopen(m_LogFile.c_str(), "a+");
|
||||
|
||||
if (!pF)
|
||||
{
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
|
||||
@ -185,19 +194,16 @@ void CLog::Log(const char *fmt, ...)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
|
||||
pF = fopen(file, "a+");
|
||||
}
|
||||
|
||||
if (pF)
|
||||
{
|
||||
fprintf(pF, "L %s: %s\n", date, msg);
|
||||
fclose(pF);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
|
||||
m_LogType = 0;
|
||||
return;
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
public:
|
||||
CLog();
|
||||
~CLog();
|
||||
|
||||
void CreateNewFile();
|
||||
void CloseFile();
|
||||
void MapChange();
|
||||
@ -49,4 +50,3 @@ public:
|
||||
};
|
||||
|
||||
#endif // __AMXXLOG_H__
|
||||
|
||||
|
1230
amxmodx/debugger.cpp
Executable file
1230
amxmodx/debugger.cpp
Executable file
File diff suppressed because it is too large
Load Diff
201
amxmodx/debugger.h
Executable file
201
amxmodx/debugger.h
Executable file
@ -0,0 +1,201 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_DEBUGGER_H_
|
||||
#define _INCLUDE_DEBUGGER_H_
|
||||
|
||||
#include "CVector.h"
|
||||
#include "amxdbg.h"
|
||||
|
||||
/**
|
||||
* Third revision of the AMX Mod X Plugin Debugger.
|
||||
* This final, object oriented version is safe for multiple calls and lets you
|
||||
* fine-tune error handling.
|
||||
* -BAILOPAN
|
||||
*/
|
||||
class Debugger
|
||||
{
|
||||
public:
|
||||
class Tracer
|
||||
{
|
||||
public:
|
||||
|
||||
struct trace_info
|
||||
{
|
||||
trace_info() : cip(0), frm(0), used(false), next(NULL), prev(NULL) {};
|
||||
|
||||
cell cip;
|
||||
cell frm;
|
||||
|
||||
trace_info *next;
|
||||
trace_info *prev;
|
||||
|
||||
bool used;
|
||||
};
|
||||
|
||||
public:
|
||||
Tracer() : m_Error(0), m_pStart(NULL), m_pEnd(NULL), m_Reset(true) {};
|
||||
~Tracer();
|
||||
public:
|
||||
void StepI(cell frm, cell cip);
|
||||
void Reset();
|
||||
void Clear();
|
||||
|
||||
Debugger::Tracer::trace_info *GetStart() const;
|
||||
Debugger::Tracer::trace_info *GetEnd() const;
|
||||
public:
|
||||
int m_Error;
|
||||
private:
|
||||
trace_info *m_pStart;
|
||||
trace_info *m_pEnd;
|
||||
|
||||
bool m_Reset;
|
||||
};
|
||||
|
||||
public:
|
||||
Debugger(AMX *pAmx, AMX_DBG *pAmxDbg) : m_pAmx(pAmx), m_pAmxDbg(pAmxDbg), m_Top(-1)
|
||||
{
|
||||
_CacheAmxOpcodeList();
|
||||
};
|
||||
~Debugger();
|
||||
public:
|
||||
//Begin a trace for a function
|
||||
void BeginExec();
|
||||
|
||||
//Step through one instruction
|
||||
void StepI();
|
||||
|
||||
//Get/set the last traced error
|
||||
int GetTracedError();
|
||||
void SetTracedError(int error);
|
||||
|
||||
//Get the first trace info of the call stack
|
||||
Debugger::Tracer::trace_info *GetTraceStart() const;
|
||||
|
||||
//Get extra info about the call stack
|
||||
bool GetTraceInfo(Debugger::Tracer::trace_info *pTraceInfo, long &line, const char *&function, const char *&file);
|
||||
|
||||
//Get the next trace in the call stack, NULL if none
|
||||
Debugger::Tracer::trace_info *GetNextTrace(Debugger::Tracer::trace_info *pTraceInfo);
|
||||
|
||||
//Returns true if an error exists
|
||||
bool ErrorExists();
|
||||
|
||||
//Formats the error message into a buffer.
|
||||
//returns length of data copied, or -1 if there is no error.
|
||||
int FormatError(char *buffer, size_t maxLength);
|
||||
|
||||
//End a trace
|
||||
void EndExec();
|
||||
|
||||
//Reset the internal states as if the debugger was inactive
|
||||
void Reset();
|
||||
|
||||
//Destroy internal states for shutdown
|
||||
void Clear();
|
||||
|
||||
void DisplayTrace(const char *message);
|
||||
|
||||
AMX *GetAMX() const { return m_pAmx; }
|
||||
public:
|
||||
//generic static opcode breaker
|
||||
static int AMXAPI DebugHook(AMX *amx);
|
||||
|
||||
static void FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength);
|
||||
static void GenericMessage(AMX *amx, int error);
|
||||
private:
|
||||
void _CacheAmxOpcodeList();
|
||||
|
||||
int _GetOpcodeFromCip(cell cip, cell *&addr);
|
||||
cell _CipAsVa(cell cip);
|
||||
|
||||
const char *_GetFilename();
|
||||
public:
|
||||
AMX *m_pAmx;
|
||||
AMX_DBG *m_pAmxDbg;
|
||||
|
||||
int m_Top;
|
||||
cell *m_pOpcodeList;
|
||||
String m_FileName;
|
||||
|
||||
CVector<Tracer *> m_pCalls;
|
||||
};
|
||||
|
||||
typedef Debugger::Tracer::trace_info trace_info_t;
|
||||
|
||||
/**
|
||||
* Error handler for plugins
|
||||
*/
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
Handler(AMX *pAmx) : m_pAmx(pAmx), m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1), m_Handling(false), m_InNativeFilter(false) {};
|
||||
~Handler() {};
|
||||
public:
|
||||
int SetErrorHandler(const char *function);
|
||||
int SetNativeFilter(const char *function);
|
||||
int SetModuleFilter(const char *function);
|
||||
public:
|
||||
int HandleError(const char *msg);
|
||||
int HandleNative(const char *native, int index, int trap);
|
||||
int HandleModule(const char *module);
|
||||
public:
|
||||
bool IsHandling() const { return m_Handling; }
|
||||
void SetErrorMsg(const char *msg);
|
||||
|
||||
const char *GetLastMsg();
|
||||
trace_info_t *GetTrace() const { return m_pTrace; }
|
||||
const char *GetFmtCache() { return m_FmtCache.c_str(); }
|
||||
|
||||
bool IsNativeFiltering() { return (m_iNatFunc > 0); }
|
||||
bool InNativeFilter() { return m_InNativeFilter; }
|
||||
private:
|
||||
AMX *m_pAmx;
|
||||
|
||||
int m_iErrFunc;
|
||||
int m_iModFunc;
|
||||
int m_iNatFunc;
|
||||
|
||||
bool m_Handling;
|
||||
|
||||
//in the future, make this a stack!
|
||||
bool m_InNativeFilter;
|
||||
|
||||
String m_MsgCache;
|
||||
String m_FmtCache;
|
||||
|
||||
trace_info_t *m_pTrace;
|
||||
};
|
||||
|
||||
extern AMX_NATIVE_INFO g_DebugNatives[];
|
||||
|
||||
#endif //_INCLUDE_DEBUGGER_H_
|
367
amxmodx/emsg.cpp
367
amxmodx/emsg.cpp
@ -57,197 +57,224 @@ 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;
|
||||
}
|
||||
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 );
|
||||
}
|
||||
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.assign( msg );
|
||||
g_teamsIds.registerTeam( msg , -1 );
|
||||
}
|
||||
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.assign(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;
|
||||
}
|
||||
}
|
||||
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.0f;
|
||||
|
||||
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;
|
||||
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.assign(wpnName);
|
||||
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;
|
||||
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.assign(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;
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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.c_str() , pPlayer->teamId );
|
||||
}
|
||||
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.c_str(), pPlayer->teamId);
|
||||
}
|
||||
}
|
||||
|
||||
void Client_DamageEnd(void* mValue)
|
||||
{
|
||||
CPlayer* dead = mPlayer;
|
||||
|
||||
if ( dead && dead->death_killer )
|
||||
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.c_str() );
|
||||
g_events.parseValue( dead->death_tk ? 1 : 0 );
|
||||
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.c_str());
|
||||
g_events.parseValue(dead->death_tk ? 1 : 0);
|
||||
g_events.executeEvents();
|
||||
dead->death_killer = 0;
|
||||
}
|
||||
@ -261,28 +288,25 @@ void Client_DeathMsg(void* mValue)
|
||||
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.assign((char*)mValue);
|
||||
victim->death_headshot = hs;
|
||||
victim->death_tk = (killer->teamId == victim->teamId);
|
||||
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.assign((char*)mValue);
|
||||
victim->death_headshot = hs;
|
||||
victim->death_tk = (killer->teamId == victim->teamId);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -313,4 +337,3 @@ void Client_ResetHUD(void* mValue)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -32,8 +32,8 @@
|
||||
#define __FAKEMETA_H__
|
||||
|
||||
#ifndef FAKEMETA
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
#else
|
||||
// Fake metamod api for modules
|
||||
|
||||
@ -42,11 +42,12 @@ int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
// from mplugin.h (metamod)
|
||||
// Flags to indicate current "load" state of plugin.
|
||||
// NOTE: order is important, as greater/less comparisons are made.
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
PL_EMPTY = 0, // empty slot
|
||||
PL_VALID, // has valid info in it
|
||||
PL_BADFILE, // nonexistent file (open failed),
|
||||
// or not a valid plugin file (query failed)
|
||||
// or not a valid plugin file (query failed)
|
||||
PL_OPENED, // dlopened and queried
|
||||
PL_FAILED, // opened, but failed to attach or unattach
|
||||
PL_RUNNING, // attached and running
|
||||
@ -55,11 +56,10 @@ typedef enum {
|
||||
|
||||
// from h_export.h (metamod)
|
||||
// Our GiveFnptrsToDll, called by engine.
|
||||
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t
|
||||
*pengfuncsFromEngine, globalvars_t *pGlobals);
|
||||
|
||||
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals);
|
||||
|
||||
// *** CFakeMeta
|
||||
|
||||
class CFakeMeta
|
||||
{
|
||||
private:
|
||||
@ -100,7 +100,6 @@ public:
|
||||
inline void SetStatus(PLUG_STATUS newStatus)
|
||||
{ m_Status = newStatus; }
|
||||
|
||||
|
||||
inline plugin_info_t * GetInfo()
|
||||
{ return m_Info; }
|
||||
inline const plugin_info_t * GetInfo() const
|
||||
@ -232,4 +231,3 @@ extern CFakeMeta g_FakeMeta;
|
||||
#endif //FAKEMETA
|
||||
|
||||
#endif // #ifndef __FAKEMETA_H__
|
||||
|
||||
|
600
amxmodx/file.cpp
600
amxmodx/file.cpp
File diff suppressed because it is too large
Load Diff
1685
amxmodx/meta_api.cpp
1685
amxmodx/meta_api.cpp
File diff suppressed because it is too large
Load Diff
1020
amxmodx/modules.cpp
1020
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -36,10 +36,10 @@
|
||||
|
||||
#undef DLLEXPORT
|
||||
#ifndef __linux__
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#define WINAPI
|
||||
#define DLLEXPORT
|
||||
#define WINAPI
|
||||
#endif
|
||||
|
||||
#undef C_DLLEXPORT
|
||||
@ -49,5 +49,6 @@
|
||||
#define STATIC_MODULE 1
|
||||
|
||||
int CheckModules(AMX *amx, char error[128]);
|
||||
const char *StrCaseStr(const char *as, const char *bs);
|
||||
|
||||
#endif // __MODULES_H__
|
||||
|
@ -42,12 +42,13 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||
AdditionalDependencies="..\JIT\natives-x86.obj ..\zlib\zlib.lib"
|
||||
OutputFile="debug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
||||
@ -639,6 +640,9 @@
|
||||
<File
|
||||
RelativePath="..\CVault.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\emsg.cpp">
|
||||
</File>
|
||||
@ -797,6 +801,9 @@
|
||||
<File
|
||||
RelativePath="..\CVector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.h">
|
||||
</File>
|
||||
|
@ -266,8 +266,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||
|
||||
int size = params[3];
|
||||
|
||||
while (size-->0)
|
||||
*dest = *source;
|
||||
memcpy(dest, source, size * sizeof(cell));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -293,8 +292,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||
|
||||
int size = params[3];
|
||||
|
||||
while (size-->0)
|
||||
*dest = *source;
|
||||
memcpy(dest, source, size * sizeof(cell));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -424,7 +422,7 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
|
||||
{"get_param", get_param},
|
||||
{"get_param_byref", get_param_byref},
|
||||
{"set_param_byref", set_param_byref},
|
||||
{"get_array", set_array},
|
||||
{"get_array", get_array},
|
||||
{"set_array", set_array},
|
||||
//these are dummy functions for floats ;p
|
||||
{"get_param_f", get_param},
|
||||
|
@ -1,3 +1,33 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "newmenus.h"
|
||||
|
||||
@ -5,8 +35,9 @@ CVector<Menu *> g_NewMenus;
|
||||
|
||||
void ClearMenus()
|
||||
{
|
||||
for (size_t i=0; i<g_NewMenus.size(); i++)
|
||||
for (size_t i = 0; i < g_NewMenus.size(); i++)
|
||||
delete g_NewMenus[i];
|
||||
|
||||
g_NewMenus.clear();
|
||||
}
|
||||
|
||||
@ -19,8 +50,9 @@ Menu::Menu(const char *title, int mid, int tid)
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
for (size_t i=0; i<m_Items.size(); i++)
|
||||
for (size_t i = 0; i < m_Items.size(); i++)
|
||||
delete m_Items[i];
|
||||
|
||||
m_Items.clear();
|
||||
}
|
||||
|
||||
@ -80,16 +112,21 @@ int Menu::PagekeyToItem(page_t page, item_t key)
|
||||
if (page == 0)
|
||||
{
|
||||
item_t rem = numItems >= 7 ? 7 : numItems;
|
||||
|
||||
if (key == rem)
|
||||
{
|
||||
if (pages > 1)
|
||||
return MENU_MORE;
|
||||
else
|
||||
return MENU_EXIT;
|
||||
} else if (key == rem+1) {
|
||||
}
|
||||
else if (key == rem + 1)
|
||||
{
|
||||
return MENU_EXIT;
|
||||
}
|
||||
} else if (page == pages - 1) {
|
||||
}
|
||||
else if (page == pages - 1)
|
||||
{
|
||||
//find number of remaining items
|
||||
//for example, 11 items on page 1... means start=7, 11-7=4
|
||||
item_t rem = numItems - start;
|
||||
@ -97,14 +134,18 @@ int Menu::PagekeyToItem(page_t page, item_t key)
|
||||
if (key == rem)
|
||||
{
|
||||
return MENU_EXIT;
|
||||
} else if (key == rem+1) {
|
||||
}
|
||||
else if (key == rem + 1)
|
||||
{
|
||||
return MENU_BACK;
|
||||
}
|
||||
} else {
|
||||
if (key == 7)
|
||||
{
|
||||
return MENU_MORE;
|
||||
} else if (key == 8) {
|
||||
}
|
||||
else if (key == 8)
|
||||
{
|
||||
return MENU_BACK;
|
||||
}
|
||||
}
|
||||
@ -147,9 +188,10 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
|
||||
char buffer[255];
|
||||
if (g_coloredmenus)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page+1, pages);
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page+1, pages);
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
item_t start = page * 7;
|
||||
@ -162,15 +204,19 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
}
|
||||
|
||||
menuitem *pItem = NULL;
|
||||
|
||||
int option = 0;
|
||||
keys = 0;
|
||||
bool enabled = true;
|
||||
int ret = 0;
|
||||
for (item_t i=start; i<end; i++)
|
||||
|
||||
for (item_t i = start; i < end; i++)
|
||||
{
|
||||
pItem = m_Items[i];
|
||||
|
||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
||||
enabled = false;
|
||||
|
||||
if (pItem->handler != -1)
|
||||
{
|
||||
ret = executeForwards(pItem->handler, player, thisId, i);
|
||||
@ -179,6 +225,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (pItem->pfn)
|
||||
{
|
||||
ret = (pItem->pfn)(player, thisId, i);
|
||||
@ -187,6 +234,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
keys |= (1<<option);
|
||||
@ -202,6 +250,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
|
||||
//now for a weird part >:o
|
||||
//this will either be MORE or BACK..
|
||||
keys |= (1<<option++);
|
||||
@ -211,7 +260,9 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||
}
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
if (pages > 1)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
@ -241,6 +292,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
|
||||
if (func == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
||||
@ -248,7 +300,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
}
|
||||
|
||||
int id = g_menucmds.registerMenuId(title, amx);
|
||||
g_menucmds.registerMenuCmd( g_plugins.findPluginFast(amx), id, 1023, func );
|
||||
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
|
||||
|
||||
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
|
||||
g_NewMenus.push_back(pMenu);
|
||||
@ -365,54 +417,54 @@ static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *name;
|
||||
int len;
|
||||
char *name;
|
||||
|
||||
name = get_amxstring(amx, params[3], 0, len);
|
||||
name = get_amxstring(amx, params[3], 0, len);
|
||||
|
||||
pItem->name.assign(name);
|
||||
pItem->name.assign(name);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *cmd;
|
||||
int len;
|
||||
char *cmd;
|
||||
|
||||
cmd = get_amxstring(amx, params[3], 0, len);
|
||||
cmd = get_amxstring(amx, params[3], 0, len);
|
||||
|
||||
pItem->cmd.assign(cmd);
|
||||
pItem->cmd.assign(cmd);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
pItem->handler = params[3];
|
||||
pItem->handler = params[3];
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
||||
|
@ -1,14 +1,45 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NEWMENUS_H
|
||||
#define _INCLUDE_NEWMENUS_H
|
||||
|
||||
#define MENU_EXIT -3
|
||||
#define MENU_BACK -2
|
||||
#define MENU_MORE -1
|
||||
#define MENU_EXIT -3
|
||||
#define MENU_BACK -2
|
||||
#define MENU_MORE -1
|
||||
#define ITEM_IGNORE 0
|
||||
#define ITEM_ENABLED 1
|
||||
#define ITEM_DISABLED 2
|
||||
|
||||
#define MENUITEMS 7
|
||||
#define MENUITEMS 7
|
||||
|
||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
||||
|
||||
@ -16,33 +47,40 @@ struct menuitem
|
||||
{
|
||||
String name;
|
||||
String cmd;
|
||||
|
||||
int access;
|
||||
int handler;
|
||||
|
||||
MENUITEM_CALLBACK pfn;
|
||||
size_t id;
|
||||
};
|
||||
|
||||
typedef unsigned int menu_t;
|
||||
typedef unsigned int item_t;
|
||||
typedef unsigned int page_t;
|
||||
typedef unsigned int menu_t;
|
||||
typedef unsigned int item_t;
|
||||
typedef unsigned int page_t;
|
||||
|
||||
class Menu
|
||||
{
|
||||
public:
|
||||
Menu(const char *title, int menuId, int thisId);
|
||||
~Menu();
|
||||
|
||||
menuitem *GetMenuItem(item_t item);
|
||||
size_t GetPageCount();
|
||||
size_t GetItemCount();
|
||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
||||
|
||||
const char *GetTextString(int player, page_t page, int &keys);
|
||||
bool Display(int player, page_t page);
|
||||
|
||||
int PagekeyToItem(page_t page, item_t key);
|
||||
int GetMenuMenuid();
|
||||
private:
|
||||
CVector<menuitem * > m_Items;
|
||||
|
||||
String m_Title;
|
||||
String m_Text;
|
||||
|
||||
int menuId;
|
||||
int thisId;
|
||||
};
|
||||
|
@ -31,239 +31,217 @@
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
void amx_command(){
|
||||
void amx_command()
|
||||
{
|
||||
const char* cmd = CMD_ARGV(1);
|
||||
|
||||
const char* cmd = CMD_ARGV(1);
|
||||
if (!strcmp(cmd, "plugins") || !strcmp(cmd, "list"))
|
||||
{
|
||||
|
||||
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( "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;
|
||||
}
|
||||
|
||||
a = g_plugins.begin();
|
||||
|
||||
while (a)
|
||||
{
|
||||
if ( (*a).getStatusCode() == ps_bad_load )
|
||||
{
|
||||
//error
|
||||
print_srvconsole("Load fails: %s\n", (*a).getError());
|
||||
}
|
||||
++a;
|
||||
}
|
||||
|
||||
print_srvconsole( "%d plugins, %d running\n",plugins,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;
|
||||
}
|
||||
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
|
||||
|
||||
a = g_plugins.begin();
|
||||
|
||||
while (a)
|
||||
{
|
||||
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);
|
||||
|
||||
if ((*a).getStatusCode() == ps_bad_load)
|
||||
{
|
||||
//error
|
||||
print_srvconsole("Load fails: %s\n", (*a).getError());
|
||||
}
|
||||
++a;
|
||||
}
|
||||
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
|
||||
|
||||
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())
|
||||
{
|
||||
const char* sPlugin = CMD_ARGV(2);
|
||||
|
||||
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
||||
|
||||
if ( plugin && plugin->isValid() && plugin->isPaused() )
|
||||
{
|
||||
plugin->unpausePlugin();
|
||||
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
|
||||
} else if (!plugin) {
|
||||
print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
|
||||
} else {
|
||||
print_srvconsole("Plugin %s can't be unpaused right now.", 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( "Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
||||
print_srvconsole( "Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
#if defined JIT && !defined ASM32
|
||||
print_srvconsole( "Core mode: JIT Only\n");
|
||||
#elif !defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: ASM32 Only\n");
|
||||
#elif defined JIT && defined ASM32
|
||||
print_srvconsole( "Core mode: JIT+ASM32\n");
|
||||
#else
|
||||
print_srvconsole( "Core mode: Normal\n");
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(cmd,"modules"))
|
||||
{
|
||||
print_srvconsole( "Currently loaded modules:\n");
|
||||
print_srvconsole( " %-23.22s %-8.7s %-20.19s %-11.10s\n",
|
||||
"name", "version", "author", "status");
|
||||
|
||||
int running = 0;
|
||||
int modules = 0;
|
||||
|
||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||
|
||||
while ( a )
|
||||
{
|
||||
if ( (*a).getStatusValue() == MODULE_LOADED )
|
||||
++running;
|
||||
|
||||
++modules;
|
||||
|
||||
print_srvconsole( " [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules,
|
||||
(*a).getName(), (*a).getVersion(), (*a).getAuthor() , (*a).getStatus() );
|
||||
|
||||
++a;
|
||||
}
|
||||
|
||||
print_srvconsole( "%d modules, %d correct\n",modules,running);
|
||||
} else if (!strcmp(cmd, "gpl"))
|
||||
{
|
||||
print_srvconsole("AMX Mod X\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" by the AMX Mod X Development Team\n");
|
||||
print_srvconsole(" originally developed by OLO\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" This program is free software; you can redistribute it and/or modify it\n");
|
||||
print_srvconsole(" under the terms of the GNU General Public License as published by the\n");
|
||||
print_srvconsole(" Free Software Foundation; either version 2 of the License, or (at\n");
|
||||
print_srvconsole(" your option) any later version.\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" This program is distributed in the hope that it will be useful, but\n");
|
||||
print_srvconsole(" WITHOUT ANY WARRANTY; without even the implied warranty of\n");
|
||||
print_srvconsole(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n");
|
||||
print_srvconsole(" General Public License for more details.\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" You should have received a copy of the GNU General Public License\n");
|
||||
print_srvconsole(" along with this program; if not, write to the Free Software Foundation,\n");
|
||||
print_srvconsole(" Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" In addition, as a special exception, the author gives permission to\n");
|
||||
print_srvconsole(" link the code of this program with the Half-Life Game Engine (\"HL\n");
|
||||
print_srvconsole(" Engine\") and Modified Game Libraries (\"MODs\") developed by Valve,\n");
|
||||
print_srvconsole(" L.L.C (\"Valve\"). You must obey the GNU General Public License in all\n");
|
||||
print_srvconsole(" respects for all of the code used other than the HL Engine and MODs\n");
|
||||
print_srvconsole(" from Valve. If you modify this file, you may extend this exception\n");
|
||||
print_srvconsole(" to your version of the file, but you are not obligated to do so. If\n");
|
||||
print_srvconsole(" you do not wish to do so, delete this exception statement from your\n");
|
||||
print_srvconsole(" version.\n");
|
||||
print_srvconsole("\n");
|
||||
}
|
||||
else if (!strcmp(cmd, "\x74\x75\x72\x74\x6C\x65")) // !! Hidden Command :D !!
|
||||
{
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x2E\x3A\x3A\x3E\x3E\x3A\x3A\x3B\x3E\x5E\x27\x2E\x27\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x3A\x3A\x3F\x3D\x3E\x3E\x3E\x3E\x3E\x3D\x3F\x3E\x78\x2B\x3F\x3E\x3E\x3E\x3D\x3E\x3F\x2B\x3F\x3E\x3B\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x2C\x3A\x3E\x3B\x3F\x3D\x3E\x3B\x2E\x27\x5E\x5E\x3B\x3B\x2C\x3A\x3F\x3F\x3D\x78\x3F\x3B\x3E\x3A\x3B\x3A\x5E\x3B\x3D\x3E\x2B\x2B\x2B\x2B\x3D\x2C\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x2C\x3E\x37\x24\x24\x78\x3D\x3D\x3D\x3F\x3A\x27\x20\x20\x20\x20\x20\x20\x20\x2E\x3A\x3B\x3D\x3E\x3A\x3A\x3A\x3A\x3F\x3F\x3F\x3E\x5E\x2C\x2E\x2E\x2C\x2C\x2C\x2C\x3A\x3B\x3D\x3D\x3B\x5E\x2C\x2C\x2C\x3A\x5E\x3A\x3F\x3F\x3E\x3D\x3D\x3E\x3E\x2B\x3B\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x2C\x3D\x2B\x3E\x2C\x5E\x3D\x79\x24\x33\x78\x33\x24\x5A\x24\x3B\x20\x20\x3A\x3E\x2B\x3E\x3D\x3F\x5E\x2C\x2C\x2C\x5E\x5E\x3E\x3D\x3E\x3B\x3B\x3A\x5E\x5E\x3E\x3F\x3D\x2B\x37\x3D\x3F\x3E\x3E\x3E\x3F\x3D\x3F\x3F\x3D\x3D\x3D\x3D\x3E\x3F\x3D\x3E\x3E\x3E\x3D\x5A\x78\x3E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x3D\x5A\x24\x37\x78\x66\x68\x78\x5A\x5A\x24\x79\x79\x71\x23\x23\x4D\x71\x3B\x3A\x3B\x3A\x3E\x3B\x3B\x2C\x5E\x3E\x3F\x3D\x3F\x3A\x2C\x2C\x3A\x3B\x3B\x3E\x3E\x3D\x2B\x3D\x3E\x3D\x3B\x3A\x3E\x3D\x2B\x3D\x2B\x37\x2B\x3D\x2B\x37\x37\x2B\x2B\x33\x33\x33\x37\x37\x24\x5A\x79\x3A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x5E\x2B\x5A\x2B\x3E\x3D\x37\x5A\x66\x40\x40\x23\x40\x48\x23\x23\x23\x38\x5E\x3B\x3D\x3F\x2B\x3E\x3B\x3E\x5E\x5E\x2C\x27\x2E\x27\x2E\x2E\x5E\x3F\x3D\x3D\x3F\x3A\x3B\x3A\x3A\x3A\x5E\x5E\x3E\x3E\x3F\x3D\x37\x37\x3D\x3D\x37\x2B\x3D\x37\x2B\x37\x78\x24\x79\x38\x68\x45\x48\x79\x3E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x2C\x3E\x3E\x78\x33\x68\x48\x23\x23\x40\x40\x48\x45\x66\x33\x20\x2C\x3A\x3E\x3E\x3E\x3B\x3B\x3A\x3A\x2C\x2E\x2C\x5E\x3A\x2C\x5E\x3B\x3E\x37\x37\x3F\x3B\x3A\x2E\x3A\x3A\x3B\x3D\x3B\x3B\x3D\x2B\x3D\x78\x33\x37\x3E\x3D\x3D\x2B\x37\x2B\x78\x78\x78\x78\x5A\x66\x71\x68\x38\x45\x27\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x3A\x37\x37\x24\x66\x71\x45\x45\x71\x45\x3A\x3A\x2C\x5E\x3A\x3E\x3A\x3A\x3B\x3B\x5E\x3A\x2C\x5E\x5E\x2C\x2C\x5E\x3A\x3E\x2B\x33\x3D\x3E\x3A\x3A\x3A\x3D\x2B\x2B\x3D\x3F\x3F\x37\x37\x2B\x37\x3D\x3D\x5A\x33\x78\x33\x37\x78\x24\x5A\x33\x37\x38\x40\x71\x38\x66\x40\x2C\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x5A\x45\x40\x5E\x5E\x5E\x3A\x2C\x3A\x3B\x3E\x3A\x5E\x5E\x2C\x2E\x2E\x2C\x5E\x3B\x3B\x3A\x2B\x3E\x3F\x3B\x3F\x3F\x3F\x3F\x3E\x3F\x3D\x37\x3B\x3B\x3D\x33\x2B\x3D\x3D\x78\x78\x5A\x78\x33\x78\x5A\x5A\x5A\x24\x71\x48\x79\x5A\x24\x79\x45\x3E\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x3B\x2C\x2C\x27\x5E\x5E\x2C\x3A\x5E\x3A\x3A\x5E\x3A\x3B\x3F\x3E\x3F\x3E\x3B\x3E\x3E\x3F\x3D\x2B\x37\x37\x2B\x2B\x3D\x2B\x37\x2B\x37\x37\x2B\x3B\x3D\x33\x2B\x2B\x37\x37\x2B\x3D\x78\x78\x66\x78\x78\x37\x33\x66\x78\x38\x23\x23\x27\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x3F\x3B\x5E\x2C\x3B\x3F\x3D\x3F\x3F\x3B\x3A\x3A\x3A\x3E\x3F\x3E\x3E\x3F\x3A\x3F\x33\x78\x78\x33\x24\x24\x33\x2B\x37\x78\x24\x78\x33\x3D\x2B\x2B\x5A\x24\x78\x24\x78\x33\x33\x24\x5A\x79\x24\x24\x24\x68\x45\x48\x38\x68\x45\x40\x3E\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2C\x3A\x3E\x3F\x37\x3D\x3E\x3F\x2B\x3F\x3F\x3E\x3F\x3F\x3F\x3D\x3F\x3E\x3F\x3D\x37\x2B\x3E\x3E\x2B\x37\x37\x33\x37\x33\x78\x33\x33\x33\x78\x37\x37\x37\x78\x5A\x78\x5A\x79\x79\x5A\x24\x79\x79\x79\x79\x79\x68\x71\x38\x38\x71\x23\x23\x45\x37\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x2B\x3F\x2B\x78\x40\x38\x3F\x3B\x3E\x3B\x3B\x3E\x3F\x37\x2B\x3F\x3F\x3D\x3D\x3E\x3F\x2B\x37\x37\x37\x37\x33\x33\x78\x78\x33\x37\x24\x5A\x78\x5A\x5A\x78\x24\x33\x3D\x37\x37\x37\x78\x24\x5A\x78\x37\x37\x78\x66\x79\x66\x71\x66\x40\x45\x40\x3A\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x3A\x3F\x2B\x3D\x2B\x79\x23\x79\x3B\x2C\x3A\x3A\x3A\x37\x78\x3F\x3E\x3B\x3E\x3B\x3E\x3D\x37\x24\x33\x37\x33\x37\x78\x78\x33\x24\x68\x79\x33\x24\x78\x2B\x33\x33\x5A\x79\x24\x5A\x79\x24\x5A\x37\x24\x5A\x5A\x66\x38\x66\x79\x66\x40\x71\x45\x48\x5A\x3A\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x37\x3D\x37\x37\x33\x37\x37\x66\x45\x5A\x3F\x5E\x5E\x78\x37\x3D\x3F\x3E\x3B\x3B\x3E\x2B\x2B\x24\x78\x37\x2B\x37\x2B\x37\x78\x78\x71\x79\x33\x33\x24\x24\x78\x24\x5A\x3F\x37\x78\x24\x78\x79\x66\x5A\x78\x79\x66\x79\x68\x79\x66\x5A\x33\x3F\x3D\x3D\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x3D\x3F\x37\x37\x78\x33\x5A\x4E\x4D\x23\x38\x33\x3F\x3E\x3B\x3E\x3B\x3D\x3D\x33\x66\x24\x78\x33\x2B\x78\x24\x5A\x24\x5A\x71\x79\x78\x33\x33\x78\x79\x5A\x5A\x33\x66\x24\x78\x78\x24\x79\x5A\x24\x79\x5A\x37\x66\x24\x3D\x3B\x66\x23\x4D\x4D\x4D\x79\x3B\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x33\x37\x37\x24\x78\x66\x79\x48\x4D\x4D\x4D\x4D\x23\x71\x68\x5A\x24\x5A\x79\x68\x68\x5A\x5A\x24\x79\x66\x68\x78\x5A\x4E\x45\x66\x66\x45\x45\x45\x24\x5A\x40\x71\x68\x5A\x68\x5A\x37\x66\x79\x78\x37\x78\x37\x68\x38\x38\x71\x48\x40\x23\x45\x3A\x3D\x37\x45\x27\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x37\x37\x78\x37\x33\x38\x45\x45\x71\x20\x5E\x3D\x2B\x3F\x2B\x2B\x79\x71\x45\x48\x40\x45\x45\x45\x45\x45\x71\x40\x40\x71\x38\x38\x79\x66\x38\x68\x48\x48\x45\x66\x37\x2B\x3A\x37\x3F\x3B\x3A\x2C\x27\x2C\x27\x78\x4D\x23\x48\x48\x48\x79\x2B\x3A\x3F\x79\x27\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x78\x78\x24\x40\x4E\x4E\x4D\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x3E\x3E\x3F\x3E\x3E\x3E\x3E\x3B\x3B\x3B\x3A\x3A\x3F\x3E\x3A\x2E\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x45\x4D\x40\x45\x78\x5E\x33\x68\x33\x2B\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x24\x48\x45\x48\x78\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x4E\x40\x2B\x66\x33\x78\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x2C\x20\x3A\x20\x20\n");
|
||||
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->isPaused())
|
||||
{
|
||||
|
||||
|
||||
print_srvconsole("Usage: amxx < command > [ argument ]\n");
|
||||
print_srvconsole("Commands:\n");
|
||||
print_srvconsole(" version - display amxx version info\n");
|
||||
print_srvconsole(" gpl - print the license\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");
|
||||
|
||||
plugin->unpausePlugin();
|
||||
print_srvconsole("Unpaused plugin \"%s\"\n", plugin->getName());
|
||||
}
|
||||
}
|
||||
else if (!plugin)
|
||||
{
|
||||
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
|
||||
} else {
|
||||
print_srvconsole("Plugin %s can't be unpaused right now.", 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("Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
||||
print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__);
|
||||
#if defined JIT && !defined ASM32
|
||||
print_srvconsole("Core mode: JIT Only\n");
|
||||
#elif !defined JIT && defined ASM32
|
||||
print_srvconsole("Core mode: ASM32 Only\n");
|
||||
#elif defined JIT && defined ASM32
|
||||
print_srvconsole("Core mode: JIT+ASM32\n");
|
||||
#else
|
||||
print_srvconsole("Core mode: Normal\n");
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(cmd, "modules"))
|
||||
{
|
||||
print_srvconsole("Currently loaded modules:\n");
|
||||
print_srvconsole(" %-23.22s %-8.7s %-20.19s %-11.10s\n", "name", "version", "author", "status");
|
||||
|
||||
int running = 0;
|
||||
int modules = 0;
|
||||
|
||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||
|
||||
while (a)
|
||||
{
|
||||
if ((*a).getStatusValue() == MODULE_LOADED)
|
||||
++running;
|
||||
++modules;
|
||||
|
||||
print_srvconsole(" [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus());
|
||||
++a;
|
||||
}
|
||||
|
||||
print_srvconsole("%d modules, %d correct\n", modules, running);
|
||||
}
|
||||
else if (!strcmp(cmd, "gpl"))
|
||||
{
|
||||
print_srvconsole("AMX Mod X\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" by the AMX Mod X Development Team\n");
|
||||
print_srvconsole(" originally developed by OLO\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" This program is free software; you can redistribute it and/or modify it\n");
|
||||
print_srvconsole(" under the terms of the GNU General Public License as published by the\n");
|
||||
print_srvconsole(" Free Software Foundation; either version 2 of the License, or (at\n");
|
||||
print_srvconsole(" your option) any later version.\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" This program is distributed in the hope that it will be useful, but\n");
|
||||
print_srvconsole(" WITHOUT ANY WARRANTY; without even the implied warranty of\n");
|
||||
print_srvconsole(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n");
|
||||
print_srvconsole(" General Public License for more details.\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" You should have received a copy of the GNU General Public License\n");
|
||||
print_srvconsole(" along with this program; if not, write to the Free Software Foundation,\n");
|
||||
print_srvconsole(" Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
|
||||
print_srvconsole("\n");
|
||||
print_srvconsole(" In addition, as a special exception, the author gives permission to\n");
|
||||
print_srvconsole(" link the code of this program with the Half-Life Game Engine (\"HL\n");
|
||||
print_srvconsole(" Engine\") and Modified Game Libraries (\"MODs\") developed by Valve,\n");
|
||||
print_srvconsole(" L.L.C (\"Valve\"). You must obey the GNU General Public License in all\n");
|
||||
print_srvconsole(" respects for all of the code used other than the HL Engine and MODs\n");
|
||||
print_srvconsole(" from Valve. If you modify this file, you may extend this exception\n");
|
||||
print_srvconsole(" to your version of the file, but you are not obligated to do so. If\n");
|
||||
print_srvconsole(" you do not wish to do so, delete this exception statement from your\n");
|
||||
print_srvconsole(" version.\n");
|
||||
print_srvconsole("\n");
|
||||
}
|
||||
else if (!strcmp(cmd, "\x74\x75\x72\x74\x6C\x65")) // !! Hidden Command :D !!
|
||||
{
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x2E\x3A\x3A\x3E\x3E\x3A\x3A\x3B\x3E\x5E\x27\x2E\x27\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x3A\x3A\x3F\x3D\x3E\x3E\x3E\x3E\x3E\x3D\x3F\x3E\x78\x2B\x3F\x3E\x3E\x3E\x3D\x3E\x3F\x2B\x3F\x3E\x3B\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x2C\x3A\x3E\x3B\x3F\x3D\x3E\x3B\x2E\x27\x5E\x5E\x3B\x3B\x2C\x3A\x3F\x3F\x3D\x78\x3F\x3B\x3E\x3A\x3B\x3A\x5E\x3B\x3D\x3E\x2B\x2B\x2B\x2B\x3D\x2C\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x2C\x3E\x37\x24\x24\x78\x3D\x3D\x3D\x3F\x3A\x27\x20\x20\x20\x20\x20\x20\x20\x2E\x3A\x3B\x3D\x3E\x3A\x3A\x3A\x3A\x3F\x3F\x3F\x3E\x5E\x2C\x2E\x2E\x2C\x2C\x2C\x2C\x3A\x3B\x3D\x3D\x3B\x5E\x2C\x2C\x2C\x3A\x5E\x3A\x3F\x3F\x3E\x3D\x3D\x3E\x3E\x2B\x3B\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x2C\x3D\x2B\x3E\x2C\x5E\x3D\x79\x24\x33\x78\x33\x24\x5A\x24\x3B\x20\x20\x3A\x3E\x2B\x3E\x3D\x3F\x5E\x2C\x2C\x2C\x5E\x5E\x3E\x3D\x3E\x3B\x3B\x3A\x5E\x5E\x3E\x3F\x3D\x2B\x37\x3D\x3F\x3E\x3E\x3E\x3F\x3D\x3F\x3F\x3D\x3D\x3D\x3D\x3E\x3F\x3D\x3E\x3E\x3E\x3D\x5A\x78\x3E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x3D\x5A\x24\x37\x78\x66\x68\x78\x5A\x5A\x24\x79\x79\x71\x23\x23\x4D\x71\x3B\x3A\x3B\x3A\x3E\x3B\x3B\x2C\x5E\x3E\x3F\x3D\x3F\x3A\x2C\x2C\x3A\x3B\x3B\x3E\x3E\x3D\x2B\x3D\x3E\x3D\x3B\x3A\x3E\x3D\x2B\x3D\x2B\x37\x2B\x3D\x2B\x37\x37\x2B\x2B\x33\x33\x33\x37\x37\x24\x5A\x79\x3A\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x5E\x2B\x5A\x2B\x3E\x3D\x37\x5A\x66\x40\x40\x23\x40\x48\x23\x23\x23\x38\x5E\x3B\x3D\x3F\x2B\x3E\x3B\x3E\x5E\x5E\x2C\x27\x2E\x27\x2E\x2E\x5E\x3F\x3D\x3D\x3F\x3A\x3B\x3A\x3A\x3A\x5E\x5E\x3E\x3E\x3F\x3D\x37\x37\x3D\x3D\x37\x2B\x3D\x37\x2B\x37\x78\x24\x79\x38\x68\x45\x48\x79\x3E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x2C\x3E\x3E\x78\x33\x68\x48\x23\x23\x40\x40\x48\x45\x66\x33\x20\x2C\x3A\x3E\x3E\x3E\x3B\x3B\x3A\x3A\x2C\x2E\x2C\x5E\x3A\x2C\x5E\x3B\x3E\x37\x37\x3F\x3B\x3A\x2E\x3A\x3A\x3B\x3D\x3B\x3B\x3D\x2B\x3D\x78\x33\x37\x3E\x3D\x3D\x2B\x37\x2B\x78\x78\x78\x78\x5A\x66\x71\x68\x38\x45\x27\x20\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x3A\x37\x37\x24\x66\x71\x45\x45\x71\x45\x3A\x3A\x2C\x5E\x3A\x3E\x3A\x3A\x3B\x3B\x5E\x3A\x2C\x5E\x5E\x2C\x2C\x5E\x3A\x3E\x2B\x33\x3D\x3E\x3A\x3A\x3A\x3D\x2B\x2B\x3D\x3F\x3F\x37\x37\x2B\x37\x3D\x3D\x5A\x33\x78\x33\x37\x78\x24\x5A\x33\x37\x38\x40\x71\x38\x66\x40\x2C\x20\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x5A\x45\x40\x5E\x5E\x5E\x3A\x2C\x3A\x3B\x3E\x3A\x5E\x5E\x2C\x2E\x2E\x2C\x5E\x3B\x3B\x3A\x2B\x3E\x3F\x3B\x3F\x3F\x3F\x3F\x3E\x3F\x3D\x37\x3B\x3B\x3D\x33\x2B\x3D\x3D\x78\x78\x5A\x78\x33\x78\x5A\x5A\x5A\x24\x71\x48\x79\x5A\x24\x79\x45\x3E\x20\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27\x3B\x2C\x2C\x27\x5E\x5E\x2C\x3A\x5E\x3A\x3A\x5E\x3A\x3B\x3F\x3E\x3F\x3E\x3B\x3E\x3E\x3F\x3D\x2B\x37\x37\x2B\x2B\x3D\x2B\x37\x2B\x37\x37\x2B\x3B\x3D\x33\x2B\x2B\x37\x37\x2B\x3D\x78\x78\x66\x78\x78\x37\x33\x66\x78\x38\x23\x23\x27\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x3F\x3B\x5E\x2C\x3B\x3F\x3D\x3F\x3F\x3B\x3A\x3A\x3A\x3E\x3F\x3E\x3E\x3F\x3A\x3F\x33\x78\x78\x33\x24\x24\x33\x2B\x37\x78\x24\x78\x33\x3D\x2B\x2B\x5A\x24\x78\x24\x78\x33\x33\x24\x5A\x79\x24\x24\x24\x68\x45\x48\x38\x68\x45\x40\x3E\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2C\x3A\x3E\x3F\x37\x3D\x3E\x3F\x2B\x3F\x3F\x3E\x3F\x3F\x3F\x3D\x3F\x3E\x3F\x3D\x37\x2B\x3E\x3E\x2B\x37\x37\x33\x37\x33\x78\x33\x33\x33\x78\x37\x37\x37\x78\x5A\x78\x5A\x79\x79\x5A\x24\x79\x79\x79\x79\x79\x68\x71\x38\x38\x71\x23\x23\x45\x37\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x2B\x3F\x2B\x78\x40\x38\x3F\x3B\x3E\x3B\x3B\x3E\x3F\x37\x2B\x3F\x3F\x3D\x3D\x3E\x3F\x2B\x37\x37\x37\x37\x33\x33\x78\x78\x33\x37\x24\x5A\x78\x5A\x5A\x78\x24\x33\x3D\x37\x37\x37\x78\x24\x5A\x78\x37\x37\x78\x66\x79\x66\x71\x66\x40\x45\x40\x3A\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x3A\x3F\x2B\x3D\x2B\x79\x23\x79\x3B\x2C\x3A\x3A\x3A\x37\x78\x3F\x3E\x3B\x3E\x3B\x3E\x3D\x37\x24\x33\x37\x33\x37\x78\x78\x33\x24\x68\x79\x33\x24\x78\x2B\x33\x33\x5A\x79\x24\x5A\x79\x24\x5A\x37\x24\x5A\x5A\x66\x38\x66\x79\x66\x40\x71\x45\x48\x5A\x3A\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x37\x3D\x37\x37\x33\x37\x37\x66\x45\x5A\x3F\x5E\x5E\x78\x37\x3D\x3F\x3E\x3B\x3B\x3E\x2B\x2B\x24\x78\x37\x2B\x37\x2B\x37\x78\x78\x71\x79\x33\x33\x24\x24\x78\x24\x5A\x3F\x37\x78\x24\x78\x79\x66\x5A\x78\x79\x66\x79\x68\x79\x66\x5A\x33\x3F\x3D\x3D\x20\x20\x20\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x2B\x3D\x3F\x37\x37\x78\x33\x5A\x4E\x4D\x23\x38\x33\x3F\x3E\x3B\x3E\x3B\x3D\x3D\x33\x66\x24\x78\x33\x2B\x78\x24\x5A\x24\x5A\x71\x79\x78\x33\x33\x78\x79\x5A\x5A\x33\x66\x24\x78\x78\x24\x79\x5A\x24\x79\x5A\x37\x66\x24\x3D\x3B\x66\x23\x4D\x4D\x4D\x79\x3B\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x33\x37\x37\x24\x78\x66\x79\x48\x4D\x4D\x4D\x4D\x23\x71\x68\x5A\x24\x5A\x79\x68\x68\x5A\x5A\x24\x79\x66\x68\x78\x5A\x4E\x45\x66\x66\x45\x45\x45\x24\x5A\x40\x71\x68\x5A\x68\x5A\x37\x66\x79\x78\x37\x78\x37\x68\x38\x38\x71\x48\x40\x23\x45\x3A\x3D\x37\x45\x27\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x37\x37\x78\x37\x33\x38\x45\x45\x71\x20\x5E\x3D\x2B\x3F\x2B\x2B\x79\x71\x45\x48\x40\x45\x45\x45\x45\x45\x71\x40\x40\x71\x38\x38\x79\x66\x38\x68\x48\x48\x45\x66\x37\x2B\x3A\x37\x3F\x3B\x3A\x2C\x27\x2C\x27\x78\x4D\x23\x48\x48\x48\x79\x2B\x3A\x3F\x79\x27\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x78\x78\x24\x40\x4E\x4E\x4D\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x3E\x3E\x3F\x3E\x3E\x3E\x3E\x3B\x3B\x3B\x3A\x3A\x3F\x3E\x3A\x2E\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x45\x4D\x40\x45\x78\x5E\x33\x68\x33\x2B\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x24\x48\x45\x48\x78\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x4E\x40\x2B\x66\x33\x78\x20\x20\n");
|
||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x2C\x20\x3A\x20\x20\n");
|
||||
} else {
|
||||
print_srvconsole("Usage: amxx < command > [ argument ]\n");
|
||||
print_srvconsole("Commands:\n");
|
||||
print_srvconsole(" version - display amxx version info\n");
|
||||
print_srvconsole(" gpl - print the license\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()
|
||||
{
|
||||
@ -272,13 +250,12 @@ void plugin_srvcmd()
|
||||
|
||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||
|
||||
while ( a )
|
||||
while (a)
|
||||
{
|
||||
if ( (*a).matchCommand( cmd ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||
if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction()))
|
||||
{
|
||||
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
|
||||
if ( ret ) break;
|
||||
if (ret) break;
|
||||
}
|
||||
++a;
|
||||
}
|
||||
|
1007
amxmodx/string.cpp
1007
amxmodx/string.cpp
File diff suppressed because it is too large
Load Diff
177
amxmodx/util.cpp
177
amxmodx/util.cpp
@ -30,11 +30,10 @@
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _vsnprintf vsnprintf
|
||||
#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
char *UTIL_VarArgs(const char *fmt, ...)
|
||||
@ -52,40 +51,47 @@ char *UTIL_VarArgs(const char *fmt, ...)
|
||||
int UTIL_ReadFlags(const char* c)
|
||||
{
|
||||
int flags = 0;
|
||||
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
|
||||
|
||||
while (*c)
|
||||
flags |= (1<<(*c++ - 'a'));
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void UTIL_GetFlags(char* f,int a)
|
||||
void UTIL_GetFlags(char* f, int a)
|
||||
{
|
||||
for(int i='a';i<='z';++i){
|
||||
if ( a & 1 ) *f++ = i;
|
||||
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 )
|
||||
void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen)
|
||||
{
|
||||
char *n = menu;
|
||||
char c = 0;
|
||||
int a;
|
||||
|
||||
if (!gmsgShowMenu)
|
||||
return; // some games don't support ShowMenu (Firearms)
|
||||
return; // some games don't support ShowMenu (Firearms)
|
||||
|
||||
while ( *n ) {
|
||||
while (*n)
|
||||
{
|
||||
a = mlen;
|
||||
if ( a > 175 ) a = 175;
|
||||
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_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;
|
||||
@ -93,14 +99,14 @@ void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
|
||||
}
|
||||
|
||||
/* warning - don't pass here const string */
|
||||
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
||||
void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name)
|
||||
{
|
||||
if (!gmsgMOTD)
|
||||
return; // :TODO: Maybe output a warning log?
|
||||
|
||||
if (gmsgServerName)
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client);
|
||||
WRITE_STRING(name);
|
||||
MESSAGE_END();
|
||||
}
|
||||
@ -109,15 +115,17 @@ void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
||||
char c = 0;
|
||||
int a;
|
||||
|
||||
while ( *n ) {
|
||||
while (*n)
|
||||
{
|
||||
a = mlen;
|
||||
if ( a > 175 ) a = 175;
|
||||
if (a > 175) a = 175;
|
||||
mlen -= a;
|
||||
c = *(n+=a);
|
||||
c = *(n += a);
|
||||
*n = 0;
|
||||
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
|
||||
WRITE_BYTE( c ? FALSE : TRUE );
|
||||
WRITE_STRING( motd );
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, gmsgMOTD, NULL, client);
|
||||
WRITE_BYTE(c ? FALSE : TRUE);
|
||||
WRITE_STRING(motd);
|
||||
MESSAGE_END();
|
||||
*n = c;
|
||||
motd = n;
|
||||
@ -125,42 +133,52 @@ void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
||||
|
||||
if (gmsgServerName)
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||
WRITE_STRING( hostname->string );
|
||||
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 ",
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 ] );
|
||||
|
||||
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)
|
||||
@ -168,50 +186,57 @@ 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 ] == ' ' ) {
|
||||
while (src[d] && e < 480)
|
||||
{
|
||||
if (src[d] == ' ')
|
||||
{
|
||||
c = e;
|
||||
}
|
||||
else if ( src[ d ] == '\n' ) {
|
||||
else if (src[d] == '\n')
|
||||
{
|
||||
c = -1;
|
||||
b = 0;
|
||||
}
|
||||
message[ e++ ] = src[ d++ ];
|
||||
if ( ++b == 69 ) {
|
||||
if ( c == -1 ) {
|
||||
message[ e++ ] = '\n';
|
||||
|
||||
message[e++] = src[d++];
|
||||
|
||||
if (++b == 69)
|
||||
{
|
||||
if (c == -1)
|
||||
{
|
||||
message[e++] = '\n';
|
||||
b = 0;
|
||||
}
|
||||
else {
|
||||
message[ c ] = '\n';
|
||||
} else {
|
||||
message[c] = '\n';
|
||||
b = e - c - 1;
|
||||
c = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
message[ e ] = 0;
|
||||
|
||||
message[e] = 0;
|
||||
return message;
|
||||
}
|
||||
|
||||
unsigned short FixedUnsigned16( float value, float scale )
|
||||
unsigned short FixedUnsigned16(float value, float scale)
|
||||
{
|
||||
int output = (int)(value * scale);
|
||||
|
||||
if ( output < 0 )
|
||||
if (output < 0)
|
||||
output = 0;
|
||||
else if ( output > 0xFFFF )
|
||||
else if (output > 0xFFFF)
|
||||
output = 0xFFFF;
|
||||
|
||||
return (unsigned short)output;
|
||||
}
|
||||
|
||||
short FixedSigned16( float value, float scale )
|
||||
short FixedSigned16(float value, float scale)
|
||||
{
|
||||
int output = (int)(value * scale);
|
||||
|
||||
if ( output > 32767 )
|
||||
if (output > 32767)
|
||||
output = 32767;
|
||||
else if ( output < -32768 )
|
||||
else if (output < -32768)
|
||||
output = -32768;
|
||||
|
||||
return (short)output;
|
||||
@ -219,15 +244,15 @@ short FixedSigned16( float value, float scale )
|
||||
|
||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
|
||||
{
|
||||
if ( pEntity )
|
||||
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
|
||||
if (pEntity)
|
||||
MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity);
|
||||
else
|
||||
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
|
||||
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_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);
|
||||
@ -237,30 +262,34 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pM
|
||||
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_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 )
|
||||
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg)
|
||||
{
|
||||
if (!gmsgTextMsg)
|
||||
return; // :TODO: Maybe output a warning log?
|
||||
|
||||
char c = msg[190];
|
||||
msg[190] = 0; // truncate without checking with strlen()
|
||||
if ( pEntity )
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
||||
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_BEGIN(MSG_BROADCAST, gmsgTextMsg);
|
||||
|
||||
WRITE_BYTE(msg_dest);
|
||||
WRITE_STRING(msg);
|
||||
MESSAGE_END();
|
||||
msg[190] = c;
|
||||
}
|
||||
@ -275,7 +304,7 @@ void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg )
|
||||
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2)
|
||||
{
|
||||
if (!cmd)
|
||||
return; // no command
|
||||
return; // no command
|
||||
|
||||
// store command
|
||||
g_fakecmd.argv[0] = cmd;
|
||||
@ -304,7 +333,7 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
||||
// store argument
|
||||
g_fakecmd.argv[1] = arg1;
|
||||
// build argument line
|
||||
snprintf( g_fakecmd.args, 255, "%s", arg1);
|
||||
snprintf(g_fakecmd.args, 255, "%s", arg1);
|
||||
// if snprintf reached 255 chars limit, this will make sure there will be no access violation
|
||||
g_fakecmd.args[255] = 0;
|
||||
}
|
||||
|
@ -34,52 +34,49 @@
|
||||
|
||||
Vault g_vault;
|
||||
|
||||
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx,cell *params)
|
||||
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx, cell *params)
|
||||
{
|
||||
int iLen;
|
||||
int iLen;
|
||||
|
||||
g_vault.put( get_amxstring(amx,params[1],0,iLen) , get_amxstring(amx,params[2],1,iLen) );
|
||||
g_vault.saveVault();
|
||||
g_vault.put(get_amxstring(amx, params[1], 0, iLen), get_amxstring(amx, params[2], 1, iLen));
|
||||
g_vault.saveVault();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx,cell *params)
|
||||
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx, cell *params)
|
||||
{
|
||||
int iLen;
|
||||
int iLen;
|
||||
const char* key = get_amxstring(amx, params[1], 0, 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]);
|
||||
|
||||
if ( params[3] )
|
||||
return set_amxstring( amx , params[2] , g_vault.get( key ) , params[3] );
|
||||
|
||||
return g_vault.get_number( key );
|
||||
return g_vault.get_number(key);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx,cell *params)
|
||||
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx, cell *params)
|
||||
{
|
||||
int iLen;
|
||||
int iLen;
|
||||
|
||||
g_vault.remove( get_amxstring(amx,params[1],0,iLen) );
|
||||
g_vault.saveVault();
|
||||
g_vault.remove(get_amxstring(amx, params[1], 0, iLen));
|
||||
g_vault.saveVault();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx,cell *params)
|
||||
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;
|
||||
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 }
|
||||
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}
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,5,0
|
||||
PRODUCTVERSION 1,5,5,0
|
||||
FILEVERSION 1,6,0,0
|
||||
PRODUCTVERSION 1,6,0,0
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@ -45,12 +45,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "Comments", "AMX Mod X"
|
||||
VALUE "FileDescription", "AMX Mod X"
|
||||
VALUE "FileVersion", "1.55"
|
||||
VALUE "FileVersion", "1.60"
|
||||
VALUE "InternalName", "amxmodx"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
||||
VALUE "ProductName", "AMX Mod X"
|
||||
VALUE "ProductVersion", "1.55"
|
||||
VALUE "ProductVersion", "1.60"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -30,7 +30,11 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
HINSTANCE lib = dlmount("./amxxpc32.so");
|
||||
HINSTANCE lib = NULL;
|
||||
if (FileExists("./amxxpc32.so"))
|
||||
lib = dlmount("./amxxpc32.so");
|
||||
else
|
||||
lib = dlmount("amxxpc32.so");
|
||||
#else
|
||||
HINSTANCE lib = dlmount("amxxpc32.dll");
|
||||
#endif
|
||||
@ -101,9 +105,12 @@ int main(int argc, char **argv)
|
||||
|
||||
unlink(file);
|
||||
|
||||
HINSTANCE lib64 = 0;
|
||||
HINSTANCE lib64 = NULL;
|
||||
#ifdef __linux__
|
||||
lib64 = dlmount("./amxxpc64.so");
|
||||
if (FileExists("./amxxpc64.so"))
|
||||
lib64 = dlmount("./amxxpc64.so");
|
||||
else
|
||||
lib64 = dlmount("amxxpc64.so");
|
||||
#else
|
||||
lib64 = dlmount("amxxpc64.dll");
|
||||
#endif
|
||||
@ -374,3 +381,15 @@ void show_help()
|
||||
printf("\t-p<name> set name of \"prefix\" file\n");
|
||||
printf("\t-r[name] write cross reference report to console or to specified file\n");
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
bool FileExists(const char *file)
|
||||
{
|
||||
FILE *fp = fopen(file, "rb");
|
||||
if (!fp)
|
||||
return false;
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef _AMXXSC_INCLUDE_H
|
||||
#define _AMXXSC_INCLUDE_H
|
||||
|
||||
#define VERSION_STRING "1.50-300"
|
||||
#define VERSION_STRING "1.60-300"
|
||||
#define VERSION 03000
|
||||
#define MAGIC_HEADER 0x414D5842
|
||||
#define MAGIC_HEADER2 0x414D5858
|
||||
@ -67,4 +67,8 @@ struct BinPlugin
|
||||
int32_t offs; //file offset
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
bool FileExists(const char *file);
|
||||
#endif
|
||||
|
||||
#endif //_AMXXSC_INCLUDE_H
|
||||
|
@ -18,7 +18,7 @@ INCLUDE = -I.
|
||||
ifeq "$(PAWN64)" "true"
|
||||
BINARY = $(NAME)64.so
|
||||
BIN_DIR = Release64
|
||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64
|
||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -Dpc_printf=pc_printf64
|
||||
else
|
||||
BINARY = $(NAME)32.so
|
||||
BIN_DIR = Release32
|
||||
|
@ -65,12 +65,16 @@
|
||||
* purpose messages; errors go through pc_error(). The function is modelled
|
||||
* after printf().
|
||||
*/
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
__declspec (dllexport)
|
||||
int pc_printf(const char *message,...)
|
||||
#else
|
||||
extern int pc_printf(const char *message,...)
|
||||
#endif
|
||||
#else
|
||||
int pc_printf(const char *message, ...)
|
||||
#endif
|
||||
{
|
||||
#if PAWN_CELL_SIZE==32
|
||||
int ret;
|
||||
|
@ -6,6 +6,8 @@ EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Debug32 = Debug32
|
||||
Debug64 = Debug64
|
||||
Release = Release
|
||||
Release32 = Release32
|
||||
Release64 = Release64
|
||||
@ -13,6 +15,10 @@ Global
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug.ActiveCfg = Release|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug.Build.0 = Release|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.ActiveCfg = Debug32|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.Build.0 = Debug32|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug64.ActiveCfg = Debug64|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Debug64.Build.0 = Debug64|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Release.ActiveCfg = Release|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Release.Build.0 = Release|Win32
|
||||
{19B72687-080B-437A-917A-12AEB0031635}.Release32.ActiveCfg = Release32|Win32
|
||||
|
@ -200,6 +200,104 @@
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug32|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="1"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/amxxpc32.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/libpc300.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)/libpc300.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug64|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=64;NO_MAIN"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="1"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/amxxpc64.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/libpc300.pdb"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)/libpc300.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
@ -247,9 +345,6 @@
|
||||
<File
|
||||
RelativePath=".\scstate.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scstub.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scvars.c">
|
||||
</File>
|
||||
|
@ -63,6 +63,12 @@
|
||||
#define PREPROC_TERM '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
|
||||
#define sDEF_PREFIX "default.inc" /* default prefix filename */
|
||||
|
||||
#if defined WIN32
|
||||
#define INVISIBLE
|
||||
#else
|
||||
#define INVISIBLE __attribute__((visibility("protected")))
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
void *pv; /* e.g. a name */
|
||||
int i;
|
||||
@ -435,12 +441,16 @@ int pc_enablewarning(int number,int enable);
|
||||
*/
|
||||
|
||||
/* general console output */
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
__declspec (dllexport)
|
||||
int pc_printf(const char *message,...);
|
||||
#else
|
||||
extern int pc_printf(const char *message,...);
|
||||
#endif
|
||||
#else
|
||||
int pc_printf(const char *message, ...) INVISIBLE;
|
||||
#endif
|
||||
|
||||
/* error report function */
|
||||
int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
|
||||
@ -629,7 +639,7 @@ SC_FUNC void jmp_eq0(int number);
|
||||
SC_FUNC void outval(cell val,int newline);
|
||||
|
||||
/* function prototypes in SC5.C */
|
||||
SC_FUNC int error(int number,...) __attribute__((visibility("protected")));
|
||||
SC_FUNC int error(int number,...) INVISIBLE;
|
||||
SC_FUNC void errorset(int code);
|
||||
|
||||
/* function prototypes in SC6.C */
|
||||
|
@ -1918,9 +1918,11 @@ static int declloc(int fstatic)
|
||||
/* Although valid, a local variable whose name is equal to that
|
||||
* of a global variable or to that of a local variable at a lower
|
||||
* level might indicate a bug.
|
||||
* NOTE - don't bother with the error if there's no valid function!
|
||||
*/
|
||||
if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name)!=NULL)
|
||||
error(219,name); /* variable shadows another symbol */
|
||||
if (curfunc!=NULL && (curfunc->usage & uNATIVE))
|
||||
error(219,name); /* variable shadows another symbol */
|
||||
while (matchtoken('[')){
|
||||
ident=iARRAY;
|
||||
if (numdim == sDIMEN_MAX) {
|
||||
@ -3178,7 +3180,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
|
||||
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
|
||||
int curstatus=sc_status;
|
||||
sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
|
||||
error(208);
|
||||
//error(208); //this is silly, it should be caught the first pass
|
||||
sc_status=curstatus;
|
||||
sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
|
||||
} /* if */
|
||||
@ -3643,7 +3645,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
if (argsym!=NULL) {
|
||||
error(21,name); /* symbol already defined */
|
||||
} else {
|
||||
if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN)
|
||||
if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN && curfunc!=NULL)
|
||||
error(219,name); /* variable shadows another symbol */
|
||||
/* add details of type and address */
|
||||
assert(numtags>0);
|
||||
|
@ -715,18 +715,6 @@ static int ftoi(cell *val,const unsigned char *curptr)
|
||||
#endif
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
*val=*((cell *)&fnum);
|
||||
#if !defined NDEBUG
|
||||
/* I assume that the C/C++ compiler stores "double" values in IEEE 754
|
||||
* format (as mandated in the ANSI standard).
|
||||
*/
|
||||
{ float test1 = 0.0, test2 = 50.0, test3 = -50.0;
|
||||
uint64_t bit = 1;
|
||||
/* test 0.0 == all bits 0 */
|
||||
assert(*(uint64_t*)&test1==0x00000000L);
|
||||
/* test sign & magnitude format */
|
||||
assert(((*(uint64_t*)&test2) ^ (*(uint64_t*)&test3)) == (bit << (PAWN_CELL_SIZE-1)));
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
@ -1419,7 +1407,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
||||
int prefixlen;
|
||||
const unsigned char *p,*s,*e;
|
||||
unsigned char *args[10];
|
||||
int match,arg,len;
|
||||
int match,arg,len,argsnum=0;
|
||||
|
||||
memset(args,0,sizeof args);
|
||||
|
||||
@ -1459,6 +1447,8 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
||||
/* store the parameter (overrule any earlier) */
|
||||
if (args[arg]!=NULL)
|
||||
free(args[arg]);
|
||||
else
|
||||
argsnum++;
|
||||
len=(int)(e-s);
|
||||
args[arg]=(unsigned char*)malloc(len+1);
|
||||
if (args[arg]==NULL)
|
||||
@ -1515,12 +1505,15 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
||||
if (match) {
|
||||
/* calculate the length of the substituted string */
|
||||
for (e=(unsigned char*)substitution,len=0; *e!='\0'; e++) {
|
||||
if (*e=='%' && isdigit(*(e+1))) {
|
||||
if (*e=='%' && isdigit(*(e+1)) && argsnum) {
|
||||
arg=*(e+1)-'0';
|
||||
assert(arg>=0 && arg<=9);
|
||||
if (args[arg]!=NULL)
|
||||
if (args[arg]!=NULL) {
|
||||
len+=strlen((char*)args[arg]);
|
||||
e++; /* skip %, digit is skipped later */
|
||||
e++; /* skip %, digit is skipped later */
|
||||
} else {
|
||||
len++;
|
||||
}
|
||||
} else {
|
||||
len++;
|
||||
} /* if */
|
||||
@ -1538,8 +1531,21 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
||||
if (args[arg]!=NULL) {
|
||||
strins((char*)s,(char*)args[arg],strlen((char*)args[arg]));
|
||||
s+=strlen((char*)args[arg]);
|
||||
e++; /* skip %, digit is skipped later */
|
||||
} else {
|
||||
strins((char*)s,(char*)e,1);
|
||||
s++;
|
||||
} /* if */
|
||||
e++; /* skip %, digit is skipped later */
|
||||
} else if (*e=='"') {
|
||||
p=e;
|
||||
if (is_startstring(e)) { /* skip strings */
|
||||
e=skipstring(e);
|
||||
strins((char*)s,(char*)p,(e-p+1));
|
||||
s+=(e-p+1);
|
||||
} else {
|
||||
strins((char*)s,(char*)e,1);
|
||||
s++;
|
||||
}
|
||||
} else {
|
||||
strins((char*)s,(char*)e,1);
|
||||
s++;
|
||||
@ -1578,7 +1584,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
|
||||
if (*start=='\0')
|
||||
break; /* abort loop on error */
|
||||
/* if matching the operator "defined", skip it plus the symbol behind it */
|
||||
if (strncmp((char*)start,"defined",7)==0 && *(start+7)<=' ') {
|
||||
if (strncmp((char*)start,"defined",7)==0 && !isalpha((char)*(start+7))) {
|
||||
start+=7; /* skip "defined" */
|
||||
/* skip white space & parantheses */
|
||||
while (*start<=' ' && *start!='\0' || *start=='(')
|
||||
@ -2451,7 +2457,7 @@ static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int i
|
||||
while (ptr!=NULL) {
|
||||
if (hash==ptr->hash && strcmp(name,ptr->name)==0
|
||||
&& (ptr->parent==NULL || includechildren)
|
||||
&& (ptr->fnumber<0 || ptr->fnumber==fnumber))
|
||||
&& (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
|
||||
return ptr;
|
||||
ptr=ptr->next;
|
||||
} /* while */
|
||||
|
@ -964,8 +964,12 @@ static int hier14(value *lval1)
|
||||
check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag);
|
||||
store(&lval3); /* now, store the expression result */
|
||||
} /* if */
|
||||
if (!oper && !matchtag(lval3.tag,lval2.tag,TRUE))
|
||||
error(213); /* tagname mismatch (if "oper", warning already given in plunge2()) */
|
||||
if (!oper) { /* tagname mismatch (if "oper", warning already given in plunge2()) */
|
||||
if (lval3.sym && !matchtag(lval3.sym->tag, lval2.tag, TRUE))
|
||||
error(213);
|
||||
else if (!lval3.sym && !matchtag(lval3.tag, lval2.tag, TRUE))
|
||||
error(213);
|
||||
}
|
||||
if (lval3.sym)
|
||||
markusage(lval3.sym,uWRITTEN);
|
||||
sideeffect=TRUE;
|
||||
@ -2202,7 +2206,8 @@ static int nesting=0;
|
||||
if ((sym->usage & uNATIVE)==0)
|
||||
totalsize++; /* add "call" opcode */
|
||||
totalsize+=nest_stkusage;
|
||||
assert(curfunc!=NULL);
|
||||
if (!curfunc) /* if we got here, the function is invalid! */
|
||||
return;
|
||||
if (curfunc->x.stacksize<totalsize)
|
||||
curfunc->x.stacksize=totalsize;
|
||||
nest_stkusage-=nargs+heapalloc+1; /* stack/heap space, +1 for argcount param */
|
||||
|
@ -581,6 +581,8 @@ SC_FUNC int assemble(FILE *fout,FILE *fin)
|
||||
constvalue *constptr;
|
||||
cell mainaddr;
|
||||
|
||||
fcurrent = -1;
|
||||
|
||||
/* if compression failed, restart the assembly with compaction switched off */
|
||||
if (setjmp(compact_err)!=0) {
|
||||
assert(sc_compress); /* cannot arrive here if compact encoding was disabled */
|
||||
|
@ -450,9 +450,14 @@ SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
|
||||
#endif
|
||||
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
||||
symbol *sub;
|
||||
#if !defined NDEBUG
|
||||
count = sym->dim.array.level;
|
||||
#endif
|
||||
strcat(string," [ ");
|
||||
for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
|
||||
assert(sub->dim.array.level==count++);
|
||||
#if !defined NDEBUG
|
||||
assert(sub->dim.array.level==count--);
|
||||
#endif
|
||||
sprintf(string+strlen(string),"%x:%x ",sub->x.idxtag,sub->dim.array.length);
|
||||
} /* for */
|
||||
strcat(string,"]");
|
||||
|
@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = cstrike_amxx
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "CStrike"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "CSTRIKE"
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "CSX"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "CSX"
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "DoD Fun"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "DODFUN"
|
||||
|
@ -187,6 +187,8 @@ void ServerDeactivate() {
|
||||
for ( i=DODMAX_WEAPONS-DODMAX_CUSTOMWPNS;i<DODMAX_WEAPONS;i++)
|
||||
weaponData[i].needcheck = false;
|
||||
|
||||
g_map.Init();
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
@ -381,7 +383,6 @@ void OnAmxxAttach() {
|
||||
}
|
||||
|
||||
g_map.Init();
|
||||
|
||||
}
|
||||
|
||||
void OnAmxxDetach() {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "DoDX"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "DODX"
|
||||
|
@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = engine_amxx
|
||||
|
@ -65,7 +65,7 @@ void OnPluginsLoaded()
|
||||
StartFrameForward = MF_RegisterForward("server_frame", ET_IGNORE, FP_DONE); // done
|
||||
DispatchKeyForward = MF_RegisterForward("pfn_keyvalue", ET_STOP, FP_CELL, FP_DONE); // done
|
||||
PlaybackForward = MF_RegisterForward("pfn_playbackevent", ET_STOP, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_ARRAY, FP_ARRAY, FP_FLOAT, FP_FLOAT, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE); // done
|
||||
SpawnForward = MF_RegisterForward("pfn_spawn", ET_IGNORE, FP_CELL, FP_DONE); // done
|
||||
SpawnForward = MF_RegisterForward("pfn_spawn", ET_STOP, FP_CELL, FP_DONE); // done
|
||||
pfnTouchForward = MF_RegisterForward("pfn_touch", ET_STOP, FP_CELL, FP_CELL, FP_DONE); // done
|
||||
VexdTouchForward = MF_RegisterForward("vexd_pfntouch", ET_IGNORE, FP_CELL, FP_CELL, FP_DONE); // done
|
||||
VexdServerForward = MF_RegisterForward("ServerFrame", ET_IGNORE, FP_DONE); // done
|
||||
|
@ -1071,7 +1071,7 @@ AMX_NATIVE_INFO engine_Natives[] = {
|
||||
{"register_touch", register_touch},
|
||||
|
||||
{"eng_get_string", get_string},
|
||||
{"in_view_cone", in_view_cone},
|
||||
{"is_in_viewcone", in_view_cone},
|
||||
{"is_visible", is_visible},
|
||||
{"trace_forward", trace_forward},
|
||||
|
||||
|
@ -1404,7 +1404,8 @@ static cell AMX_NATIVE_CALL find_ent_by_model(AMX *amx, cell *params) {
|
||||
|
||||
edict_t *pStart;
|
||||
|
||||
if (iStart == -1) {
|
||||
if (iStart == -1)
|
||||
{
|
||||
pStart = NULL;
|
||||
} else {
|
||||
if (!is_ent_valid(iStart))
|
||||
@ -1413,20 +1414,20 @@ static cell AMX_NATIVE_CALL find_ent_by_model(AMX *amx, cell *params) {
|
||||
pStart = INDEXENT2(iStart);
|
||||
}
|
||||
|
||||
int checkEnt = ENTINDEX(FIND_ENTITY_BY_STRING(pStart, "classname", szClass));
|
||||
const char *CheckModel = "";
|
||||
edict_t *pEdict = FIND_ENTITY_BY_STRING(pStart, "classname", szClass);
|
||||
|
||||
while (!FNullEnt(checkEnt)) {
|
||||
CheckModel = STRING(pStart->v.model);
|
||||
if (strcmp(CheckModel, szModel)==0) {
|
||||
return checkEnt;
|
||||
} else {
|
||||
pStart = INDEXENT2(checkEnt);
|
||||
checkEnt = ENTINDEX(FIND_ENTITY_BY_STRING(pStart, "classname", szClass));
|
||||
}
|
||||
const char *check;
|
||||
|
||||
while (pEdict && !FNullEnt(pEdict))
|
||||
{
|
||||
check = STRING(pEdict->v.model);
|
||||
if (!check || strcmp(check, szModel))
|
||||
pEdict = FIND_ENTITY_BY_STRING(pEdict, "classname", szClass);
|
||||
else
|
||||
return ENTINDEX(pEdict);
|
||||
}
|
||||
|
||||
return checkEnt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL find_ent_by_tname(AMX *amx, cell *params) {
|
||||
|
@ -37,7 +37,8 @@ int fstrcmp(const char *s1, const char *s2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Spawn(edict_t *pEntity) {
|
||||
int Spawn(edict_t *pEntity)
|
||||
{
|
||||
if (!g_precachedStuff) {
|
||||
// Used for SetView, added by JGHG
|
||||
int returnValue = PRECACHE_MODEL("models/rpgrocket.mdl");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "Engine"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "ENGINE"
|
||||
|
@ -60,8 +60,10 @@ debug:
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/sdk/*.o
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(BINARY)
|
||||
rm -rf Debug/sdk/*.o
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(BINARY)
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "FakeMeta"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "FAKEMETA"
|
||||
|
@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -pipe -fomit-frame-pointer
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = fun_amxx
|
||||
|
@ -31,6 +31,7 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "fun.h"
|
||||
|
||||
/*
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "Fun"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "FUN"
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "GeoIP"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "GEOIP"
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "MSSQL"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.56"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "MSSQL"
|
||||
|
@ -214,7 +214,7 @@ static cell AMX_NATIVE_CALL sql_getfield(AMX *amx, cell *params) // 2-4 params
|
||||
SQLResult *Result = Results[id];
|
||||
int numParams = (*params)/sizeof(cell);
|
||||
cell *fAddr = NULL;
|
||||
const char *field = Result->GetField(id);
|
||||
const char *field = Result->GetField(params[2]);
|
||||
if (field == NULL)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column %d", id);
|
||||
@ -260,7 +260,7 @@ static cell AMX_NATIVE_CALL sql_getresult(AMX *amx, cell *params) // 4 params
|
||||
cell *fAddr = NULL;
|
||||
int len = 0;
|
||||
const char *column = MF_GetAmxString(amx, params[2], 0, &len);
|
||||
const char *field = Result->GetField(id);
|
||||
const char *field = Result->GetField(column);
|
||||
if (field == NULL)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column \"%s\"", column);
|
||||
@ -319,6 +319,54 @@ static cell AMX_NATIVE_CALL sql_num_rows(AMX *amx, cell *params)
|
||||
return (cell)Result->NumRows();
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sql_num_fields(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1]-1;
|
||||
|
||||
if (id >= Results.size() || Results[id]->isFree)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid result handle %d", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SQLResult *Result = Results[id];
|
||||
|
||||
return (cell)Result->FieldCount;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sql_field_name(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1]-1;
|
||||
|
||||
if (id >= Results.size() || Results[id]->isFree)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid result handle %d", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SQLResult *Result = Results[id];
|
||||
|
||||
int field = params[2];
|
||||
|
||||
if (field < 1 || field > Result->FieldCount)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid field number %d", field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADODB::FieldPtr pFld = NULL;
|
||||
_variant_t index = (short)field;
|
||||
pFld = Result->res->Fields->GetItem(&index);
|
||||
if (pFld != NULL && (LPCSTR)(pFld->GetName()) != NULL)
|
||||
{
|
||||
MF_SetAmxString(amx, params[3], (LPCSTR)(pFld->GetName()), params[4]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static cell AMX_NATIVE_CALL sql_type(AMX *amx, cell *params)
|
||||
{
|
||||
return MF_SetAmxString(amx, params[1], "mssql", params[2]);
|
||||
@ -335,6 +383,8 @@ AMX_NATIVE_INFO mssql_Natives[] = {
|
||||
{ "dbi_free_result", sql_free_result },
|
||||
{ "dbi_num_rows", sql_num_rows },
|
||||
{ "dbi_result", sql_getresult },
|
||||
{ "dbi_num_fields", sql_num_fields },
|
||||
{ "dbi_field_name", sql_field_name },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "NS"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "Steve Dudenhoeffer"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "NS"
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
String(String &src)
|
||||
String(const String &src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
|
@ -2,7 +2,8 @@
|
||||
#define _INCLUDE_JOURNAL_H
|
||||
|
||||
#include "Binary.h"
|
||||
#include "NHash.h"
|
||||
#include "sh_list.h"
|
||||
#include "sh_tinyhash.h"
|
||||
#include "CString.h"
|
||||
|
||||
enum JOp
|
||||
@ -21,7 +22,7 @@ enum Encode
|
||||
Encode_Medium,
|
||||
};
|
||||
|
||||
typedef NHash<String,String> VaultMap;
|
||||
typedef THash<String,String> VaultMap;
|
||||
|
||||
class Journal
|
||||
{
|
||||
|
@ -1,320 +0,0 @@
|
||||
#ifndef _INCLUDE_NHASH_H
|
||||
#define _INCLUDE_NHASH_H
|
||||
|
||||
#include <time.h>
|
||||
#include "compat.h"
|
||||
|
||||
/**
|
||||
* This is a primitive, typical hash class.
|
||||
* Design goals were: modular, easy to use, compact
|
||||
* The table size is fixed by a constant, 2K gives about ~8-16K in immediate memory usage.
|
||||
* Each entry in the table uses about 20-28 bytes, depending on the data being stored.
|
||||
* In theory we could optimize this further by storing a linked list of the hash items.
|
||||
* (this would sacrifice ~8 bytes per node!)
|
||||
* --- by David "BAILOPAN" Anderson
|
||||
*/
|
||||
|
||||
#define TABLE_SIZE 2048
|
||||
|
||||
template <class K>
|
||||
int HashFunction(const K & k);
|
||||
|
||||
template <class K>
|
||||
bool Compare(const K & k1, const K & k2);
|
||||
|
||||
template <class K, class V>
|
||||
class NHash
|
||||
{
|
||||
private:
|
||||
struct hashnode
|
||||
{
|
||||
K key;
|
||||
V val;
|
||||
time_t stamp;
|
||||
hashnode *next;
|
||||
hashnode *prev;
|
||||
};
|
||||
struct bucket
|
||||
{
|
||||
hashnode *head;
|
||||
hashnode *tail;
|
||||
};
|
||||
public:
|
||||
NHash()
|
||||
{
|
||||
memset(&m_Buckets, 0, sizeof(m_Buckets));
|
||||
m_Size = 0;
|
||||
}
|
||||
~NHash()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
void Clear()
|
||||
{
|
||||
hashnode *n, *t;
|
||||
for (size_t i=0; i<TABLE_SIZE; i++)
|
||||
{
|
||||
n = m_Buckets[i].head;
|
||||
while (n)
|
||||
{
|
||||
t = n->next;
|
||||
delete n;
|
||||
n = t;
|
||||
}
|
||||
m_Buckets[i].head = NULL;
|
||||
m_Buckets[i].tail = NULL;
|
||||
}
|
||||
}
|
||||
void Insert(const K & key, const V & val)
|
||||
{
|
||||
Insert(key, val, time(NULL));
|
||||
}
|
||||
void Insert(const K & key, const V & val, time_t stamp)
|
||||
{
|
||||
bucket *b;
|
||||
hashnode *n;
|
||||
if (!_Find(key, &b, &n))
|
||||
{
|
||||
n = new hashnode;
|
||||
n->key = key;
|
||||
_Insert(b, n);
|
||||
}
|
||||
n->val = val;
|
||||
n->stamp = stamp;
|
||||
}
|
||||
bool Exists(const K & k)
|
||||
{
|
||||
uint16_t h = HashFunction(k);
|
||||
if (h >= TABLE_SIZE)
|
||||
h = h % TABLE_SIZE;
|
||||
bucket *b = &(m_Buckets[h]);
|
||||
hashnode *n = b->head;
|
||||
while (n)
|
||||
{
|
||||
if (Compare(n->key,k))
|
||||
return true;
|
||||
n = n->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
V & Retrieve(const K & k, time_t & stamp)
|
||||
{
|
||||
hashnode *n;
|
||||
bucket *b;
|
||||
if (!_Find(k, &b, &n))
|
||||
{
|
||||
n = new hashnode;
|
||||
n->key = k;
|
||||
n->stamp = time(NULL);
|
||||
_Insert(b, n);
|
||||
}
|
||||
stamp = n->stamp;
|
||||
return n->val;
|
||||
}
|
||||
V & Retrieve(const K & k)
|
||||
{
|
||||
time_t stamp;
|
||||
return Retrieve(k, stamp);
|
||||
}
|
||||
size_t Size()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
void Remove(const K & key)
|
||||
{
|
||||
bucket *b;
|
||||
hashnode *n;
|
||||
if (_Find(key, &b, &n))
|
||||
{
|
||||
_Remove(b, n);
|
||||
}
|
||||
}
|
||||
size_t Prune(time_t start=0, time_t end=0)
|
||||
{
|
||||
size_t num = m_Size;
|
||||
hashnode *n, *t;
|
||||
bucket *b;
|
||||
for (size_t i=0; i<TABLE_SIZE; i++)
|
||||
{
|
||||
b = &(m_Buckets[i]);
|
||||
n = b->head;
|
||||
while (n)
|
||||
{
|
||||
t = n->next;
|
||||
if (n->stamp != 0)
|
||||
{
|
||||
if (start == 0 && end == 0)
|
||||
_Remove(b, n);
|
||||
else if (start == 0 && n->stamp < end)
|
||||
_Remove(b, n);
|
||||
else if (end == 0 && n->stamp > start)
|
||||
_Remove(b, n);
|
||||
else if (n->stamp > start && n->stamp < end)
|
||||
_Remove(b, n);
|
||||
}
|
||||
n = t;
|
||||
}
|
||||
if (!m_Size)
|
||||
return num;
|
||||
}
|
||||
return (num - m_Size);
|
||||
}
|
||||
private:
|
||||
bucket m_Buckets[TABLE_SIZE];
|
||||
size_t m_Size;
|
||||
public:
|
||||
friend class iterator;
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
}
|
||||
iterator(NHash *hash) : m_Hash(hash),
|
||||
m_CurPos(0),
|
||||
m_CurNode(0)
|
||||
{
|
||||
Next();
|
||||
}
|
||||
void Next()
|
||||
{
|
||||
if (!m_CurNode || !m_CurNode->next)
|
||||
{
|
||||
bucket *b;
|
||||
int i;
|
||||
for (i=m_CurPos+1; i<TABLE_SIZE; i++)
|
||||
{
|
||||
b = &(m_Hash->m_Buckets[i]);
|
||||
if (b->head)
|
||||
{
|
||||
m_CurNode = b->head;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//m_LastPos = m_CurPos;
|
||||
m_CurPos = i;
|
||||
} else {
|
||||
m_CurNode = m_CurNode->next;
|
||||
}
|
||||
}
|
||||
bool Done()
|
||||
{
|
||||
if (!m_CurNode)
|
||||
return true;
|
||||
if (!m_CurNode->next && m_CurPos >= TABLE_SIZE)
|
||||
return true;
|
||||
if (!m_CurNode->next)
|
||||
{
|
||||
bucket *b;
|
||||
for (int i=m_CurPos+1; i<TABLE_SIZE; i++)
|
||||
{
|
||||
b = &(m_Hash->m_Buckets[i]);
|
||||
if (b->head)
|
||||
{
|
||||
//trick next into moving to this one quickly :)
|
||||
m_CurPos = i - 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
K & GetKey()
|
||||
{
|
||||
return m_CurNode->key;
|
||||
}
|
||||
V & GetVal()
|
||||
{
|
||||
return m_CurNode->val;
|
||||
}
|
||||
time_t GetStamp()
|
||||
{
|
||||
return m_CurNode->stamp;
|
||||
}
|
||||
private:
|
||||
NHash *m_Hash;
|
||||
int m_CurPos;
|
||||
//int m_LastPos;
|
||||
hashnode *m_CurNode;
|
||||
//hashnode *m_LastNode;
|
||||
};
|
||||
public:
|
||||
iterator GetIter()
|
||||
{
|
||||
return iterator(this);
|
||||
}
|
||||
private:
|
||||
bool _Find(const K & k, bucket **b, hashnode **n)
|
||||
{
|
||||
uint16_t h = HashFunction(k);
|
||||
if (h >= TABLE_SIZE)
|
||||
h = h % TABLE_SIZE;
|
||||
bucket *bb = &(m_Buckets[h]);
|
||||
if (b)
|
||||
*b = bb;
|
||||
hashnode *nn = bb->head;
|
||||
while (nn)
|
||||
{
|
||||
if (Compare(nn->key,k))
|
||||
{
|
||||
if (n)
|
||||
*n = nn;
|
||||
return true;
|
||||
}
|
||||
nn = nn->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void _Insert(hashnode *n)
|
||||
{
|
||||
uint16_t h = HashFunction(n->key);
|
||||
if (h >= TABLE_SIZE)
|
||||
h = h % TABLE_SIZE;
|
||||
bucket *b = &(m_Buckets[h]);
|
||||
_Insert(b, n);
|
||||
}
|
||||
//Lowest call for insertion
|
||||
void _Insert(bucket *b, hashnode *n)
|
||||
{
|
||||
n->next = NULL;
|
||||
if (b->head == NULL)
|
||||
{
|
||||
b->head = n;
|
||||
b->tail = n;
|
||||
n->prev = NULL;
|
||||
} else {
|
||||
b->tail->next = n;
|
||||
n->prev = b->tail;
|
||||
b->tail = n;
|
||||
}
|
||||
m_Size++;
|
||||
}
|
||||
//Lowest call for deletion, returns next node if any
|
||||
hashnode *_Remove(bucket *b, hashnode *n)
|
||||
{
|
||||
hashnode *n2 = n->next;
|
||||
if (b->head == n && b->tail == n)
|
||||
{
|
||||
b->head = NULL;
|
||||
b->tail = NULL;
|
||||
} else if (b->head == n) {
|
||||
n->next->prev = NULL;
|
||||
b->head = n->next;
|
||||
if (b->head->next == NULL)
|
||||
b->tail = b->head;
|
||||
} else if (b->tail == n) {
|
||||
n->prev->next = NULL;
|
||||
b->tail = n->prev;
|
||||
if (b->tail->prev == NULL)
|
||||
b->head = b->tail;
|
||||
} else {
|
||||
n->prev->next = n->next;
|
||||
n->next->prev = n->prev;
|
||||
}
|
||||
delete n;
|
||||
m_Size--;
|
||||
return n2;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_NHASH_H
|
@ -18,9 +18,9 @@ int HashFunction<String>(const String & k)
|
||||
}
|
||||
|
||||
template <>
|
||||
bool Compare<String>(const String & k1, const String & k2)
|
||||
int Compare<String>(const String & k1, const String & k2)
|
||||
{
|
||||
return (strcmp(k1.c_str(),k2.c_str())==0);
|
||||
return strcmp(k1.c_str(),k2.c_str());
|
||||
}
|
||||
|
||||
NVault::NVault(const char *file)
|
||||
@ -137,18 +137,18 @@ bool NVault::_SaveToFile()
|
||||
String key;
|
||||
String val;
|
||||
|
||||
NHash<String,String>::iterator iter = m_Hash.GetIter();
|
||||
while (!iter.Done())
|
||||
THash<String,String>::iterator iter = m_Hash.begin();
|
||||
while (iter != m_Hash.end())
|
||||
{
|
||||
key = iter.GetKey();
|
||||
val = iter.GetVal();
|
||||
stamp = iter.GetStamp();
|
||||
key = (*iter).key;
|
||||
val = (*iter).val;
|
||||
stamp = (*iter).stamp;
|
||||
bw.WriteInt32(stamp);
|
||||
bw.WriteUInt8( key.size() );
|
||||
bw.WriteUInt16( val.size() );
|
||||
bw.WriteChars( key.c_str(), key.size() );
|
||||
bw.WriteChars( val.c_str(), val.size() );
|
||||
iter.Next();
|
||||
iter++;
|
||||
}
|
||||
} catch (...) {
|
||||
fclose(fp);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef _INCLUDE_NVAULT_H
|
||||
#define _INCLUDE_NVAULT_H
|
||||
|
||||
#include "sh_list.h"
|
||||
#include "sh_tinyhash.h"
|
||||
#include "IVault.h"
|
||||
#include "CString.h"
|
||||
#include "Journal.h"
|
||||
@ -51,7 +53,7 @@ private:
|
||||
bool _SaveToFile();
|
||||
private:
|
||||
String m_File;
|
||||
NHash<String, String> m_Hash;
|
||||
THash<String, String> m_Hash;
|
||||
Journal *m_Journal;
|
||||
bool m_Open;
|
||||
};
|
||||
|
@ -29,10 +29,10 @@ static cell nvault_open(AMX *amx, cell *params)
|
||||
sprintf(file, "%s/%s.vault", path, name);
|
||||
for (size_t i=0; i<g_Vaults.size(); i++)
|
||||
{
|
||||
if (!g_Vaults[i])
|
||||
continue;
|
||||
if (strcmp(g_Vaults.at(i)->GetFilename(), file) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
NVault *v = new NVault(file);
|
||||
if (!v->Open())
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "nVault"
|
||||
#define MODULE_VERSION "1.55"
|
||||
#define MODULE_VERSION "1.60"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "nVault"
|
||||
|
@ -162,10 +162,13 @@
|
||||
RelativePath=".\Journal.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NHash.h">
|
||||
RelativePath=".\NVault.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NVault.h">
|
||||
RelativePath=".\sh_list.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sh_tinyhash.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
@ -186,10 +189,10 @@
|
||||
RelativePath=".\CString.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\sdk\moduleconfig.h">
|
||||
RelativePath=".\moduleconfig.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\moduleconfig.h">
|
||||
RelativePath=".\sdk\moduleconfig.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
|
250
dlls/nvault/sh_list.h
Executable file
250
dlls/nvault/sh_list.h
Executable file
@ -0,0 +1,250 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): David "BAILOPAN" Anderson
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SMM_LIST_H
|
||||
#define _INCLUDE_SMM_LIST_H
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
//namespace SourceHook
|
||||
//{
|
||||
//This class is from CSDM for AMX Mod X
|
||||
template <class T>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
class iterator;
|
||||
friend class iterator;
|
||||
class ListNode
|
||||
{
|
||||
public:
|
||||
ListNode(const T & o) : obj(o) { };
|
||||
ListNode() { };
|
||||
T obj;
|
||||
ListNode *next;
|
||||
ListNode *prev;
|
||||
};
|
||||
private:
|
||||
ListNode *_Initialize()
|
||||
{
|
||||
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
|
||||
n->next = NULL;
|
||||
n->prev = NULL;
|
||||
return n;
|
||||
}
|
||||
public:
|
||||
List() : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
}
|
||||
List(const List &src) : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
}
|
||||
~List()
|
||||
{
|
||||
clear();
|
||||
if (m_Head)
|
||||
{
|
||||
free(m_Head);
|
||||
m_Head = NULL;
|
||||
}
|
||||
}
|
||||
void push_back(const T &obj)
|
||||
{
|
||||
ListNode *node = new ListNode(obj);
|
||||
|
||||
if (!m_Head->prev)
|
||||
{
|
||||
//link in the node as the first item
|
||||
node->next = m_Head;
|
||||
node->prev = m_Head;
|
||||
m_Head->prev = node;
|
||||
m_Head->next = node;
|
||||
} else {
|
||||
node->prev = m_Head->prev;
|
||||
node->next = m_Head;
|
||||
m_Head->prev->next = node;
|
||||
m_Head->prev = node;
|
||||
}
|
||||
m_Size++;
|
||||
}
|
||||
size_t size()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
ListNode *node = m_Head->next;
|
||||
ListNode *temp;
|
||||
m_Head->next = NULL;
|
||||
m_Head->prev = NULL;
|
||||
while (node && node != m_Head)
|
||||
{
|
||||
temp = node->next;
|
||||
delete node;
|
||||
node = temp;
|
||||
}
|
||||
m_Size = 0;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return (m_Head->next == NULL);
|
||||
}
|
||||
T & back()
|
||||
{
|
||||
return m_Head->prev->obj;
|
||||
}
|
||||
private:
|
||||
ListNode *m_Head;
|
||||
size_t m_Size;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
friend class List;
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_This = NULL;
|
||||
}
|
||||
iterator(const List &src)
|
||||
{
|
||||
m_This = src.m_Head;
|
||||
}
|
||||
iterator(ListNode *n) : m_This(n)
|
||||
{
|
||||
}
|
||||
iterator(const iterator &where)
|
||||
{
|
||||
m_This = where.m_This;
|
||||
}
|
||||
iterator & operator--()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return *this;
|
||||
}
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return old;
|
||||
}
|
||||
T & operator * () const
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T & operator * ()
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T * operator -> () const
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
bool operator != (const iterator &where) const
|
||||
{
|
||||
return (m_This != where.m_This);
|
||||
}
|
||||
bool operator ==(const iterator &where) const
|
||||
{
|
||||
return (m_This == where.m_This);
|
||||
}
|
||||
private:
|
||||
ListNode *m_This;
|
||||
};
|
||||
public:
|
||||
iterator begin() const
|
||||
{
|
||||
if (m_Size)
|
||||
return iterator(m_Head->next);
|
||||
else
|
||||
return iterator(m_Head);
|
||||
}
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Head);
|
||||
}
|
||||
iterator erase(iterator &where)
|
||||
{
|
||||
ListNode *pNode = where.m_This;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
//If we are both the head and tail...
|
||||
if (m_Head->next == pNode && m_Head->prev == pNode)
|
||||
{
|
||||
m_Head->next = NULL;
|
||||
m_Head->prev = NULL;
|
||||
} else if (m_Head->next == pNode) {
|
||||
//we are only the first
|
||||
pNode->next->prev = m_Head;
|
||||
m_Head->next = pNode->next;
|
||||
} else if (m_Head->prev == pNode) {
|
||||
//we are the tail
|
||||
pNode->prev->next = m_Head;
|
||||
m_Head->prev = pNode->prev;
|
||||
} else {
|
||||
//middle unlink
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
}
|
||||
|
||||
delete pNode;
|
||||
m_Size--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
public:
|
||||
void remove(const T & obj)
|
||||
{
|
||||
iterator b;
|
||||
for (b=begin(); b!=end(); b++)
|
||||
{
|
||||
if ( (*b) == obj )
|
||||
{
|
||||
erase( b );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename U>
|
||||
iterator find(const U & equ)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=begin(); iter!=end(); iter++)
|
||||
{
|
||||
if ( (*iter) == equ )
|
||||
return iter;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
List & operator =(List &src)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
//}; //NAMESPACE
|
||||
|
||||
#endif //_INCLUDE_CSDM_LIST_H
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user