Compare commits
1 Commits
amxmodx-1.
...
amxmodx-1.
Author | SHA1 | Date | |
---|---|---|---|
7b527c9c25 |
196
amxmodx/CCmd.cpp
196
amxmodx/CCmd.cpp
@ -35,10 +35,8 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CmdMngr
|
// class CmdMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
CmdMngr::CmdMngr() {
|
||||||
CmdMngr::CmdMngr()
|
memset(sortedlists,0,sizeof(sortedlists));
|
||||||
{
|
|
||||||
memset(sortedlists, 0, sizeof(sortedlists));
|
|
||||||
srvcmdlist = 0;
|
srvcmdlist = 0;
|
||||||
clcmdlist = 0;
|
clcmdlist = 0;
|
||||||
prefixHead = 0;
|
prefixHead = 0;
|
||||||
@ -51,12 +49,13 @@ CmdMngr::CmdMngr()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdMngr::Command::Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags,
|
CmdMngr::Command::Command( CPluginMngr::CPlugin* pplugin,const char* pcmd,
|
||||||
int pfunc, bool pviewable, CmdMngr* pparent) : commandline(pcmd), info(pinfo)
|
const char* pinfo , int pflags , int pfunc,
|
||||||
{
|
bool pviewable, CmdMngr* pparent ) : commandline(pcmd) , info(pinfo) {
|
||||||
|
|
||||||
char szCmd[64], szArg[64];
|
char szCmd[64], szArg[64];
|
||||||
*szCmd = 0; *szArg = 0;
|
*szCmd = 0; *szArg=0;
|
||||||
sscanf(pcmd, "%s %s", szCmd, szArg);
|
sscanf(pcmd,"%s %s",szCmd,szArg);
|
||||||
command.assign(szCmd);
|
command.assign(szCmd);
|
||||||
argument.assign(szArg);
|
argument.assign(szArg);
|
||||||
plugin = pplugin;
|
plugin = pplugin;
|
||||||
@ -74,190 +73,180 @@ CmdMngr::Command::~Command()
|
|||||||
++uniqueid;
|
++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);
|
Command* b = new Command( plugin , cmd , info , level , func , listable, this );
|
||||||
if (b == 0) return 0;
|
if ( b == 0 ) return 0;
|
||||||
setCmdLink(&sortedlists[0], b);
|
setCmdLink( &sortedlists[0] , b );
|
||||||
|
return 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 >= 1024 || id < 0 ) return (Command*)id;
|
||||||
if (id < 0)
|
if ( id < 0 ){
|
||||||
{
|
for (CmdMngr::iterator a = begin( type ); a ; ++a){
|
||||||
for (CmdMngr::iterator a = begin(type); a ; ++a)
|
if ( (*a).id == id )
|
||||||
{
|
|
||||||
if ((*a).id == id)
|
|
||||||
return &(*a);
|
return &(*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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_cmdaccess = access;
|
||||||
buf_cmdtype = type;
|
buf_cmdtype = type;
|
||||||
buf_cmdid = id;
|
buf_cmdid = id;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
int a = id;
|
int a = id;
|
||||||
id -= buf_cmdid;
|
id -= buf_cmdid;
|
||||||
buf_cmdid = a;
|
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);
|
return &(*buf_cmdptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++buf_cmdptr;
|
++buf_cmdptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdMngr::getCmdNum(int type, int access)
|
int CmdMngr::getCmdNum( int type, int access )
|
||||||
{
|
{
|
||||||
if ((access == buf_access) && (type == buf_type))
|
if ( (access == buf_access) && (type == buf_type) )
|
||||||
return buf_num; // once calculated don't have to be done again
|
return buf_num; // once calculated don't have to be done again
|
||||||
|
|
||||||
buf_access = access;
|
buf_access = access;
|
||||||
buf_type = type;
|
buf_type = type;
|
||||||
buf_num = 0;
|
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;
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf_num;
|
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;
|
break;
|
||||||
|
|
||||||
a = &(*a)->next;
|
a = &(*a)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
np->next = *a;
|
np->next = *a;
|
||||||
*a = np;
|
*a = np;
|
||||||
} else {
|
}
|
||||||
while (*a) a = &(*a)->next;
|
else
|
||||||
|
{
|
||||||
|
while ( *a ) a = &(*a)->next;
|
||||||
*a = np;
|
*a = np;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::clearCmdLink(CmdLink** phead, bool pclear)
|
void CmdMngr::clearCmdLink( CmdLink** phead, bool pclear )
|
||||||
{
|
{
|
||||||
while (*phead)
|
while( *phead ){
|
||||||
{
|
|
||||||
CmdLink* pp = (*phead)->next;
|
CmdLink* pp = (*phead)->next;
|
||||||
|
if ( pclear ) delete (*phead)->cmd;
|
||||||
if (pclear) delete (*phead)->cmd;
|
|
||||||
delete *phead;
|
delete *phead;
|
||||||
*phead = pp;
|
*phead = pp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::Command::setCmdType(int a)
|
void CmdMngr::Command::setCmdType( int a )
|
||||||
{
|
{
|
||||||
switch (a)
|
switch(a){
|
||||||
{
|
case CMD_ConsoleCommand: cmdtype |= 3; break;
|
||||||
case CMD_ConsoleCommand: cmdtype |= 3; break;
|
case CMD_ClientCommand: cmdtype |= 1; break;
|
||||||
case CMD_ClientCommand: cmdtype |= 1; break;
|
case CMD_ServerCommand: cmdtype |= 2; break;
|
||||||
case CMD_ServerCommand: cmdtype |= 2; break;
|
|
||||||
}
|
}
|
||||||
|
if ( cmdtype & 1 ) { // ClientCommand
|
||||||
if (cmdtype & 1) // ClientCommand
|
parent->setCmdLink( &parent->sortedlists[1] , this );
|
||||||
{
|
if ( !parent->registerCmdPrefix( this ) )
|
||||||
parent->setCmdLink(&parent->sortedlists[1], this);
|
parent->setCmdLink( &parent->clcmdlist , this , false );
|
||||||
|
|
||||||
if (!parent->registerCmdPrefix(this))
|
|
||||||
parent->setCmdLink(&parent->clcmdlist, this, false);
|
|
||||||
}
|
}
|
||||||
|
if ( cmdtype & 2 ) { // ServerCommand
|
||||||
if (cmdtype & 2) // ServerCommand
|
parent->setCmdLink( &parent->sortedlists[2] , this );
|
||||||
{
|
parent->setCmdLink( &parent->srvcmdlist , this , false );
|
||||||
parent->setCmdLink(&parent->sortedlists[2], this);
|
|
||||||
parent->setCmdLink(&parent->srvcmdlist, this, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CmdMngr::Command::getCmdType() const
|
const char* CmdMngr::Command::getCmdType() const {
|
||||||
{
|
switch( cmdtype ){
|
||||||
switch (cmdtype)
|
case 1: return"client";
|
||||||
{
|
case 2: return "server";
|
||||||
case 1: return "client";
|
case 3: return "console";
|
||||||
case 2: return "server";
|
|
||||||
case 3: return "console";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CmdMngr::registerCmdPrefix(Command* cc)
|
bool CmdMngr::registerCmdPrefix( Command* cc )
|
||||||
{
|
{
|
||||||
CmdPrefix** b = findPrefix(cc->getCommand());
|
CmdPrefix** b = findPrefix( cc->getCommand() );
|
||||||
|
if (*b){
|
||||||
if (*b)
|
setCmdLink( &(*b)->list , cc , false );
|
||||||
{
|
|
||||||
setCmdLink(&(*b)->list, cc, false);
|
|
||||||
cc->prefix = (*b)->name.size();
|
cc->prefix = (*b)->name.size();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::registerPrefix(const char* nn)
|
void CmdMngr::registerPrefix( const char* nn )
|
||||||
{
|
{
|
||||||
if (*nn == 0) return;
|
if ( *nn == 0 ) return;
|
||||||
CmdPrefix** b = findPrefix(nn);
|
CmdPrefix** b = findPrefix( nn );
|
||||||
|
|
||||||
if (*b) return;
|
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;
|
CmdPrefix** aa = &prefixHead;
|
||||||
|
while(*aa){
|
||||||
while (*aa)
|
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
|
||||||
{
|
|
||||||
if (!strncmp((*aa)->name.c_str(), nn, (*aa)->name.size()))
|
|
||||||
break;
|
break;
|
||||||
aa = &(*aa)->next;
|
aa=&(*aa)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return aa;
|
return aa;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::clearPrefix()
|
void CmdMngr::clearPrefix(){
|
||||||
{
|
while(prefixHead){
|
||||||
while (prefixHead)
|
|
||||||
{
|
|
||||||
CmdPrefix* a = prefixHead->next;
|
CmdPrefix* a = prefixHead->next;
|
||||||
delete prefixHead;
|
delete prefixHead;
|
||||||
prefixHead = a;
|
prefixHead = a;
|
||||||
@ -275,8 +264,7 @@ void CmdMngr::clear()
|
|||||||
clearBufforedInfo();
|
clearBufforedInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::clearBufforedInfo()
|
void CmdMngr::clearBufforedInfo() {
|
||||||
{
|
|
||||||
buf_type = -1;
|
buf_type = -1;
|
||||||
buf_access = 0;
|
buf_access = 0;
|
||||||
buf_id = -1;
|
buf_id = -1;
|
||||||
@ -285,4 +273,4 @@ void CmdMngr::clearBufforedInfo()
|
|||||||
buf_cmdaccess = 0;
|
buf_cmdaccess = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdMngr::Command::uniqueid = 0;
|
int CmdMngr::Command::uniqueid = 0;
|
@ -36,8 +36,7 @@
|
|||||||
// class CmdMngr
|
// class CmdMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
CMD_ConsoleCommand,
|
CMD_ConsoleCommand,
|
||||||
CMD_ClientCommand,
|
CMD_ClientCommand,
|
||||||
CMD_ServerCommand
|
CMD_ServerCommand
|
||||||
@ -49,17 +48,14 @@ public:
|
|||||||
class Command;
|
class Command;
|
||||||
friend class Command;
|
friend class Command;
|
||||||
|
|
||||||
class Command
|
class Command {
|
||||||
{
|
|
||||||
friend class CmdMngr;
|
friend class CmdMngr;
|
||||||
|
|
||||||
CPluginMngr::CPlugin* plugin;
|
CPluginMngr::CPlugin* plugin;
|
||||||
CmdMngr* parent;
|
CmdMngr* parent;
|
||||||
String command;
|
String command;
|
||||||
String argument;
|
String argument;
|
||||||
String commandline;
|
String commandline;
|
||||||
String info;
|
String info;
|
||||||
|
|
||||||
bool listable;
|
bool listable;
|
||||||
int function;
|
int function;
|
||||||
int flags;
|
int flags;
|
||||||
@ -67,33 +63,33 @@ public:
|
|||||||
int cmdtype;
|
int cmdtype;
|
||||||
int prefix;
|
int prefix;
|
||||||
static int uniqueid;
|
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();
|
~Command();
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline const char* getCommand() { return command.c_str(); }
|
inline const char* getCommand() { return command.c_str(); }
|
||||||
inline const char* getArgument() { return argument.c_str(); }
|
inline const char* getArgument() { return argument.c_str(); }
|
||||||
inline const char* getCmdInfo() { return info.c_str(); }
|
inline const char* getCmdInfo() { return info.c_str(); }
|
||||||
inline const char* getCmdLine() { return commandline.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 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 matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd )); }
|
||||||
inline int getFunction() const { return function; }
|
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 CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||||
inline bool isViewable() const { return listable; }
|
inline bool isViewable() const { return listable; }
|
||||||
inline int getFlags() const { return flags; }
|
inline int getFlags() const { return flags; }
|
||||||
inline long int getId() const { return (long int)id; }
|
inline long int getId() const { return (long int)id; }
|
||||||
|
|
||||||
const char* getCmdType() const;
|
const char* getCmdType() const;
|
||||||
void setCmdType(int a);
|
void setCmdType( int a );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct CmdPrefix;
|
struct CmdPrefix;
|
||||||
friend struct CmdPrefix;
|
friend struct CmdPrefix;
|
||||||
|
|
||||||
struct CmdLink
|
struct CmdLink {
|
||||||
{
|
|
||||||
Command* cmd;
|
Command* cmd;
|
||||||
CmdLink* next;
|
CmdLink* next;
|
||||||
CmdLink(Command* c): cmd(c), next(0) {}
|
CmdLink(Command* c): cmd(c), next(0) {}
|
||||||
@ -103,40 +99,36 @@ private:
|
|||||||
CmdLink* srvcmdlist;
|
CmdLink* srvcmdlist;
|
||||||
CmdLink* clcmdlist;
|
CmdLink* clcmdlist;
|
||||||
|
|
||||||
struct CmdPrefix
|
struct CmdPrefix {
|
||||||
{
|
|
||||||
String name;
|
String name;
|
||||||
CmdMngr* parent;
|
CmdMngr* parent;
|
||||||
CmdLink* list;
|
CmdLink* list;
|
||||||
CmdPrefix* next;
|
CmdPrefix* next;
|
||||||
CmdPrefix(const char* nn, CmdMngr* pp): name(nn), parent(pp), list(0), next(0) {}
|
CmdPrefix( const char* nn , CmdMngr* pp) : name(nn),parent(pp),list(0),next(0){}
|
||||||
~CmdPrefix() { parent->clearCmdLink(&list); }
|
~CmdPrefix(){ parent->clearCmdLink(&list); }
|
||||||
} *prefixHead;
|
} *prefixHead;
|
||||||
|
|
||||||
bool registerCmdPrefix(Command* cc);
|
bool registerCmdPrefix( Command* cc );
|
||||||
CmdPrefix** findPrefix(const char* nn);
|
CmdPrefix** findPrefix( const char* nn );
|
||||||
void clearPrefix();
|
void clearPrefix();
|
||||||
|
|
||||||
void setCmdLink(CmdLink** a, Command* c, bool sorted = true);
|
void setCmdLink( CmdLink** a , Command* c, bool sorted = true );
|
||||||
void clearCmdLink(CmdLink** phead, bool pclear = false);
|
void clearCmdLink( CmdLink** phead, bool pclear = false );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CmdMngr();
|
CmdMngr();
|
||||||
~CmdMngr() { clear(); }
|
~CmdMngr() {clear();}
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
void registerPrefix(const char* nn);
|
void registerPrefix( const char* nn );
|
||||||
|
Command* registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable );
|
||||||
Command* registerCommand(CPluginMngr::CPlugin* plugin, int func, char* cmd, char* info, int level, bool listable);
|
Command* getCmd( long int id ,int type, int access);
|
||||||
Command* getCmd(long int id, int type, int access);
|
int getCmdNum( int type, int access );
|
||||||
int getCmdNum(int type, int access);
|
|
||||||
|
|
||||||
void clearBufforedInfo();
|
void clearBufforedInfo();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
class iterator
|
class iterator {
|
||||||
{
|
|
||||||
CmdLink *a;
|
CmdLink *a;
|
||||||
public:
|
public:
|
||||||
iterator(CmdLink*aa = 0) : a(aa) {}
|
iterator(CmdLink*aa = 0) : a(aa) {}
|
||||||
@ -146,30 +138,28 @@ public:
|
|||||||
operator bool () const { return a ? true : false; }
|
operator bool () const { return a ? true : false; }
|
||||||
Command& operator*() { return *a->cmd; }
|
Command& operator*() { return *a->cmd; }
|
||||||
};
|
};
|
||||||
|
inline iterator clcmdprefixbegin(const char* nn){
|
||||||
inline iterator clcmdprefixbegin(const char* nn)
|
|
||||||
{
|
|
||||||
CmdPrefix* a = *findPrefix(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 clcmdbegin() const { return iterator(clcmdlist); }
|
inline iterator srvcmdbegin() const {return iterator(srvcmdlist);}
|
||||||
inline iterator srvcmdbegin() const { return iterator(srvcmdlist); }
|
inline iterator begin( int type ) const { return iterator(sortedlists[type]); }
|
||||||
inline iterator begin(int type) const { return iterator(sortedlists[type]); }
|
|
||||||
inline iterator end() const { return iterator(0); }
|
inline iterator end() const { return iterator(0); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int buf_cmdid;
|
int buf_cmdid;
|
||||||
int buf_cmdtype;
|
int buf_cmdtype;
|
||||||
int buf_cmdaccess;
|
int buf_cmdaccess;
|
||||||
|
|
||||||
iterator buf_cmdptr;
|
iterator buf_cmdptr;
|
||||||
|
|
||||||
int buf_id;
|
int buf_id;
|
||||||
int buf_type;
|
int buf_type;
|
||||||
int buf_access;
|
int buf_access;
|
||||||
int buf_num;
|
int buf_num;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //COMMANDS_H
|
#endif
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
// class ClEvent
|
// 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_Plugin = plugin;
|
||||||
m_Func = func;
|
m_Func = func;
|
||||||
@ -45,14 +45,13 @@ EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
|||||||
m_FlagAlive = true;
|
m_FlagAlive = true;
|
||||||
m_FlagDead = true;
|
m_FlagDead = true;
|
||||||
|
|
||||||
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||||
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||||
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||||
|
|
||||||
if (flags & 24)
|
if (flags & 24)
|
||||||
{
|
{
|
||||||
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||||
m_FlagDead = (flags & 8) ? true : false; // flag d
|
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Stamp = 0.0f;
|
m_Stamp = 0.0f;
|
||||||
@ -65,14 +64,12 @@ EventsMngr::ClEvent::~ClEvent()
|
|||||||
{
|
{
|
||||||
cond_t *tmp1 = m_Conditions;
|
cond_t *tmp1 = m_Conditions;
|
||||||
cond_t *tmp2 = NULL;
|
cond_t *tmp2 = NULL;
|
||||||
|
|
||||||
while (tmp1)
|
while (tmp1)
|
||||||
{
|
{
|
||||||
tmp2 = tmp1->next;
|
tmp2 = tmp1->next;
|
||||||
delete tmp1;
|
delete tmp1;
|
||||||
tmp1 = tmp2;
|
tmp1 = tmp2;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Conditions = NULL;
|
m_Conditions = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,17 +82,14 @@ void EventsMngr::NextParam()
|
|||||||
|
|
||||||
MsgDataEntry *tmp = NULL;
|
MsgDataEntry *tmp = NULL;
|
||||||
int tmpSize = 0;
|
int tmpSize = 0;
|
||||||
|
|
||||||
if (m_ParseVault)
|
if (m_ParseVault)
|
||||||
{
|
{
|
||||||
// copy to tmp
|
// copy to tmp
|
||||||
tmp = new MsgDataEntry[m_ParseVaultSize];
|
tmp = new MsgDataEntry[m_ParseVaultSize];
|
||||||
|
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
return; // :TODO: Error report !!
|
return; // :TODO: Error report !!
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(tmp, m_ParseVault, m_ParseVaultSize * sizeof(MsgDataEntry));
|
memcpy(tmp, m_ParseVault, m_ParseVaultSize * sizeof(MsgDataEntry));
|
||||||
tmpSize = m_ParseVaultSize;
|
tmpSize = m_ParseVaultSize;
|
||||||
delete [] m_ParseVault;
|
delete [] m_ParseVault;
|
||||||
@ -108,7 +102,6 @@ void EventsMngr::NextParam()
|
|||||||
m_ParseVaultSize = INITIAL_PARSEVAULT_SIZE;
|
m_ParseVaultSize = INITIAL_PARSEVAULT_SIZE;
|
||||||
|
|
||||||
m_ParseVault = new MsgDataEntry[m_ParseVaultSize];
|
m_ParseVault = new MsgDataEntry[m_ParseVaultSize];
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
memcpy(m_ParseVault, tmp, tmpSize * sizeof(MsgDataEntry));
|
memcpy(m_ParseVault, tmp, tmpSize * sizeof(MsgDataEntry));
|
||||||
@ -135,6 +128,7 @@ EventsMngr::~EventsMngr()
|
|||||||
clearEvents();
|
clearEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
|
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
|
||||||
{
|
{
|
||||||
return m_Plugin;
|
return m_Plugin;
|
||||||
@ -176,7 +170,7 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
|
|||||||
|
|
||||||
// rest of line
|
// rest of line
|
||||||
tmpCond->sValue.assign(value);
|
tmpCond->sValue.assign(value);
|
||||||
tmpCond->fValue = static_cast<float>(atof(value));
|
tmpCond->fValue = atof(value);
|
||||||
tmpCond->iValue = atoi(value);
|
tmpCond->iValue = atoi(value);
|
||||||
|
|
||||||
tmpCond->next = NULL;
|
tmpCond->next = NULL;
|
||||||
@ -184,11 +178,10 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
|
|||||||
if (m_Conditions)
|
if (m_Conditions)
|
||||||
{
|
{
|
||||||
cond_t *tmp = m_Conditions;
|
cond_t *tmp = m_Conditions;
|
||||||
|
|
||||||
while (tmp->next)
|
while (tmp->next)
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
|
||||||
tmp->next = tmpCond;
|
tmp->next = tmpCond;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_Conditions = tmpCond;
|
m_Conditions = tmpCond;
|
||||||
@ -201,7 +194,6 @@ EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ClEvent *event = new ClEvent(plugin, func, flags);
|
ClEvent *event = new ClEvent(plugin, func, flags);
|
||||||
|
|
||||||
if (!event)
|
if (!event)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -224,11 +216,12 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
|||||||
if (!m_Events[msg_type].size())
|
if (!m_Events[msg_type].size())
|
||||||
return;
|
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)
|
if ((*iter).m_Done)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
if (!(*iter).m_Plugin->isExecutable((*iter).m_Func))
|
if (!(*iter).m_Plugin->isExecutable((*iter).m_Func))
|
||||||
{
|
{
|
||||||
(*iter).m_Done = true;
|
(*iter).m_Done = true;
|
||||||
@ -237,7 +230,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
|||||||
|
|
||||||
if (pPlayer)
|
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;
|
(*iter).m_Done = true;
|
||||||
continue;
|
continue;
|
||||||
@ -254,7 +247,6 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
|||||||
(*iter).m_Done = true;
|
(*iter).m_Done = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ParseNotDone = true;
|
m_ParseNotDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +257,6 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
|||||||
m_ParseVault[0].type = MSG_INTEGER;
|
m_ParseVault[0].type = MSG_INTEGER;
|
||||||
m_ParseVault[0].iValue = index;
|
m_ParseVault[0].iValue = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ParseFun = &m_Events[msg_type];
|
m_ParseFun = &m_Events[msg_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +266,7 @@ void EventsMngr::parseValue(int iValue)
|
|||||||
if (!m_ParseNotDone || !m_ParseFun)
|
if (!m_ParseNotDone || !m_ParseFun)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
// grow if needed
|
// grow if needed
|
||||||
++m_ParsePos;
|
++m_ParsePos;
|
||||||
NextParam();
|
NextParam();
|
||||||
@ -292,25 +284,23 @@ void EventsMngr::parseValue(int iValue)
|
|||||||
// loop through conditions
|
// loop through conditions
|
||||||
bool execute = false;
|
bool execute = false;
|
||||||
bool anyConditions = false;
|
bool anyConditions = false;
|
||||||
|
|
||||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||||
{
|
{
|
||||||
if (condIter->paramId == m_ParsePos)
|
if (condIter->paramId == m_ParsePos)
|
||||||
{
|
{
|
||||||
anyConditions = true;
|
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 (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 (iValue < condIter->iValue) execute=true; break;
|
||||||
case '>': if (iValue > condIter->iValue) execute = true; break;
|
case '>': if (iValue > condIter->iValue) execute=true; break;
|
||||||
}
|
}
|
||||||
if (execute)
|
if (execute)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyConditions && !execute)
|
if (anyConditions && !execute)
|
||||||
(*iter).m_Done = true; // don't execute
|
(*iter).m_Done = true; // don't execute
|
||||||
}
|
}
|
||||||
@ -322,6 +312,7 @@ void EventsMngr::parseValue(float fValue)
|
|||||||
if (!m_ParseNotDone || !m_ParseFun)
|
if (!m_ParseNotDone || !m_ParseFun)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
// grow if needed
|
// grow if needed
|
||||||
++m_ParsePos;
|
++m_ParsePos;
|
||||||
NextParam();
|
NextParam();
|
||||||
@ -339,25 +330,22 @@ void EventsMngr::parseValue(float fValue)
|
|||||||
// loop through conditions
|
// loop through conditions
|
||||||
bool execute = false;
|
bool execute = false;
|
||||||
bool anyConditions = false;
|
bool anyConditions = false;
|
||||||
|
|
||||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||||
{
|
{
|
||||||
if (condIter->paramId == m_ParsePos)
|
if (condIter->paramId == m_ParsePos)
|
||||||
{
|
{
|
||||||
anyConditions = true;
|
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 (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 (fValue > condIter->fValue) execute = true; break;
|
case '>': if (fValue > condIter->fValue) execute=true; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execute)
|
if (execute)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyConditions && !execute)
|
if (anyConditions && !execute)
|
||||||
(*iter).m_Done = true; // don't execute
|
(*iter).m_Done = true; // don't execute
|
||||||
}
|
}
|
||||||
@ -386,24 +374,21 @@ void EventsMngr::parseValue(const char *sz)
|
|||||||
// loop through conditions
|
// loop through conditions
|
||||||
bool execute = false;
|
bool execute = false;
|
||||||
bool anyConditions = false;
|
bool anyConditions = false;
|
||||||
|
|
||||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||||
{
|
{
|
||||||
if (condIter->paramId == m_ParsePos)
|
if (condIter->paramId == m_ParsePos)
|
||||||
{
|
{
|
||||||
anyConditions = true;
|
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 (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 (strstr(sz, condIter->sValue.c_str())) execute=true; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (execute)
|
if (execute)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyConditions && !execute)
|
if (anyConditions && !execute)
|
||||||
(*iter).m_Done = true; // don't execute
|
(*iter).m_Done = true; // don't execute
|
||||||
}
|
}
|
||||||
@ -418,14 +403,13 @@ void EventsMngr::executeEvents()
|
|||||||
|
|
||||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||||
{
|
{
|
||||||
if ((*iter).m_Done)
|
if ( (*iter).m_Done )
|
||||||
{
|
{
|
||||||
(*iter).m_Done = false;
|
(*iter).m_Done = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*iter).m_Stamp = (float)*m_Timer;
|
(*iter).m_Stamp = (float)*m_Timer;
|
||||||
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0));
|
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CurrentMsgType = -1;
|
m_CurrentMsgType = -1;
|
||||||
@ -439,53 +423,53 @@ int EventsMngr::getArgNum() const
|
|||||||
|
|
||||||
const char* EventsMngr::getArgString(int a) const
|
const char* EventsMngr::getArgString(int a) const
|
||||||
{
|
{
|
||||||
if (a < 0 || a > m_ParsePos)
|
if ( a < 0 || a > m_ParsePos )
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
static char var[32];
|
static char var[32];
|
||||||
|
|
||||||
switch (m_ParseVault[a].type)
|
switch(m_ParseVault[a].type)
|
||||||
{
|
{
|
||||||
case MSG_INTEGER:
|
case MSG_INTEGER:
|
||||||
sprintf(var, "%d", m_ParseVault[a].iValue);
|
sprintf( var, "%d", m_ParseVault[a].iValue );
|
||||||
return var;
|
return var;
|
||||||
case MSG_STRING:
|
case MSG_STRING:
|
||||||
return m_ParseVault[a].sValue;
|
return m_ParseVault[a].sValue;
|
||||||
default:
|
default:
|
||||||
sprintf(var, "%g", m_ParseVault[a].fValue);
|
sprintf( var, "%g", m_ParseVault[a].fValue );
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventsMngr::getArgInteger(int a) const
|
int EventsMngr::getArgInteger(int a) const
|
||||||
{
|
{
|
||||||
if (a < 0 || a > m_ParsePos)
|
if ( a < 0 || a > m_ParsePos )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
switch (m_ParseVault[a].type)
|
switch(m_ParseVault[a].type)
|
||||||
{
|
{
|
||||||
case MSG_INTEGER:
|
case MSG_INTEGER:
|
||||||
return m_ParseVault[a].iValue;
|
return m_ParseVault[a].iValue;
|
||||||
case MSG_STRING:
|
case MSG_STRING:
|
||||||
return atoi(m_ParseVault[a].sValue);
|
return atoi(m_ParseVault[a].sValue);
|
||||||
default:
|
default:
|
||||||
return (int)m_ParseVault[a].fValue;
|
return (int)m_ParseVault[a].fValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float EventsMngr::getArgFloat(int a) const
|
float EventsMngr::getArgFloat(int a) const
|
||||||
{
|
{
|
||||||
if (a < 0 || a > m_ParsePos)
|
if ( a < 0 || a > m_ParsePos )
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
switch (m_ParseVault[a].type)
|
switch(m_ParseVault[a].type)
|
||||||
{
|
{
|
||||||
case MSG_INTEGER:
|
case MSG_INTEGER:
|
||||||
return static_cast<float>(m_ParseVault[a].iValue);
|
return m_ParseVault[a].iValue;
|
||||||
case MSG_STRING:
|
case MSG_STRING:
|
||||||
return static_cast<float>(atof(m_ParseVault[a].sValue));
|
return atof(m_ParseVault[a].sValue);
|
||||||
default:
|
default:
|
||||||
return m_ParseVault[a].fValue;
|
return m_ParseVault[a].fValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +479,6 @@ void EventsMngr::clearEvents(void)
|
|||||||
{
|
{
|
||||||
m_Events[i].clear();
|
m_Events[i].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete parsevault
|
// delete parsevault
|
||||||
if (m_ParseVault)
|
if (m_ParseVault)
|
||||||
{
|
{
|
||||||
@ -514,26 +497,25 @@ int EventsMngr::getEventId(const char* msg)
|
|||||||
CS_EventsIds id;
|
CS_EventsIds id;
|
||||||
} table[] =
|
} table[] =
|
||||||
{
|
{
|
||||||
{"CS_DeathMsg", CS_DeathMsg},
|
{ "CS_DeathMsg" , CS_DeathMsg },
|
||||||
// {"CS_RoundEnd", CS_RoundEnd},
|
// { "CS_RoundEnd" , CS_RoundEnd },
|
||||||
// {"CS_RoundStart", CS_RoundStart},
|
// { "CS_RoundStart" , CS_RoundStart },
|
||||||
// {"CS_Restart", CS_Restart},
|
// { "CS_Restart" , CS_Restart },
|
||||||
{"", CS_Null}
|
{ "" , CS_Null }
|
||||||
};
|
};
|
||||||
|
|
||||||
// if msg is a number, return it
|
// if msg is a number, return it
|
||||||
int pos = atoi(msg);
|
int pos = atoi(msg);
|
||||||
|
|
||||||
if (pos != 0)
|
if (pos != 0)
|
||||||
return pos;
|
return pos;
|
||||||
|
|
||||||
// try to find in table first
|
// try to find in table first
|
||||||
for (pos = 0; table[pos].id != CS_Null; ++pos)
|
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
|
||||||
if (!strcmp(table[pos].name, msg))
|
if ( !strcmp( table[ pos ].name , msg ) )
|
||||||
return table[pos].id;
|
return table[ pos ].id;
|
||||||
|
|
||||||
// find the id of the message
|
// 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()
|
int EventsMngr::getCurrentMsgType()
|
||||||
|
@ -32,10 +32,9 @@
|
|||||||
#ifndef __CEVENTS_H__
|
#ifndef __CEVENTS_H__
|
||||||
#define __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_DEATHMSG = MAX_REG_MSGS,
|
||||||
// CS_ROUNDEND,
|
// CS_ROUNDEND,
|
||||||
// CS_ROUNDSTART,
|
// CS_ROUNDSTART,
|
||||||
@ -68,7 +67,7 @@ public:
|
|||||||
|
|
||||||
class ClEvent
|
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
|
int m_Func; // function to be executed
|
||||||
CPluginMngr::CPlugin *m_Plugin; // the plugin this ClEvent class is assigned to
|
CPluginMngr::CPlugin *m_Plugin; // the plugin this ClEvent class is assigned to
|
||||||
@ -101,7 +100,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// constructors & destructors
|
// constructors & destructors
|
||||||
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||||
~ClEvent();
|
~ClEvent();
|
||||||
|
|
||||||
inline CPluginMngr::CPlugin* getPlugin();
|
inline CPluginMngr::CPlugin* getPlugin();
|
||||||
@ -117,22 +116,21 @@ private:
|
|||||||
const char* sValue;
|
const char* sValue;
|
||||||
MsgParamType type;
|
MsgParamType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
MsgDataEntry *m_ParseVault;
|
MsgDataEntry *m_ParseVault;
|
||||||
int m_ParseVaultSize;
|
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 CList<ClEvent> ClEventVec;
|
||||||
typedef ClEventVec::iterator ClEventVecIter;
|
typedef ClEventVec::iterator ClEventVecIter;
|
||||||
|
|
||||||
ClEventVec m_Events[MAX_AMX_REG_MSG];
|
ClEventVec m_Events[MAX_AMX_REG_MSG];
|
||||||
ClEventVec *m_ParseFun; // current Event vector
|
ClEventVec *m_ParseFun; // current Event vector
|
||||||
|
|
||||||
bool m_ParseNotDone;
|
bool m_ParseNotDone;
|
||||||
int m_ParsePos; // is args. num. - 1
|
int m_ParsePos; // is args. num. - 1
|
||||||
float* m_Timer;
|
float* m_Timer;
|
||||||
|
|
||||||
ClEvent* getValidEvent(ClEvent* a);
|
ClEvent* getValidEvent(ClEvent* a );
|
||||||
|
|
||||||
int m_CurrentMsgType;
|
int m_CurrentMsgType;
|
||||||
public:
|
public:
|
||||||
@ -142,20 +140,20 @@ public:
|
|||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
|
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
|
||||||
|
|
||||||
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
|
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
|
||||||
void parseValue(int iValue);
|
void parseValue(int iValue);
|
||||||
void parseValue(float fValue);
|
void parseValue(float fValue);
|
||||||
void parseValue(const char *sz);
|
void parseValue(const char *sz);
|
||||||
void executeEvents();
|
void executeEvents();
|
||||||
|
int getArgNum() const; //{ return (parsePos+1); }
|
||||||
int getArgNum() const; //{ return (parsePos + 1); }
|
|
||||||
const char* getArgString(int a) const;
|
const char* getArgString(int a) const;
|
||||||
int getArgInteger(int a) const;
|
int getArgInteger(int a) const;
|
||||||
float getArgFloat(int a) const;
|
float getArgFloat(int a) const;
|
||||||
void clearEvents(void);
|
void clearEvents(void);
|
||||||
static int getEventId(const char* msg);
|
static int getEventId( const char* msg );
|
||||||
int getCurrentMsgType();
|
int getCurrentMsgType();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__CEVENTS_H__
|
#endif // #ifdef __CEVENTS_H__
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,91 +36,91 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class File
|
// 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)
|
if ( fp )
|
||||||
fclose(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);
|
if ( f ) fputs( n.c_str() , f.fp ) ;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator<<(File& f, const char* n)
|
File& operator<<( File& f, const char* n )
|
||||||
{
|
{
|
||||||
if (f) fputs(n, f.fp);
|
if ( f ) fputs( n , f.fp ) ;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator<<(File& f, int n)
|
File& operator<<( File& f, int n )
|
||||||
{
|
{
|
||||||
if (f) fprintf(f.fp, "%d", n);
|
if ( f ) fprintf( f.fp , "%d" , n ) ;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator<<(File& f, const char& c)
|
|
||||||
|
File& operator<<( File& f, const char& c )
|
||||||
{
|
{
|
||||||
if (f) fputc(c, f.fp);
|
if ( f ) fputc( c , f.fp ) ;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator>>(File& f, String& n)
|
File& operator>>( File& f, String& n )
|
||||||
{
|
{
|
||||||
if (!f) return f;
|
if ( !f ) return f;
|
||||||
char temp[1024];
|
char temp[1024];
|
||||||
fscanf(f.fp, "%s", temp);
|
fscanf( f.fp , "%s", temp );
|
||||||
n.assign(temp);
|
n.assign(temp);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
File& operator>>(File& f, char* n)
|
File& operator>>( File& f, char* n )
|
||||||
{
|
{
|
||||||
if (f) fscanf(f.fp, "%s", n);
|
if ( f ) fscanf( f.fp , "%s", n );
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
int File::getline(char* buf, int sz)
|
int File::getline( char* buf, int sz )
|
||||||
{
|
{
|
||||||
int a = sz;
|
int a = sz;
|
||||||
char *origBuf = buf;
|
char *origBuf = buf;
|
||||||
|
if ( *this )
|
||||||
if (*this)
|
{
|
||||||
{
|
int c;
|
||||||
int c;
|
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
|
||||||
while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
|
*buf++ = c;
|
||||||
*buf++ = c;
|
*buf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trim 0x0a and 0x0d characters at the end
|
||||||
|
while (buf != origBuf)
|
||||||
|
{
|
||||||
|
if (*buf == 0x0a || *buf == 0x0d)
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
}
|
--buf;
|
||||||
|
}
|
||||||
|
|
||||||
// trim 0x0a and 0x0d characters at the end
|
return a - sz;
|
||||||
while (buf != origBuf)
|
|
||||||
{
|
|
||||||
if (*buf == 0x0a || *buf == 0x0d)
|
|
||||||
*buf = 0;
|
|
||||||
--buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
return a - sz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File& File::skipWs()
|
File& File::skipWs( )
|
||||||
{
|
{
|
||||||
if (!*this) return *this;
|
if ( !*this ) return *this;
|
||||||
int c;
|
int c;
|
||||||
while (isspace(c = getc(fp))) {};
|
while( isspace( c = getc( fp ) ) ){};
|
||||||
ungetc(c, fp);
|
ungetc( c , fp );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,19 +41,18 @@ class File
|
|||||||
FILE* fp;
|
FILE* fp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
File(const char* n, const char* m);
|
File( const char* n, const char* m );
|
||||||
~File();
|
~File( );
|
||||||
|
operator bool ( ) const;
|
||||||
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 String& n);
|
friend File& operator<<( File& f, const char& c );
|
||||||
friend File& operator<<(File& f, const char* n);
|
friend File& operator<<( File& f, int n );
|
||||||
friend File& operator<<(File& f, const char& c);
|
friend File& operator>>( File& f, String& n );
|
||||||
friend File& operator<<(File& f, int n);
|
friend File& operator>>( File& f, char* n );
|
||||||
friend File& operator>>(File& f, String& n);
|
int getline( char* buf, int sz );
|
||||||
friend File& operator>>(File& f, char* n);
|
File& skipWs( );
|
||||||
|
|
||||||
int getline(char* buf, int sz);
|
|
||||||
|
|
||||||
File& skipWs();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* In addition, as a special exception, the author gives permission to
|
* In addition, as a special exception, the author gives permission to
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
* 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
|
* 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
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
@ -30,30 +30,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "debugger.h"
|
|
||||||
#include "binlog.h"
|
|
||||||
|
|
||||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type)
|
void AMXAPI amxx_InvalidateTrace(AMX *amx);
|
||||||
|
|
||||||
|
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||||
{
|
{
|
||||||
m_FuncName = name;
|
m_FuncName = name;
|
||||||
m_ExecType = et;
|
m_ExecType = et;
|
||||||
m_NumParams = numParams;
|
m_NumParams = numParams;
|
||||||
|
|
||||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||||
|
|
||||||
// find funcs
|
// find funcs
|
||||||
int func;
|
int func;
|
||||||
|
AMXForward *tmp = NULL;
|
||||||
m_Funcs.clear();
|
m_Funcs.clear();
|
||||||
|
|
||||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||||
{
|
{
|
||||||
if ((fwd_type != FORWARD_ALL) &&
|
|
||||||
((fwd_type == FORWARD_ONLY_NEW && ((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
|
|
||||||
|| (fwd_type == FORWARD_ONLY_OLD && !((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
|
|
||||||
))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
AMXForward tmp;
|
AMXForward tmp;
|
||||||
@ -62,8 +53,6 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
|
|||||||
m_Funcs.push_back(tmp);
|
m_Funcs.push_back(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Name.assign(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
@ -75,6 +64,8 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
|
|
||||||
cell globRetVal = 0;
|
cell globRetVal = 0;
|
||||||
|
|
||||||
|
unsigned int id = 0;
|
||||||
|
|
||||||
AMXForwardList::iterator iter;
|
AMXForwardList::iterator iter;
|
||||||
|
|
||||||
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
|
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
|
||||||
@ -83,78 +74,66 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
{
|
{
|
||||||
// Get debug info
|
// Get debug info
|
||||||
AMX *amx = (*iter).pPlugin->getAMX();
|
AMX *amx = (*iter).pPlugin->getAMX();
|
||||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||||
|
if (pInfo)
|
||||||
if (pDebugger)
|
pInfo->error = AMX_ERR_NONE;
|
||||||
pDebugger->BeginExec();
|
|
||||||
|
|
||||||
// handle strings & arrays
|
// handle strings & arrays
|
||||||
int i;
|
int i, ax=0;
|
||||||
|
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
{
|
{
|
||||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
const char *str = reinterpret_cast<const char*>(params[i]);
|
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
if (!str)
|
amx_Allot(iter->pPlugin->getAMX(),
|
||||||
str = "";
|
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
&realParams[i], &tmp);
|
||||||
amx_SetStringOld(tmp, str, 0, 0);
|
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||||
physAddrs[i] = tmp;
|
physAddrs[i] = tmp;
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
cell *tmp;
|
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;
|
physAddrs[i] = tmp;
|
||||||
|
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
realParams[i] = params[i];
|
realParams[i] = params[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
for (i=m_NumParams-1; i>=0; i--)
|
||||||
for (i = m_NumParams-1; i >= 0; i--)
|
|
||||||
{
|
{
|
||||||
amx_Push(amx, realParams[i]);
|
amx_Push(amx, realParams[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// exec
|
// exec
|
||||||
cell retVal;
|
cell retVal;
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
|
|
||||||
#endif
|
|
||||||
int err = amx_Exec(amx, &retVal, iter->func);
|
int err = amx_Exec(amx, &retVal, iter->func);
|
||||||
|
|
||||||
// log runtime error, if any
|
// log runtime error, if any
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
//Did something else set an error?
|
//Did something else set an error?
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
//we don't care, something else logged the error.
|
//we don't care, something else logged the error.
|
||||||
}
|
} else {
|
||||||
else if (err != -1)
|
|
||||||
{
|
|
||||||
//nothing logged the error so spit it out anyway
|
//nothing logged the error so spit it out anyway
|
||||||
LogError(amx, err, NULL);
|
LogError(amx, err, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
amxx_InvalidateTrace(amx);
|
||||||
amx->error = AMX_ERR_NONE;
|
amx->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->EndExec();
|
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
@ -178,9 +157,10 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
}
|
}
|
||||||
@ -192,42 +172,35 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
// decide what to do (based on exectype and retval)
|
// decide what to do (based on exectype and retval)
|
||||||
switch (m_ExecType)
|
switch (m_ExecType)
|
||||||
{
|
{
|
||||||
case ET_IGNORE:
|
case ET_IGNORE:
|
||||||
break;
|
break;
|
||||||
case ET_STOP:
|
case ET_STOP:
|
||||||
if (retVal > 0)
|
if (retVal > 0)
|
||||||
return retVal;
|
return retVal;
|
||||||
case ET_STOP2:
|
case ET_STOP2:
|
||||||
if (retVal == 1)
|
if (retVal == 1)
|
||||||
return 1;
|
return 1;
|
||||||
else if (retVal > globRetVal)
|
else if (retVal > globRetVal)
|
||||||
globRetVal = retVal;
|
globRetVal = retVal;
|
||||||
break;
|
break;
|
||||||
case ET_CONTINUE:
|
case ET_CONTINUE:
|
||||||
if (retVal > globRetVal)
|
if (retVal > globRetVal)
|
||||||
globRetVal = retVal;
|
globRetVal = retVal;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return globRetVal;
|
return globRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
{
|
{
|
||||||
char name[sNAMEMAX];
|
|
||||||
m_Func = func;
|
m_Func = func;
|
||||||
m_Amx = amx;
|
m_Amx = amx;
|
||||||
m_NumParams = numParams;
|
m_NumParams = numParams;
|
||||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||||
m_HasFunc = true;
|
m_HasFunc = true;
|
||||||
isFree = false;
|
isFree = false;
|
||||||
name[0] = '\0';
|
|
||||||
amx_GetPublic(amx, func, name);
|
|
||||||
m_Name.assign(name);
|
|
||||||
m_ToDelete = false;
|
|
||||||
m_InExec = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
@ -237,9 +210,6 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
|
|||||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||||
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
||||||
isFree = false;
|
isFree = false;
|
||||||
m_Name.assign(funcName);
|
|
||||||
m_ToDelete = false;
|
|
||||||
m_InExec = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
@ -252,81 +222,69 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
cell realParams[FORWARD_MAX_PARAMS];
|
cell realParams[FORWARD_MAX_PARAMS];
|
||||||
cell *physAddrs[FORWARD_MAX_PARAMS];
|
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||||
|
|
||||||
if (!m_HasFunc || m_ToDelete)
|
if (!m_HasFunc)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
||||||
if (!pPlugin->isExecutable(m_Func))
|
if (!pPlugin->isExecutable(m_Func))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
m_InExec = true;
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]);
|
||||||
|
if (pInfo)
|
||||||
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
pInfo->error = AMX_ERR_NONE;
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->BeginExec();
|
|
||||||
|
|
||||||
// handle strings & arrays
|
// handle strings & arrays
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
{
|
{
|
||||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
const char *str = reinterpret_cast<const char*>(params[i]);
|
|
||||||
if (!str)
|
|
||||||
str = "";
|
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
amx_Allot(m_Amx,
|
||||||
amx_SetStringOld(tmp, str, 0, 0);
|
(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;
|
physAddrs[i] = tmp;
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
cell *tmp;
|
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;
|
physAddrs[i] = tmp;
|
||||||
|
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
realParams[i] = params[i];
|
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]);
|
amx_Push(m_Amx, realParams[i]);
|
||||||
|
|
||||||
// exec
|
// exec
|
||||||
cell retVal;
|
cell retVal;
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
|
|
||||||
#endif
|
|
||||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
//Did something else set an error?
|
//Did something else set an error?
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
//we don't care, something else logged the error.
|
//we don't care, something else logged the error.
|
||||||
}
|
} else {
|
||||||
else if (err != -1)
|
|
||||||
{
|
|
||||||
//nothing logged the error so spit it out anyway
|
//nothing logged the error so spit it out anyway
|
||||||
LogError(m_Amx, err, NULL);
|
LogError(m_Amx, err, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
amxx_InvalidateTrace(m_Amx);
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->EndExec();
|
|
||||||
|
|
||||||
m_Amx->error = AMX_ERR_NONE;
|
m_Amx->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
@ -351,9 +309,10 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
}
|
}
|
||||||
@ -362,23 +321,16 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_InExec = false;
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type)
|
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
||||||
{
|
{
|
||||||
int retVal = m_Forwards.size() << 1;
|
int retVal = m_Forwards.size() << 1;
|
||||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes, fwd_type);
|
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
||||||
|
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
|
||||||
return -1; // should be invalid
|
return -1; // should be invalid
|
||||||
}
|
|
||||||
|
|
||||||
m_Forwards.push_back(tmp);
|
m_Forwards.push_back(tmp);
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,26 +338,22 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
|
|||||||
{
|
{
|
||||||
int retVal = -1;
|
int retVal = -1;
|
||||||
CSPForward *pForward;
|
CSPForward *pForward;
|
||||||
|
|
||||||
if (!m_FreeSPForwards.empty())
|
if (!m_FreeSPForwards.empty())
|
||||||
{
|
{
|
||||||
retVal = m_FreeSPForwards.front();
|
retVal = m_FreeSPForwards.front();
|
||||||
pForward = m_SPForwards[retVal >> 1];
|
pForward = m_SPForwards[retVal >> 1];
|
||||||
pForward->Set(func, amx, numParams, paramTypes);
|
pForward->Set(func, amx, numParams, paramTypes);
|
||||||
|
|
||||||
if (pForward->getFuncsNum() == 0)
|
if (pForward->getFuncsNum() == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_FreeSPForwards.pop();
|
m_FreeSPForwards.pop();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
retVal = (m_SPForwards.size() << 1) | 1;
|
retVal = (m_SPForwards.size() << 1) | 1;
|
||||||
pForward = new CSPForward();
|
pForward = new CSPForward();
|
||||||
|
|
||||||
if (!pForward)
|
if (!pForward)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pForward->Set(func, amx, numParams, paramTypes);
|
pForward->Set(func, amx, numParams, paramTypes);
|
||||||
|
|
||||||
if (pForward->getFuncsNum() == 0)
|
if (pForward->getFuncsNum() == 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@ -414,7 +362,6 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
|
|||||||
|
|
||||||
m_SPForwards.push_back(pForward);
|
m_SPForwards.push_back(pForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,93 +369,56 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
|
|||||||
{
|
{
|
||||||
int retVal = (m_SPForwards.size() << 1) | 1;
|
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||||
CSPForward *pForward;
|
CSPForward *pForward;
|
||||||
|
|
||||||
if (!m_FreeSPForwards.empty())
|
if (!m_FreeSPForwards.empty())
|
||||||
{
|
{
|
||||||
retVal = m_FreeSPForwards.front();
|
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);
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||||
|
|
||||||
if (pForward->getFuncsNum() == 0)
|
if (pForward->getFuncsNum() == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
m_FreeSPForwards.pop();
|
m_FreeSPForwards.pop();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pForward = new CSPForward();
|
pForward = new CSPForward();
|
||||||
|
|
||||||
if (!pForward)
|
if (!pForward)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||||
|
|
||||||
if (pForward->getFuncsNum() == 0)
|
if (pForward->getFuncsNum() == 0)
|
||||||
{
|
{
|
||||||
delete pForward;
|
delete pForward;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_SPForwards.push_back(pForward);
|
m_SPForwards.push_back(pForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CForwardMngr::isIdValid(int id) const
|
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)
|
cell CForwardMngr::executeForwards(int id, cell *params)
|
||||||
{
|
{
|
||||||
int retVal;
|
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) :
|
||||||
if (id & 1)
|
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||||
{
|
|
||||||
CSPForward *fwd = m_SPForwards[id >> 1];
|
|
||||||
retVal = fwd->execute(params, m_TmpArrays);
|
|
||||||
if (fwd->m_ToDelete)
|
|
||||||
{
|
|
||||||
fwd->m_ToDelete = false;
|
|
||||||
unregisterSPForward(id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
retVal = m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CForwardMngr::getFuncName(int id) const
|
|
||||||
{
|
|
||||||
if (!isIdValid(id))
|
|
||||||
{
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CForwardMngr::getFuncsNum(int id) const
|
|
||||||
{
|
|
||||||
if (!isIdValid(id))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (id & 1) ? m_SPForwards[id >> 1]->getFuncsNum() : m_Forwards[id >> 1]->getFuncsNum();
|
|
||||||
}
|
|
||||||
|
|
||||||
int CForwardMngr::getParamsNum(int id) const
|
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
|
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
|
||||||
{
|
{
|
||||||
if (!isIdValid(id))
|
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) :
|
||||||
{
|
m_Forwards[id >> 1]->getParamType(paramNum);
|
||||||
return FP_DONE;
|
|
||||||
}
|
|
||||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CForwardMngr::clear()
|
void CForwardMngr::clear()
|
||||||
@ -517,9 +427,7 @@ void CForwardMngr::clear()
|
|||||||
{
|
{
|
||||||
delete *iter;
|
delete *iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPForwardVec::iterator spIter;
|
SPForwardVec::iterator spIter;
|
||||||
|
|
||||||
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
||||||
{
|
{
|
||||||
delete (*spIter);
|
delete (*spIter);
|
||||||
@ -527,10 +435,8 @@ void CForwardMngr::clear()
|
|||||||
|
|
||||||
m_Forwards.clear();
|
m_Forwards.clear();
|
||||||
m_SPForwards.clear();
|
m_SPForwards.clear();
|
||||||
|
|
||||||
while (!m_FreeSPForwards.empty())
|
while (!m_FreeSPForwards.empty())
|
||||||
m_FreeSPForwards.pop();
|
m_FreeSPForwards.pop();
|
||||||
|
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,126 +448,74 @@ bool CForwardMngr::isSPForward(int id) const
|
|||||||
void CForwardMngr::unregisterSPForward(int id)
|
void CForwardMngr::unregisterSPForward(int id)
|
||||||
{
|
{
|
||||||
//make sure the id is valid
|
//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;
|
return;
|
||||||
|
|
||||||
CSPForward *fwd = m_SPForwards.at(id >> 1);
|
m_SPForwards.at(id >> 1)->isFree = true;
|
||||||
|
|
||||||
if (fwd->m_InExec)
|
m_FreeSPForwards.push(id);
|
||||||
{
|
|
||||||
fwd->m_ToDelete = true;
|
|
||||||
} else {
|
|
||||||
fwd->isFree = true;
|
|
||||||
m_FreeSPForwards.push(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type)
|
|
||||||
{
|
|
||||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
||||||
|
|
||||||
for (size_t i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
params[i] = static_cast<ForwardParam>(list[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_forwards.registerForward(funcName, et, num, params, fwd_type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||||
{
|
{
|
||||||
int curParam = 0;
|
int curParam = 0;
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, et);
|
va_start(argptr, et);
|
||||||
|
|
||||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||||
ForwardParam tmp;
|
ForwardParam tmp;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (curParam == FORWARD_MAX_PARAMS)
|
if (curParam == FORWARD_MAX_PARAMS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tmp = (ForwardParam)va_arg(argptr, int);
|
tmp = (ForwardParam)va_arg(argptr, int);
|
||||||
|
|
||||||
if (tmp == FP_DONE)
|
if (tmp == FP_DONE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
params[curParam] = tmp;
|
params[curParam] = tmp;
|
||||||
++curParam;
|
++curParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return g_forwards.registerForward(funcName, et, curParam, params);
|
return g_forwards.registerForward(funcName, et, curParam, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
|
|
||||||
{
|
|
||||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
|
||||||
|
|
||||||
for (size_t i=0; i<num; i++)
|
|
||||||
params[i] = static_cast<ForwardParam>(list[i]);
|
|
||||||
|
|
||||||
return g_forwards.registerSPForward(funcName, amx, num, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
||||||
{
|
{
|
||||||
int curParam = 0;
|
int curParam = 0;
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, funcName);
|
va_start(argptr, funcName);
|
||||||
|
|
||||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||||
ForwardParam tmp;
|
ForwardParam tmp;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (curParam == FORWARD_MAX_PARAMS)
|
if (curParam == FORWARD_MAX_PARAMS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tmp = (ForwardParam)va_arg(argptr, int);
|
tmp = (ForwardParam)va_arg(argptr, int);
|
||||||
|
|
||||||
if (tmp == FP_DONE)
|
if (tmp == FP_DONE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
params[curParam] = tmp;
|
params[curParam] = tmp;
|
||||||
++curParam;
|
++curParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerSPForward(AMX *amx, int func, ...)
|
int registerSPForward(AMX *amx, int func, ...)
|
||||||
{
|
{
|
||||||
int curParam = 0;
|
int curParam = 0;
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, func);
|
va_start(argptr, func);
|
||||||
|
|
||||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||||
ForwardParam tmp;
|
ForwardParam tmp;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (curParam == FORWARD_MAX_PARAMS)
|
if (curParam == FORWARD_MAX_PARAMS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tmp = (ForwardParam)va_arg(argptr, int);
|
tmp = (ForwardParam)va_arg(argptr, int);
|
||||||
|
|
||||||
if (tmp == FP_DONE)
|
if (tmp == FP_DONE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
params[curParam] = tmp;
|
params[curParam] = tmp;
|
||||||
++curParam;
|
++curParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return g_forwards.registerSPForward(func, amx, curParam, params);
|
return g_forwards.registerSPForward(func, amx, curParam, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,12 +525,9 @@ cell executeForwards(int id, ...)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cell params[FORWARD_MAX_PARAMS];
|
cell params[FORWARD_MAX_PARAMS];
|
||||||
|
|
||||||
int paramsNum = g_forwards.getParamsNum(id);
|
int paramsNum = g_forwards.getParamsNum(id);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, id);
|
va_start(argptr, id);
|
||||||
|
|
||||||
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
||||||
{
|
{
|
||||||
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
||||||
@ -687,9 +538,7 @@ cell executeForwards(int id, ...)
|
|||||||
else
|
else
|
||||||
params[i] = (cell)va_arg(argptr, cell);
|
params[i] = (cell)va_arg(argptr, cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
return g_forwards.executeForwards(id, params);
|
return g_forwards.executeForwards(id, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,16 +546,13 @@ cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemTy
|
|||||||
{
|
{
|
||||||
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
||||||
{
|
{
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
m_validateAllAllocUnits();
|
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);
|
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
||||||
m_TmpArrays[m_TmpArraysNum].size = size;
|
m_TmpArrays[m_TmpArraysNum].size = size;
|
||||||
m_TmpArrays[m_TmpArraysNum].type = type;
|
m_TmpArrays[m_TmpArraysNum].type = type;
|
||||||
|
@ -46,15 +46,8 @@
|
|||||||
#ifndef FORWARD_H
|
#ifndef FORWARD_H
|
||||||
#define FORWARD_H
|
#define FORWARD_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "sh_stack.h"
|
|
||||||
|
|
||||||
const int FORWARD_MAX_PARAMS = 32;
|
const int FORWARD_MAX_PARAMS = 32;
|
||||||
|
|
||||||
#define FORWARD_ONLY_OLD 1
|
|
||||||
#define FORWARD_ONLY_NEW 2
|
|
||||||
#define FORWARD_ALL 3
|
|
||||||
|
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
{
|
{
|
||||||
ET_IGNORE = 0, // Ignore return vaue
|
ET_IGNORE = 0, // Ignore return vaue
|
||||||
@ -84,9 +77,7 @@ enum ForwardArrayElemType
|
|||||||
struct ForwardPreparedArray
|
struct ForwardPreparedArray
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
ForwardArrayElemType type;
|
ForwardArrayElemType type;
|
||||||
|
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
bool copyBack;
|
bool copyBack;
|
||||||
};
|
};
|
||||||
@ -97,45 +88,31 @@ class CForward
|
|||||||
const char *m_FuncName;
|
const char *m_FuncName;
|
||||||
ForwardExecType m_ExecType;
|
ForwardExecType m_ExecType;
|
||||||
int m_NumParams;
|
int m_NumParams;
|
||||||
String m_Name;
|
|
||||||
|
|
||||||
struct AMXForward
|
struct AMXForward
|
||||||
{
|
{
|
||||||
CPluginMngr::CPlugin *pPlugin;
|
CPluginMngr::CPlugin *pPlugin;
|
||||||
int func;
|
int func;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CVector<AMXForward> AMXForwardList;
|
typedef CVector<AMXForward> AMXForwardList;
|
||||||
|
|
||||||
AMXForwardList m_Funcs;
|
AMXForwardList m_Funcs;
|
||||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type=FORWARD_ALL);
|
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);
|
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||||
|
|
||||||
int getParamsNum() const
|
int getParamsNum() const
|
||||||
{
|
{
|
||||||
return m_NumParams;
|
return m_NumParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFuncsNum() const
|
int getFuncsNum() const
|
||||||
{
|
{
|
||||||
return m_Funcs.size();
|
return m_Funcs.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getFuncName() const
|
|
||||||
{
|
|
||||||
return m_Name.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
ForwardParam getParamType(int paramId) const
|
ForwardParam getParamType(int paramId) const
|
||||||
{
|
{
|
||||||
if (paramId < 0 || paramId >= m_NumParams)
|
if (paramId < 0 || paramId >= m_NumParams)
|
||||||
return FP_DONE;
|
return FP_DONE;
|
||||||
|
|
||||||
return m_ParamTypes[paramId];
|
return m_ParamTypes[paramId];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -143,19 +120,12 @@ public:
|
|||||||
// Single plugin forward
|
// Single plugin forward
|
||||||
class CSPForward
|
class CSPForward
|
||||||
{
|
{
|
||||||
friend class CForwardMngr;
|
|
||||||
const char *m_FuncName;
|
const char *m_FuncName;
|
||||||
int m_NumParams;
|
int m_NumParams;
|
||||||
|
|
||||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||||
AMX *m_Amx;
|
AMX *m_Amx;
|
||||||
|
|
||||||
int m_Func;
|
int m_Func;
|
||||||
bool m_HasFunc;
|
bool m_HasFunc;
|
||||||
String m_Name;
|
|
||||||
bool m_InExec;
|
|
||||||
bool m_ToDelete;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isFree;
|
bool isFree;
|
||||||
public:
|
public:
|
||||||
@ -164,27 +134,18 @@ public:
|
|||||||
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
|
||||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||||
|
|
||||||
int getParamsNum() const
|
int getParamsNum() const
|
||||||
{
|
{
|
||||||
return m_NumParams;
|
return m_NumParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFuncsNum() const
|
int getFuncsNum() const
|
||||||
{
|
{
|
||||||
return (m_HasFunc) ? 1 : 0;
|
return (m_HasFunc) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *getFuncName() const
|
|
||||||
{
|
|
||||||
return m_Name.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
ForwardParam getParamType(int paramId) const
|
ForwardParam getParamType(int paramId) const
|
||||||
{
|
{
|
||||||
if (paramId < 0 || paramId >= m_NumParams)
|
if (paramId < 0 || paramId >= m_NumParams)
|
||||||
return FP_DONE;
|
return FP_DONE;
|
||||||
|
|
||||||
return m_ParamTypes[paramId];
|
return m_ParamTypes[paramId];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -193,50 +154,45 @@ class CForwardMngr
|
|||||||
{
|
{
|
||||||
typedef CVector<CForward*> ForwardVec;
|
typedef CVector<CForward*> ForwardVec;
|
||||||
typedef CVector<CSPForward*> SPForwardVec;
|
typedef CVector<CSPForward*> SPForwardVec;
|
||||||
typedef CStack<int> FreeSPVec; // Free SP Forwards
|
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
||||||
|
|
||||||
ForwardVec m_Forwards;
|
ForwardVec m_Forwards;
|
||||||
|
|
||||||
SPForwardVec m_SPForwards;
|
SPForwardVec m_SPForwards;
|
||||||
FreeSPVec m_FreeSPForwards; // so we don't have to free memory
|
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;
|
int m_TmpArraysNum;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CForwardMngr()
|
CForwardMngr()
|
||||||
{ m_TmpArraysNum = 0; }
|
{ m_TmpArraysNum = 0; }
|
||||||
~CForwardMngr() {}
|
~CForwardMngr()
|
||||||
|
{ }
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
// Register normal forward
|
// Register normal forward
|
||||||
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type=FORWARD_ALL);
|
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
|
||||||
// Register single plugin forward
|
// Register single plugin forward
|
||||||
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
|
||||||
// Unregister single plugin forward
|
// Unregister single plugin forward
|
||||||
void unregisterSPForward(int id);
|
void unregisterSPForward(int id);
|
||||||
|
|
||||||
// execute forward
|
// execute forward
|
||||||
cell executeForwards(int id, cell *params);
|
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 isIdValid(int id) const; // check whether forward id is valid
|
||||||
bool isSPForward(int id) const; // check whether forward is single plugin
|
bool isSPForward(int id) const; // check whether forward is single plugin
|
||||||
int getParamsNum(int id) const; // get num of params of a forward
|
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
|
int getFuncsNum(int id) const; // get num of found functions of a forward
|
||||||
const char *getFuncName(int id) const; // get the function name
|
|
||||||
|
|
||||||
ForwardParam getParamType(int id, int paramId) const;
|
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
|
// (un)register forward
|
||||||
int registerForward(const char *funcName, ForwardExecType et, ...);
|
int registerForward(const char *funcName, ForwardExecType et, ...);
|
||||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type=FORWARD_ALL);
|
|
||||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
|
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
|
||||||
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num);
|
|
||||||
int registerSPForward(AMX *amx, int func, ...);
|
int registerSPForward(AMX *amx, int func, ...);
|
||||||
void unregisterSPForward(int id);
|
void unregisterSPForward(int id);
|
||||||
|
|
||||||
@ -246,4 +202,5 @@ cell executeForwards(int id, ...);
|
|||||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
|
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
|
||||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
|
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
|
||||||
|
|
||||||
#endif //FORWARD_H
|
#endif
|
||||||
|
|
||||||
|
1238
amxmodx/CLang.cpp
1238
amxmodx/CLang.cpp
File diff suppressed because it is too large
Load Diff
140
amxmodx/CLang.h
140
amxmodx/CLang.h
@ -32,56 +32,27 @@
|
|||||||
#ifndef _INCLUDE_CLANG_H
|
#ifndef _INCLUDE_CLANG_H
|
||||||
#define _INCLUDE_CLANG_H
|
#define _INCLUDE_CLANG_H
|
||||||
|
|
||||||
#include "sh_tinyhash.h"
|
|
||||||
|
|
||||||
#define LANG_SERVER 0
|
#define LANG_SERVER 0
|
||||||
#define LANG_PLAYER -1
|
#define LANG_PLAYER -1
|
||||||
|
|
||||||
#define ERR_BADKEY 1 // Lang key not found
|
|
||||||
#define ERR_BADLANG 2 // Invalid lang
|
|
||||||
|
|
||||||
struct md5Pair
|
struct md5Pair
|
||||||
{
|
{
|
||||||
String file;
|
String file;
|
||||||
String val;
|
String val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct keyEntry
|
||||||
|
{
|
||||||
|
String key;
|
||||||
|
uint32_t hash;
|
||||||
|
};
|
||||||
|
|
||||||
struct sKeyDef
|
struct sKeyDef
|
||||||
{
|
{
|
||||||
String *definition;
|
sKeyDef() { key = -1; def = 0; }
|
||||||
|
~sKeyDef() { if (def) delete def; }
|
||||||
int key;
|
int key;
|
||||||
};
|
String *def;
|
||||||
|
|
||||||
struct lang_err
|
|
||||||
{
|
|
||||||
lang_err() : last(0.0f)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
float last;
|
|
||||||
};
|
|
||||||
|
|
||||||
class defentry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
defentry() : definition(NULL)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
defentry(const defentry &src)
|
|
||||||
{
|
|
||||||
definition = src.definition;
|
|
||||||
}
|
|
||||||
~defentry()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
String *definition;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct keytbl_val
|
|
||||||
{
|
|
||||||
keytbl_val() : index(-1)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
int index;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CLangMngr
|
class CLangMngr
|
||||||
@ -97,43 +68,84 @@ class CLangMngr
|
|||||||
~CLang();
|
~CLang();
|
||||||
|
|
||||||
// Get the definition
|
// Get the definition
|
||||||
const char *GetDef(int key, int &status);
|
const char *GetDef(const char *key);
|
||||||
// Add definitions to this language
|
// Add definitions to this language
|
||||||
void MergeDefinitions(CQueue <sKeyDef> & vec);
|
void MergeDefinitions(CQueue <sKeyDef*> & vec);
|
||||||
// Reset this language
|
// Reset this language
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
// compare this language to a language name
|
// compare this language to a language name
|
||||||
friend bool operator == (const CLang &left, const char *right)
|
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
|
// Get language name
|
||||||
const char *GetName() { return m_LanguageName; }
|
const char *GetName() { return m_LanguageName; }
|
||||||
|
// Save to file
|
||||||
|
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
|
||||||
|
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
|
||||||
|
// Load
|
||||||
|
bool Load(FILE *fp);
|
||||||
void SetMngr(CLangMngr *l) { m_LMan = l; }
|
void SetMngr(CLangMngr *l) { m_LMan = l; }
|
||||||
// Get number of entries
|
// Get number of entries
|
||||||
int Entries();
|
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:
|
||||||
typedef THash<int, defentry> LookUpVec;
|
|
||||||
typedef LookUpVec::iterator LookUpVecIter;
|
// An entry in the language
|
||||||
|
class LangEntry
|
||||||
|
{
|
||||||
|
// the definition hash
|
||||||
|
uint32_t m_DefHash;
|
||||||
|
// index into the lookup table?
|
||||||
|
int key;
|
||||||
|
// the definition
|
||||||
|
String m_pDef;
|
||||||
|
// is this from the cache or not?
|
||||||
|
bool m_isCache;
|
||||||
|
public:
|
||||||
|
// Set
|
||||||
|
void SetKey(int key);
|
||||||
|
void SetDef(const char *pDef);
|
||||||
|
void SetCache(bool c);
|
||||||
|
// Get
|
||||||
|
uint32_t GetDefHash();
|
||||||
|
int GetKey();
|
||||||
|
const char *GetDef();
|
||||||
|
int GetDefLength();
|
||||||
|
bool GetCache();
|
||||||
|
|
||||||
|
// Constructors / destructors
|
||||||
|
LangEntry();
|
||||||
|
LangEntry(int key);
|
||||||
|
LangEntry(int key, const char *pDef);
|
||||||
|
LangEntry(const LangEntry &other);
|
||||||
|
LangEntry(int pKey, uint32_t defHash, const char *pDef);
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
void Clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get (construct if needed) an entry
|
||||||
|
LangEntry * GetEntry(int key);
|
||||||
|
|
||||||
|
typedef CVector<LangEntry*> LookUpVec;
|
||||||
|
typedef LookUpVec::iterator LookUpVecIter;
|
||||||
|
|
||||||
char m_LanguageName[3];
|
char m_LanguageName[3];
|
||||||
|
|
||||||
// our lookup table
|
// our lookup table
|
||||||
LookUpVec m_LookUpTable;
|
LookUpVec m_LookUpTable;
|
||||||
int m_entries;
|
|
||||||
CLangMngr *m_LMan;
|
CLangMngr *m_LMan;
|
||||||
public:
|
public:
|
||||||
void AddEntry(int key, const char *definition);
|
LangEntry *AddEntry(int pKey, uint32_t defHash, const char *def, bool cache);
|
||||||
};
|
};
|
||||||
public:
|
|
||||||
// Merge definitions into a language
|
|
||||||
void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
|
|
||||||
|
|
||||||
private:
|
// Merge definitions into a language
|
||||||
|
void MergeDefinitions(const char *lang, CQueue <sKeyDef*> &tmpVec);
|
||||||
// strip lowercase; make lower if needed
|
// 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*> LangVec;
|
||||||
typedef CVector<CLang*>::iterator LangVecIter;
|
typedef CVector<CLang*>::iterator LangVecIter;
|
||||||
@ -141,8 +153,7 @@ private:
|
|||||||
LangVec m_Languages;
|
LangVec m_Languages;
|
||||||
|
|
||||||
CVector<md5Pair *> FileList;
|
CVector<md5Pair *> FileList;
|
||||||
CVector<String *> KeyList;
|
CVector<keyEntry*> KeyList;
|
||||||
THash<String, keytbl_val> KeyTable;
|
|
||||||
|
|
||||||
// Get a lang object (construct if needed)
|
// Get a lang object (construct if needed)
|
||||||
CLang * GetLang(const char *name);
|
CLang * GetLang(const char *name);
|
||||||
@ -154,19 +165,30 @@ private:
|
|||||||
public:
|
public:
|
||||||
// Merge a definitions file
|
// Merge a definitions file
|
||||||
int MergeDefinitionFile(const char *file);
|
int MergeDefinitionFile(const char *file);
|
||||||
// Get a definition from a lang name and a key
|
// Get a definition from a lang name and a kyer
|
||||||
const char *GetDef(const char *langName, const char *key, int &status);
|
const char *GetDef(const char *langName, const char *key);
|
||||||
|
// Format a string
|
||||||
|
const char *Format(const char *src, ...);
|
||||||
// Format a string for an AMX plugin
|
// Format a string for an AMX plugin
|
||||||
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
|
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
|
||||||
void InvalidateCache();
|
char *FormatString(const char *fmt, va_list &ap);
|
||||||
|
// Save
|
||||||
|
bool Save(const char *filename);
|
||||||
|
// Load
|
||||||
|
bool Load(const char *filename);
|
||||||
|
// Cache
|
||||||
|
bool LoadCache(const char *filename);
|
||||||
|
bool SaveCache(const char *filename);
|
||||||
// Get index
|
// Get index
|
||||||
int GetKeyEntry(String &key);
|
int GetKeyEntry(String &key);
|
||||||
int GetKeyEntry(const char *key);
|
int GetKeyEntry(const char *key);
|
||||||
|
int GetKeyHash(int key);
|
||||||
// Get key from index
|
// Get key from index
|
||||||
const char *GetKey(int key);
|
const char *GetKey(int key);
|
||||||
// Add key
|
// Add key
|
||||||
int AddKeyEntry(String &key);
|
int AddKeyEntry(String &key);
|
||||||
int AddKeyEntry(const char *key);
|
// Make a hash from a string; convert to lowercase first if needed
|
||||||
|
uint32_t MakeHash(const char *src, bool makeLower);
|
||||||
|
|
||||||
// Get the number of languages
|
// Get the number of languages
|
||||||
int GetLangsNum();
|
int GetLangsNum();
|
||||||
@ -178,8 +200,6 @@ public:
|
|||||||
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
|
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
|
||||||
void SetDefLang(int id);
|
void SetDefLang(int id);
|
||||||
|
|
||||||
inline int GetDefLang() const { return m_CurGlobId; }
|
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CList
|
// class CList
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
// Linked list
|
// Linked list
|
||||||
template <typename T, typename F = char* >
|
template <typename T, typename F = char* >
|
||||||
class CList
|
class CList
|
||||||
@ -66,10 +65,8 @@ private:
|
|||||||
~CElement()
|
~CElement()
|
||||||
{
|
{
|
||||||
delete m_pObject;
|
delete m_pObject;
|
||||||
|
|
||||||
if (m_pNext)
|
if (m_pNext)
|
||||||
m_pNext->m_pPrev = m_pPrev;
|
m_pNext->m_pPrev = m_pPrev;
|
||||||
|
|
||||||
if (m_pPrev)
|
if (m_pPrev)
|
||||||
m_pPrev->m_pNext = m_pNext;
|
m_pPrev->m_pNext = m_pNext;
|
||||||
}
|
}
|
||||||
@ -105,16 +102,15 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// CList<T, F> class
|
// CList<T,F> class
|
||||||
CElement *m_pHead; // head of the linked list
|
CElement *m_pHead; // head of the linked list
|
||||||
CElement *m_pTail; // tail of the linked list
|
CElement *m_pTail; // tail of the linked list
|
||||||
public:
|
public:
|
||||||
// iterator class
|
// iterator class
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
friend class CList<T, F>;
|
friend class CList<T,F>;
|
||||||
|
CList<T,F> *m_pList; // The list that created this iterator
|
||||||
CList<T, F> *m_pList; // The list that created this iterator
|
|
||||||
CElement *m_CurPos; // Current position in the list
|
CElement *m_CurPos; // Current position in the list
|
||||||
public:
|
public:
|
||||||
iterator()
|
iterator()
|
||||||
@ -124,7 +120,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// constructor based on list, element
|
// constructor based on list, element
|
||||||
iterator(CList<T, F> *pList, CElement *startPos)
|
iterator(CList<T,F> *pList, CElement *startPos)
|
||||||
{
|
{
|
||||||
m_pList = pList;
|
m_pList = pList;
|
||||||
m_CurPos = startPos;
|
m_CurPos = startPos;
|
||||||
@ -151,7 +147,7 @@ public:
|
|||||||
// validity check operator
|
// validity check operator
|
||||||
inline operator bool () const
|
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
|
// pre increment operator
|
||||||
@ -166,7 +162,6 @@ public:
|
|||||||
{
|
{
|
||||||
iterator tmp(*this);
|
iterator tmp(*this);
|
||||||
m_CurPos = m_CurPos->next;
|
m_CurPos = m_CurPos->next;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,20 +176,18 @@ public:
|
|||||||
{
|
{
|
||||||
return m_pList->remove(*this);
|
return m_pList->remove(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator put(T *obj)
|
iterator put(T *obj)
|
||||||
{
|
{
|
||||||
return m_pList->put(obj, *this);
|
return m_pList->put(obj, *this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CList<T, F>()
|
CList<T,F>()
|
||||||
{
|
{
|
||||||
m_pHead = NULL;
|
m_pHead = NULL;
|
||||||
m_pTail = NULL;
|
m_pTail = NULL;
|
||||||
}
|
}
|
||||||
|
~CList<T,F>()
|
||||||
~CList<T, F>()
|
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
@ -205,16 +198,12 @@ public:
|
|||||||
iterator remove(iterator &where)
|
iterator remove(iterator &where)
|
||||||
{
|
{
|
||||||
iterator tmp(where.GetNext());
|
iterator tmp(where.GetNext());
|
||||||
|
|
||||||
if (where.m_CurPos == m_pHead)
|
if (where.m_CurPos == m_pHead)
|
||||||
m_pHead = where.m_CurPos->GetNext();
|
m_pHead = where.m_CurPos->GetNext();
|
||||||
|
|
||||||
if (where.m_CurPos == m_pTail)
|
if (where.m_CurPos == m_pTail)
|
||||||
m_pTail = where.m_CurPos->GetPrev();
|
m_pTail = where.m_CurPos->GetPrev();
|
||||||
|
|
||||||
delete where.m_CurPos;
|
delete where.m_CurPos;
|
||||||
where = tmp;
|
where = tmp;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,36 +212,36 @@ public:
|
|||||||
iterator put_back(T *pObj)
|
iterator put_back(T *pObj)
|
||||||
{
|
{
|
||||||
CElement *pTmp = new CElement(pObj);
|
CElement *pTmp = new CElement(pObj);
|
||||||
|
|
||||||
if (!m_pHead)
|
if (!m_pHead)
|
||||||
{
|
{
|
||||||
m_pHead = pTmp;
|
m_pHead = pTmp;
|
||||||
m_pTail = pTmp;
|
m_pTail = pTmp;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pTmp->SetNext(NULL);
|
pTmp->SetNext(NULL);
|
||||||
pTmp->SetPrev(m_pTail);
|
pTmp->SetPrev(m_pTail);
|
||||||
m_pTail->SetNext(pTmp);
|
m_pTail->SetNext(pTmp);
|
||||||
m_pTail = pTmp;
|
m_pTail = pTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterator(this, pTmp);
|
return iterator(this, pTmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator put_front(T *pObj)
|
iterator put_front(T *pObj)
|
||||||
{
|
{
|
||||||
CElement *pTmp = new CElement(pObj);
|
CElement *pTmp = new CElement(pObj);
|
||||||
|
|
||||||
if (!m_pHead)
|
if (!m_pHead)
|
||||||
{
|
{
|
||||||
m_pHead = pTmp;
|
m_pHead = pTmp;
|
||||||
m_pTail = pTmp;
|
m_pTail = pTmp;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pTmp->SetNext(m_pHead);
|
pTmp->SetNext(m_pHead);
|
||||||
pTmp->SetPrev(NULL);
|
pTmp->SetPrev(NULL);
|
||||||
m_pHead->SetPrev(pTmp);
|
m_pHead->SetPrev(pTmp);
|
||||||
m_pHead = pTmp;
|
m_pHead = pTmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iterator(this, pTmp);
|
return iterator(this, pTmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +257,6 @@ public:
|
|||||||
iterator put(T *pObj, iterator &where)
|
iterator put(T *pObj, iterator &where)
|
||||||
{
|
{
|
||||||
CElement *pTmp = new CElement(pObj);
|
CElement *pTmp = new CElement(pObj);
|
||||||
|
|
||||||
if (where.m_CurPos->GetNext())
|
if (where.m_CurPos->GetNext())
|
||||||
where.m_CurPos->GetNext()->SetPrev(pTmp);
|
where.m_CurPos->GetNext()->SetPrev(pTmp);
|
||||||
else // where = tail
|
else // where = tail
|
||||||
@ -278,7 +266,6 @@ public:
|
|||||||
pTmp->SetNext(where.m_CurPos->GetNext());
|
pTmp->SetNext(where.m_CurPos->GetNext());
|
||||||
|
|
||||||
where.m_CurPos->SetNext(pTmp);
|
where.m_CurPos->SetNext(pTmp);
|
||||||
|
|
||||||
return ++where;
|
return ++where;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,13 +283,12 @@ public:
|
|||||||
iterator find(iterator startOn, const F &desc)
|
iterator find(iterator startOn, const F &desc)
|
||||||
{
|
{
|
||||||
iterator iter = startOn;
|
iterator iter = startOn;
|
||||||
while (iter)
|
while(iter)
|
||||||
{
|
{
|
||||||
if (*iter == desc)
|
if (*iter == desc)
|
||||||
break;
|
break;
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,16 +300,14 @@ public:
|
|||||||
int size()
|
int size()
|
||||||
{
|
{
|
||||||
iterator iter = begin();
|
iterator iter = begin();
|
||||||
int i = 0;
|
int i=0;
|
||||||
|
|
||||||
while (iter)
|
while (iter)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //CLIST_H
|
|
||||||
|
@ -35,192 +35,135 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class LogEventsMngr
|
// class LogEventsMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
LogEventsMngr::LogEventsMngr() {
|
||||||
LogEventsMngr::LogEventsMngr()
|
logCurrent = logCounter = 0;
|
||||||
{
|
logcmplist = 0;
|
||||||
logCurrent = logCounter = 0;
|
arelogevents = false;
|
||||||
logcmplist = 0;
|
memset( logevents, 0, sizeof(logevents) );
|
||||||
arelogevents = false;
|
|
||||||
memset(logevents, 0, sizeof(logevents));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::~LogEventsMngr()
|
LogEventsMngr::~LogEventsMngr() {
|
||||||
{
|
clearLogEvents();
|
||||||
clearLogEvents();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LogEventsMngr::CLogCmp::compareCondition(const char* string)
|
int LogEventsMngr::CLogCmp::compareCondition(const char* string){
|
||||||
{
|
if ( logid == parent->logCounter )
|
||||||
if (logid == parent->logCounter)
|
return result;
|
||||||
return result;
|
logid = parent->logCounter;
|
||||||
|
if ( in ) return result = strstr( string , text.c_str() ) ? 0 : 1;
|
||||||
logid = parent->logCounter;
|
return result = strcmp(string,text.c_str());
|
||||||
|
|
||||||
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;
|
char* temp = filter;
|
||||||
// expand "1=message"
|
// expand "1=message"
|
||||||
|
while ( isdigit(*filter) )
|
||||||
while (isdigit(*filter))
|
|
||||||
++filter;
|
++filter;
|
||||||
|
bool in = (*filter=='&');
|
||||||
bool in = (*filter=='&');
|
*filter++ = 0;
|
||||||
*filter++ = 0;
|
int pos = atoi(temp);
|
||||||
int pos = atoi(temp);
|
if ( pos < 0 || pos >= MAX_LOGARGS) pos = 0;
|
||||||
|
|
||||||
if (pos < 0 || pos >= MAX_LOGARGS)
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
CLogCmp* c = logcmplist;
|
CLogCmp* c = logcmplist;
|
||||||
|
while( c ) {
|
||||||
while (c)
|
if ( (c->pos==pos) && (c->in==in) && !strcmp(c->text.c_str(), filter))
|
||||||
{
|
|
||||||
if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.c_str(), filter))
|
|
||||||
return c;
|
return c;
|
||||||
c = c->next;
|
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)
|
void LogEventsMngr::CLogEvent::registerFilter( char* filter ){
|
||||||
{
|
CLogCmp *cmp = parent->registerCondition( filter );
|
||||||
CLogCmp *cmp = parent->registerCondition(filter);
|
if ( cmp == 0 ) return;
|
||||||
if (cmp == 0) return;
|
for(LogCond* c = filters; c ; c = c->next){
|
||||||
|
if ( c->argnum == cmp->pos ){
|
||||||
for (LogCond* c = filters; c; c = c->next)
|
c->list = new LogCondEle( cmp , c->list );
|
||||||
{
|
|
||||||
if (c->argnum == cmp->pos)
|
|
||||||
{
|
|
||||||
c->list = new LogCondEle(cmp, c->list);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LogCondEle* aa = new LogCondEle( cmp , 0 );
|
||||||
LogCondEle* aa = new LogCondEle(cmp, 0);
|
if ( aa == 0 ) return;
|
||||||
|
filters = new LogCond( cmp->pos , aa , filters );
|
||||||
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;
|
++logCounter;
|
||||||
int len = vsnprintf(logString, 255, frmt, vaptr);
|
int len = vsnprintf (logString, 255 , frmt, vaptr );
|
||||||
|
if ( len == - 1) {
|
||||||
if (len == - 1)
|
|
||||||
{
|
|
||||||
len = 255;
|
len = 255;
|
||||||
logString[len] = 0;
|
logString[len] = 0;
|
||||||
}
|
}
|
||||||
|
if ( len ) logString[--len] = 0;
|
||||||
if (len)
|
|
||||||
logString[--len] = 0;
|
|
||||||
|
|
||||||
logArgc = 0;
|
logArgc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::setLogString(char* frmt, ...)
|
void LogEventsMngr::setLogString( char* frmt, ... ) {
|
||||||
{
|
|
||||||
++logCounter;
|
++logCounter;
|
||||||
va_list logArgPtr;
|
va_list logArgPtr;
|
||||||
va_start(logArgPtr, frmt);
|
va_start ( logArgPtr , frmt );
|
||||||
int len = vsnprintf(logString, 255, frmt, logArgPtr);
|
int len = vsnprintf(logString, 255 , frmt, logArgPtr );
|
||||||
|
if ( len == - 1) {
|
||||||
if (len == - 1)
|
|
||||||
{
|
|
||||||
len = 255;
|
len = 255;
|
||||||
logString[len] = 0;
|
logString[len] = 0;
|
||||||
}
|
}
|
||||||
|
va_end ( logArgPtr );
|
||||||
va_end(logArgPtr);
|
if ( len ) logString[--len] = 0;
|
||||||
|
|
||||||
if (len)
|
|
||||||
logString[--len] = 0;
|
|
||||||
|
|
||||||
logArgc = 0;
|
logArgc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::parseLogString()
|
void LogEventsMngr::parseLogString( ) {
|
||||||
{
|
register const char* b = logString;
|
||||||
register const char* b = logString;
|
register int a;
|
||||||
register int a;
|
while( *b && logArgc < MAX_LOGARGS ){
|
||||||
|
a = 0;
|
||||||
while (*b && logArgc < MAX_LOGARGS)
|
if ( *b == '"' ) {
|
||||||
{
|
++b;
|
||||||
a = 0;
|
while ( *b && *b != '"' && a < 127 )
|
||||||
|
logArgs[logArgc][a++] = *b++;
|
||||||
if (*b == '"')
|
logArgs[logArgc++][a] = 0;
|
||||||
{
|
if ( *b) b+=2; // thanks to double terminator
|
||||||
++b;
|
}
|
||||||
|
else if ( *b == '(' ) {
|
||||||
while (*b && *b != '"' && a < 127)
|
++b;
|
||||||
logArgs[logArgc][a++] = *b++;
|
while ( *b && *b != ')' && a < 127 )
|
||||||
|
logArgs[logArgc][a++] = *b++;
|
||||||
logArgs[logArgc++][a] = 0;
|
logArgs[logArgc++][a] = 0;
|
||||||
if (*b) b+=2; // thanks to double terminator
|
if ( *b) b+=2;
|
||||||
}
|
}
|
||||||
else if (*b == '(')
|
else {
|
||||||
{
|
while ( *b && *b != '(' && *b != '"' && a < 127 )
|
||||||
++b;
|
logArgs[logArgc][a++] = *b++;
|
||||||
|
if ( *b ) --a;
|
||||||
while (*b && *b != ')' && a < 127)
|
logArgs[logArgc++][a] = 0;
|
||||||
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)
|
if ( pos < 1 || pos > MAX_LOGARGS)
|
||||||
return 0;
|
return 0;
|
||||||
|
arelogevents = true;
|
||||||
arelogevents = true;
|
CLogEvent** d = &logevents[pos];
|
||||||
CLogEvent** d = &logevents[pos];
|
while(*d) d = &(*d)->next;
|
||||||
|
return *d = new CLogEvent( plugin , func, this );
|
||||||
while (*d)
|
|
||||||
d = &(*d)->next;
|
|
||||||
|
|
||||||
return *d = new CLogEvent(plugin, func, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::executeLogEvents()
|
void LogEventsMngr::executeLogEvents()
|
||||||
{
|
{
|
||||||
bool valid;
|
bool valid;
|
||||||
|
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
|
||||||
for (CLogEvent* a = logevents[logArgc]; a; a = a->next)
|
|
||||||
{
|
{
|
||||||
valid = true;
|
valid = true;
|
||||||
|
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next)
|
||||||
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
|
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
|
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||||
{
|
|
||||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
|
||||||
{
|
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -229,90 +172,67 @@ void LogEventsMngr::executeLogEvents()
|
|||||||
{
|
{
|
||||||
executeForwards(a->func);
|
executeForwards(a->func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::clearLogEvents()
|
void LogEventsMngr::clearLogEvents(){
|
||||||
{
|
logCurrent = logCounter = 0;
|
||||||
logCurrent = logCounter = 0;
|
arelogevents = false;
|
||||||
arelogevents = false;
|
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
|
||||||
|
CLogEvent **a = &logevents[i];
|
||||||
for (int i = 0; i < MAX_LOGARGS + 1; ++i)
|
while(*a){
|
||||||
{
|
CLogEvent* bb = (*a)->next;
|
||||||
CLogEvent **a = &logevents[i];
|
delete *a;
|
||||||
while (*a)
|
*a = bb;
|
||||||
{
|
}
|
||||||
CLogEvent* bb = (*a)->next;
|
}
|
||||||
delete *a;
|
clearConditions();
|
||||||
*a = bb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clearConditions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::clearConditions()
|
void LogEventsMngr::clearConditions() {
|
||||||
{
|
while (logcmplist){
|
||||||
while (logcmplist)
|
CLogCmp* a = logcmplist->next;
|
||||||
{
|
delete logcmplist;
|
||||||
CLogCmp* a = logcmplist->next;
|
logcmplist = a;
|
||||||
delete logcmplist;
|
}
|
||||||
logcmplist = a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent::LogCond::~LogCond()
|
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
|
||||||
{
|
while( list ) {
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
LogCondEle* cc = list->next;
|
LogCondEle* cc = list->next;
|
||||||
delete list;
|
delete list;
|
||||||
list = cc;
|
list = cc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent::~CLogEvent()
|
LogEventsMngr::CLogEvent::~CLogEvent() {
|
||||||
{
|
while( filters ) {
|
||||||
while (filters)
|
|
||||||
{
|
|
||||||
LogCond* cc = filters->next;
|
LogCond* cc = filters->next;
|
||||||
delete filters;
|
delete filters;
|
||||||
filters = cc;
|
filters = cc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent(CLogEvent * a)
|
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent( CLogEvent * a )
|
||||||
{
|
{
|
||||||
bool valid;
|
bool valid;
|
||||||
|
while(a){
|
||||||
while (a)
|
|
||||||
{
|
|
||||||
valid = true;
|
valid = true;
|
||||||
|
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||||
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
|
|
||||||
{
|
|
||||||
valid = false;
|
valid = false;
|
||||||
|
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||||
{
|
|
||||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
|
||||||
{
|
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) break;
|
if (!valid) break;
|
||||||
}
|
}
|
||||||
|
if (!valid){
|
||||||
if (!valid)
|
|
||||||
{
|
|
||||||
a = a->next;
|
a = a->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -40,139 +40,126 @@
|
|||||||
// class LogEventsMngr
|
// class LogEventsMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
class LogEventsMngr
|
class LogEventsMngr {
|
||||||
{
|
|
||||||
char logString[256];
|
char logString[256];
|
||||||
char logArgs[MAX_LOGARGS][128];
|
char logArgs[MAX_LOGARGS][128];
|
||||||
int logArgc;
|
int logArgc;
|
||||||
int logCounter;
|
int logCounter;
|
||||||
int logCurrent;
|
int logCurrent;
|
||||||
bool arelogevents;
|
bool arelogevents;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class CLogCmp;
|
class CLogCmp;
|
||||||
class iterator;
|
class iterator;
|
||||||
class CLogEvent;
|
class CLogEvent;
|
||||||
|
|
||||||
|
friend class CLogEvent;
|
||||||
|
friend class CLogCmp;
|
||||||
|
friend class iterator;
|
||||||
|
|
||||||
|
class CLogCmp
|
||||||
|
{
|
||||||
|
friend class LogEventsMngr;
|
||||||
friend class CLogEvent;
|
friend class CLogEvent;
|
||||||
friend class CLogCmp;
|
LogEventsMngr* parent;
|
||||||
|
String text;
|
||||||
|
int logid;
|
||||||
|
int pos;
|
||||||
|
int result;
|
||||||
|
bool in;
|
||||||
|
CLogCmp *next;
|
||||||
|
CLogCmp( const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg ) : text(s) {
|
||||||
|
logid = result = 0;
|
||||||
|
pos = p;
|
||||||
|
parent = mg;
|
||||||
|
in = r;
|
||||||
|
next = n;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
int compareCondition(const char* string);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CLogCmp *logcmplist;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
class CLogEvent {
|
||||||
|
friend class LogEventsMngr;
|
||||||
friend class iterator;
|
friend class iterator;
|
||||||
|
struct LogCondEle {
|
||||||
class CLogCmp
|
CLogCmp *cmp;
|
||||||
{
|
LogCondEle *next;
|
||||||
friend class LogEventsMngr;
|
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
|
||||||
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:
|
private:
|
||||||
CLogCmp *logcmplist;
|
|
||||||
|
CLogEvent *logevents[MAX_LOGARGS+1];
|
||||||
|
CLogEvent *getValidLogEvent( CLogEvent * a );
|
||||||
|
CLogCmp* registerCondition(char* filter);
|
||||||
|
void clearConditions();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class CLogEvent
|
LogEventsMngr();
|
||||||
{
|
~LogEventsMngr();
|
||||||
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
|
// Interface
|
||||||
CLogEvent* registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos);
|
|
||||||
inline bool logEventsExist() { return arelogevents; }
|
|
||||||
|
|
||||||
void setLogString(char* frmt, va_list& vaptr);
|
|
||||||
void setLogString(char* frmt, ...);
|
|
||||||
void parseLogString();
|
|
||||||
void executeLogEvents();
|
|
||||||
|
|
||||||
inline const char* getLogString() { return logString; }
|
|
||||||
inline int getLogArgNum() { return logArgc; }
|
|
||||||
inline const char* getLogArg(int i) { return (i < 0 || i >= logArgc) ? "" : logArgs[i]; }
|
|
||||||
void clearLogEvents();
|
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
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; }
|
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
|
||||||
inline bool operator!=(const iterator& c) const { return !operator == (c); }
|
inline bool logEventsExist() { return arelogevents; }
|
||||||
CLogEvent& operator*() { return *a; }
|
void setLogString( char* frmt, va_list& vaptr );
|
||||||
operator bool () const { return a ? true : false; }
|
void setLogString( char* frmt , ... );
|
||||||
};
|
void parseLogString( );
|
||||||
|
void executeLogEvents();
|
||||||
inline iterator begin() { return iterator(getValidLogEvent(logevents[logArgc]), this); }
|
inline const char* getLogString() { return logString; }
|
||||||
inline iterator end() { return iterator(0, this); }
|
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;
|
||||||
|
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 //LOGEVENTS_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,8 +35,7 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class MenuMngr
|
// 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;
|
plugin = a;
|
||||||
keys = k;
|
keys = k;
|
||||||
menuid = mi;
|
menuid = mi;
|
||||||
@ -47,110 +46,49 @@ MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f
|
|||||||
MenuMngr::~MenuMngr()
|
MenuMngr::~MenuMngr()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
MenuMngr::MenuIdEle::uniqueid = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||||
{
|
{
|
||||||
for (MenuIdEle* b = headid; b; b = b->next)
|
for( MenuIdEle* b = headid; b ; b = b->next) {
|
||||||
{
|
if ( (!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
|
||||||
if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
|
return b->id;
|
||||||
return b->id;
|
}
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuMngr::removeMenuId(int id)
|
int MenuMngr::registerMenuId(const char* n, AMX* a )
|
||||||
{
|
{
|
||||||
MenuIdEle *n = headid;
|
int id = findMenuId( n, a );
|
||||||
MenuIdEle *l = NULL;
|
if (id) return id;
|
||||||
while (n)
|
headid = new MenuIdEle( n, a , headid );
|
||||||
{
|
if (!headid)
|
||||||
if (n->id == id)
|
return 0; // :TODO: Better error report
|
||||||
{
|
return headid->id;
|
||||||
if (l)
|
|
||||||
l->next = n->next;
|
|
||||||
else
|
|
||||||
headid = n->next;
|
|
||||||
delete n;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
l = n;
|
|
||||||
n = n->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuCommand *c = headcmd;
|
|
||||||
MenuCommand *lc = NULL;
|
|
||||||
MenuCommand *tmp;
|
|
||||||
while (c)
|
|
||||||
{
|
|
||||||
if (c->menuid == id)
|
|
||||||
{
|
|
||||||
if (m_watch_iter.a == c)
|
|
||||||
{
|
|
||||||
++m_watch_iter;
|
|
||||||
}
|
|
||||||
if (lc)
|
|
||||||
lc->next = c->next;
|
|
||||||
else
|
|
||||||
headcmd = c->next;
|
|
||||||
tmp = c->next;
|
|
||||||
delete c;
|
|
||||||
c = tmp;
|
|
||||||
} else {
|
|
||||||
lc = c;
|
|
||||||
c = c->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MenuMngr::registerMenuId(const char* n, AMX* a)
|
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
MenuCommand** temp = &headcmd;
|
MenuCommand** temp = &headcmd;
|
||||||
while (*temp) temp = &(*temp)->next;
|
while(*temp) temp = &(*temp)->next;
|
||||||
*temp = new MenuCommand(a, mi, k, f);
|
*temp = new MenuCommand(a,mi, k,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuMngr::clear()
|
void MenuMngr::clear()
|
||||||
{
|
{
|
||||||
while (headid)
|
while (headid)
|
||||||
{
|
{
|
||||||
MenuIdEle* a = headid->next;
|
MenuIdEle* a = headid->next;
|
||||||
delete headid;
|
delete headid;
|
||||||
headid = a;
|
headid = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (headcmd)
|
while (headcmd)
|
||||||
{
|
{
|
||||||
MenuCommand* a = headcmd->next;
|
MenuCommand* a = headcmd->next;
|
||||||
delete headcmd;
|
delete headcmd;
|
||||||
headcmd = a;
|
headcmd = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuMngr::iterator MenuMngr::SetWatchIter(MenuMngr::iterator iter)
|
int MenuMngr::MenuIdEle::uniqueid = 0;
|
||||||
{
|
|
||||||
MenuMngr::iterator old = m_watch_iter;
|
|
||||||
|
|
||||||
m_watch_iter = iter;
|
|
||||||
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MenuMngr::MenuIdEle::uniqueid = 0;
|
|
@ -38,59 +38,55 @@
|
|||||||
|
|
||||||
class MenuMngr
|
class MenuMngr
|
||||||
{
|
{
|
||||||
struct MenuIdEle
|
struct MenuIdEle
|
||||||
{
|
{
|
||||||
String name;
|
String name;
|
||||||
AMX* amx;
|
AMX* amx;
|
||||||
MenuIdEle* next;
|
MenuIdEle* next;
|
||||||
|
int id;
|
||||||
int id;
|
static int uniqueid;
|
||||||
static int uniqueid;
|
MenuIdEle( const char* n, AMX* a, MenuIdEle* m ) : name( n ) , amx(a) , next( m ) {
|
||||||
|
id = ++uniqueid;
|
||||||
MenuIdEle(const char* n, AMX* a, MenuIdEle* m) : name(n), amx(a), next(m)
|
}
|
||||||
{
|
~MenuIdEle() { --uniqueid; }
|
||||||
id = ++uniqueid;
|
} *headid;
|
||||||
}
|
|
||||||
} *headid;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class iterator;
|
class iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class MenuCommand
|
class MenuCommand
|
||||||
{
|
{
|
||||||
friend class iterator;
|
friend class iterator;
|
||||||
friend class MenuMngr;
|
friend class MenuMngr;
|
||||||
|
|
||||||
CPluginMngr::CPlugin *plugin;
|
CPluginMngr::CPlugin *plugin;
|
||||||
int menuid;
|
int menuid;
|
||||||
int keys;
|
int keys;
|
||||||
int function;
|
int function;
|
||||||
|
MenuCommand* next;
|
||||||
MenuCommand* next;
|
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
|
||||||
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
public:
|
||||||
public:
|
inline int getFunction() { return function; }
|
||||||
inline int getFunction() { return function; }
|
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
inline bool matchCommand( int m, int k ) { return ((m == menuid) && (keys & k)); }
|
||||||
inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
|
} *headcmd;
|
||||||
} *headcmd;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MenuMngr() : m_watch_iter(end())
|
|
||||||
{ headid = NULL; headcmd = NULL; }
|
MenuMngr() { headid = 0; headcmd = 0; }
|
||||||
~MenuMngr();
|
~MenuMngr();
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
|
|
||||||
int findMenuId(const char* name, AMX* a = 0);
|
int findMenuId(const char* name, AMX* a = 0);
|
||||||
int registerMenuId(const char* n, AMX* a);
|
int registerMenuId(const char* n, AMX* a );
|
||||||
void removeMenuId(int id);
|
|
||||||
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
class iterator
|
class iterator {
|
||||||
{
|
|
||||||
friend class MenuMngr;
|
|
||||||
MenuCommand* a;
|
MenuCommand* a;
|
||||||
public:
|
public:
|
||||||
iterator(MenuCommand*aa) : a(aa) {}
|
iterator(MenuCommand*aa) : a(aa) {}
|
||||||
@ -100,14 +96,8 @@ public:
|
|||||||
operator bool () const { return a ? true : false; }
|
operator bool () const { return a ? true : false; }
|
||||||
MenuCommand& operator*() { return *a; }
|
MenuCommand& operator*() { return *a; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline iterator begin() const { return iterator(headcmd); }
|
inline iterator begin() const { return iterator(headcmd); }
|
||||||
inline iterator end() const { return iterator(0); }
|
inline iterator end() const { return iterator(0); }
|
||||||
|
|
||||||
MenuMngr::iterator SetWatchIter(MenuMngr::iterator iter);
|
|
||||||
inline MenuMngr::iterator GetWatchIter() { return m_watch_iter; }
|
|
||||||
private:
|
|
||||||
MenuMngr::iterator m_watch_iter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //MENUS_H
|
#endif
|
||||||
|
@ -29,19 +29,17 @@
|
|||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "newmenus.h"
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPlayer
|
// class CPlayer
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
void CPlayer::Init(edict_t* e, int i)
|
void CPlayer::Init( edict_t* e , int i )
|
||||||
{
|
{
|
||||||
index = i;
|
index = i;
|
||||||
pEdict = e;
|
pEdict = e;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
ingame = false;
|
ingame = false;
|
||||||
bot_value = false;
|
bot = false;
|
||||||
bot_cached = false;
|
|
||||||
authorized = false;
|
authorized = false;
|
||||||
|
|
||||||
current = 0;
|
current = 0;
|
||||||
@ -50,279 +48,185 @@ void CPlayer::Init(edict_t* e, int i)
|
|||||||
aiming = 0;
|
aiming = 0;
|
||||||
menu = 0;
|
menu = 0;
|
||||||
keys = 0;
|
keys = 0;
|
||||||
menuexpire = 0.0;
|
|
||||||
newmenu = -1;
|
|
||||||
|
|
||||||
death_weapon.clear();
|
death_weapon.clear();
|
||||||
name.clear();
|
name.clear();
|
||||||
ip.clear();
|
ip.clear();
|
||||||
team.clear();
|
team.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayer::Disconnect()
|
void CPlayer::Disconnect() {
|
||||||
{
|
ingame = false;
|
||||||
ingame = false;
|
initialized = false;
|
||||||
initialized = false;
|
authorized = false;
|
||||||
authorized = false;
|
bot = 0;
|
||||||
|
|
||||||
if (newmenu != -1)
|
|
||||||
{
|
|
||||||
Menu *pMenu = g_NewMenus[newmenu];
|
|
||||||
if (pMenu)
|
|
||||||
{
|
|
||||||
//prevent recursion
|
|
||||||
newmenu = -1;
|
|
||||||
menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(ENTINDEX(pEdict)),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
|
||||||
for (iter=queries.begin(); iter!=end; iter++)
|
|
||||||
{
|
|
||||||
unregisterSPForward((*iter)->resultFwd);
|
|
||||||
delete [] (*iter)->params;
|
|
||||||
delete (*iter);
|
|
||||||
}
|
|
||||||
queries.clear();
|
|
||||||
|
|
||||||
bot_value = false;
|
|
||||||
bot_cached = false;
|
|
||||||
menu = 0;
|
|
||||||
newmenu = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayer::PutInServer()
|
void CPlayer::PutInServer() {
|
||||||
{
|
playtime = gpGlobals->time;
|
||||||
playtime = gpGlobals->time;
|
ingame = true;
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPlayer::NextHUDChannel()
|
|
||||||
{
|
|
||||||
int ilow = 1;
|
|
||||||
|
|
||||||
for (int i=ilow+1; i<=4; i++)
|
|
||||||
{
|
|
||||||
if (channels[i] < channels[ilow])
|
|
||||||
ilow = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ilow;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
|
||||||
{
|
|
||||||
bot_value = false;
|
|
||||||
bot_cached = false;
|
|
||||||
name.assign(connectname);
|
|
||||||
ip.assign(ipaddress);
|
|
||||||
time = gpGlobals->time;
|
|
||||||
death_killer = 0;
|
|
||||||
menu = 0;
|
|
||||||
newmenu = -1;
|
|
||||||
|
|
||||||
memset(flags, 0, sizeof(flags));
|
|
||||||
memset(weapons, 0, sizeof(weapons));
|
|
||||||
|
|
||||||
initialized = true;
|
|
||||||
authorized = false;
|
|
||||||
|
|
||||||
for (int i=0; i<=4; i++)
|
|
||||||
{
|
|
||||||
channels[i] = 0.0f;
|
|
||||||
hudmap[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
|
||||||
for (iter=queries.begin(); iter!=end; iter++)
|
|
||||||
{
|
|
||||||
unregisterSPForward((*iter)->resultFwd);
|
|
||||||
delete [] (*iter)->params;
|
|
||||||
delete (*iter);
|
|
||||||
}
|
|
||||||
queries.clear();
|
|
||||||
|
|
||||||
const char* authid = GETPLAYERAUTHID(pEdict);
|
|
||||||
|
|
||||||
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class Grenades
|
// 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;
|
Obj* a = new Obj;
|
||||||
if (a == 0) return;
|
if ( a == 0 ) return;
|
||||||
a->player = player;
|
a->player = player;
|
||||||
a->grenade = grenade;
|
a->grenade = grenade;
|
||||||
a->time = gpGlobals->time + time;
|
a->time = gpGlobals->time + time;
|
||||||
a->type = type;
|
a->type = type;
|
||||||
a->next = head;
|
a->next = head;
|
||||||
head = a;
|
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;
|
bool found = false;
|
||||||
Obj** a = &head;
|
Obj** a = &head;
|
||||||
|
while ( *a ){
|
||||||
while (*a)
|
if ( (*a)->time > gpGlobals->time ) {
|
||||||
{
|
if ( (*a)->grenade == enemy ) {
|
||||||
if ((*a)->time > gpGlobals->time)
|
found = true;
|
||||||
{
|
(*p) = (*a)->player;
|
||||||
if ((*a)->grenade == enemy)
|
type = (*a)->type;
|
||||||
{
|
}
|
||||||
found = true;
|
}
|
||||||
(*p) = (*a)->player;
|
else {
|
||||||
type = (*a)->type;
|
Obj* b = (*a)->next;
|
||||||
}
|
delete *a;
|
||||||
} else {
|
*a = b;
|
||||||
Obj* b = (*a)->next;
|
|
||||||
delete *a;
|
continue;
|
||||||
*a = b;
|
|
||||||
continue;
|
}
|
||||||
}
|
a = &(*a)->next;
|
||||||
a = &(*a)->next;
|
}
|
||||||
}
|
return found;
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grenades::clear()
|
void Grenades::clear()
|
||||||
{
|
{
|
||||||
while (head)
|
while(head){
|
||||||
{
|
Obj* a = head->next;
|
||||||
Obj* a = head->next;
|
delete head;
|
||||||
delete head;
|
head = a;
|
||||||
head = a;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class XVars
|
// class XVars
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
void XVars::clear() {
|
||||||
void XVars::clear()
|
|
||||||
{
|
|
||||||
delete[] head;
|
delete[] head;
|
||||||
head = 0;
|
head = 0;
|
||||||
num = 0;
|
num = 0;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int XVars::put(AMX* p, cell* v)
|
int XVars::put( AMX* p, cell* v )
|
||||||
{
|
{
|
||||||
for (int a = 0; a < num; ++a)
|
for(int a = 0; a < num; ++a) {
|
||||||
{
|
if ( (head[a].amx == p) && (head[a].value == v) )
|
||||||
if ((head[a].amx == p) && (head[a].value == v))
|
return a;
|
||||||
return a;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((num >= size) && realloc_array(size ? (size * 2) : 8))
|
if ( (num >= size) && realloc_array( size ? (size * 2) : 8 ) )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
head[num].value = v;
|
head[num].value = v;
|
||||||
head[num].amx = p;
|
head[num].amx = p;
|
||||||
|
return num++;
|
||||||
return num++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int XVars::realloc_array(int nsize)
|
int XVars::realloc_array( int nsize )
|
||||||
{
|
{
|
||||||
XVarEle* me = new XVarEle[nsize];
|
XVarEle* me = new XVarEle[nsize];
|
||||||
|
if ( me ){
|
||||||
if (me)
|
for(int a = 0 ; a < num; ++a)
|
||||||
{
|
|
||||||
for (int a = 0 ; a < num; ++a)
|
|
||||||
me[a] = head[a];
|
me[a] = head[a];
|
||||||
|
|
||||||
delete[] head;
|
delete[] head;
|
||||||
head = me;
|
head = me;
|
||||||
size = nsize;
|
size = nsize;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class TeamIds
|
// class TeamIds
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
TeamIds::TeamIds() { head = 0; newTeam = 0; }
|
TeamIds::TeamIds() { head = 0; newTeam = 0; }
|
||||||
|
TeamIds::~TeamIds() {
|
||||||
TeamIds::~TeamIds()
|
while( head ) {
|
||||||
{
|
|
||||||
while (head)
|
|
||||||
{
|
|
||||||
TeamEle* a = head->next;
|
TeamEle* a = head->next;
|
||||||
delete head;
|
delete head;
|
||||||
head = a;
|
head = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeamIds::registerTeam(const char* n, int s)
|
void TeamIds::registerTeam( const char* n ,int s )
|
||||||
{
|
{
|
||||||
TeamEle** a = &head;
|
TeamEle** a = &head;
|
||||||
|
while( *a ){
|
||||||
while (*a)
|
if ( strcmp((*a)->name.c_str(),n) == 0 ){
|
||||||
{
|
if (s != -1){
|
||||||
if (strcmp((*a)->name.c_str(),n) == 0)
|
|
||||||
{
|
|
||||||
if (s != -1)
|
|
||||||
{
|
|
||||||
(*a)->id = s;
|
(*a)->id = s;
|
||||||
newTeam &= ~(1<<(*a)->tid);
|
newTeam &= ~(1<<(*a)->tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
a = &(*a)->next;
|
a = &(*a)->next;
|
||||||
}
|
}
|
||||||
|
*a = new TeamEle( n , s );
|
||||||
*a = new TeamEle(n, s);
|
if ( *a == 0 ) return;
|
||||||
|
newTeam |= (1<<(*a)->tid);
|
||||||
if (*a == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
newTeam |= (1<<(*a)->tid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int TeamIds::findTeamId(const char* n)
|
int TeamIds::findTeamId( const char* n )
|
||||||
{
|
{
|
||||||
TeamEle* a = head;
|
TeamEle* a = head;
|
||||||
|
while( a ){
|
||||||
while (a)
|
if ( !stricmp(a->name.c_str(),n) )
|
||||||
{
|
|
||||||
if (!stricmp(a->name.c_str(), n))
|
|
||||||
return a->id;
|
return a->id;
|
||||||
a = a->next;
|
a = a->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TeamIds::findTeamIdCase(const char* n)
|
int TeamIds::findTeamIdCase( const char* n)
|
||||||
{
|
{
|
||||||
TeamEle* a = head;
|
TeamEle* a = head;
|
||||||
|
while( a ){
|
||||||
while (a)
|
if ( !strcmp(a->name.c_str(), n) )
|
||||||
{
|
|
||||||
if (!strcmp(a->name.c_str(), n))
|
|
||||||
return a->id;
|
return a->id;
|
||||||
a = a->next;
|
a = a->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char TeamIds::TeamEle::uid = 0;
|
char TeamIds::TeamEle::uid = 0;
|
||||||
|
|
||||||
|
237
amxmodx/CMisc.h
237
amxmodx/CMisc.h
@ -33,48 +33,38 @@
|
|||||||
#define CMISC_H
|
#define CMISC_H
|
||||||
|
|
||||||
#include "CList.h"
|
#include "CList.h"
|
||||||
#include "sh_list.h"
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CCVar
|
// class CCVar
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
class CCVar
|
class CCVar
|
||||||
{
|
{
|
||||||
cvar_t cvar;
|
cvar_t cvar;
|
||||||
String name;
|
String name;
|
||||||
String plugin;
|
String plugin;
|
||||||
|
|
||||||
public:
|
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.name = (char*)name.c_str();
|
||||||
cvar.flags = pflags;
|
cvar.flags = pflags;
|
||||||
cvar.string = "";
|
cvar.string = "";
|
||||||
cvar.value = pvalue;
|
cvar.value = pvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline cvar_t* getCvar() { return &cvar; }
|
inline cvar_t* getCvar() { return &cvar; }
|
||||||
inline const char* getPluginName() { return plugin.c_str(); }
|
inline const char* getPluginName() { return plugin.c_str(); }
|
||||||
inline const char* getName() { return name.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); }
|
||||||
int plugin_id;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPlayer
|
// class CPlayer
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
struct ClientCvarQuery_Info
|
|
||||||
{
|
|
||||||
int resultFwd;
|
|
||||||
int requestId;
|
|
||||||
int paramLen;
|
|
||||||
cell *params;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CPlayer
|
class CPlayer
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
edict_t* pEdict;
|
edict_t* pEdict;
|
||||||
|
|
||||||
@ -84,17 +74,13 @@ public:
|
|||||||
|
|
||||||
bool initialized;
|
bool initialized;
|
||||||
bool ingame;
|
bool ingame;
|
||||||
bool bot_cached;
|
bool bot;
|
||||||
bool bot_value;
|
|
||||||
bool authorized;
|
bool authorized;
|
||||||
bool vgui;
|
|
||||||
|
|
||||||
float time;
|
float time;
|
||||||
float playtime;
|
float playtime;
|
||||||
float menuexpire;
|
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
|
||||||
int ammo;
|
int ammo;
|
||||||
int clip;
|
int clip;
|
||||||
} weapons[MAX_WEAPONS];
|
} weapons[MAX_WEAPONS];
|
||||||
@ -115,52 +101,26 @@ public:
|
|||||||
String death_weapon;
|
String death_weapon;
|
||||||
int newmenu;
|
int newmenu;
|
||||||
int page;
|
int page;
|
||||||
|
|
||||||
float channels[5];
|
|
||||||
cell hudmap[5];
|
|
||||||
|
|
||||||
Vector lastTrace;
|
Vector lastTrace;
|
||||||
|
Vector thisTrace;
|
||||||
Vector lastHit;
|
Vector lastHit;
|
||||||
|
|
||||||
List<ClientCvarQuery_Info *> queries;
|
void Init( edict_t* e , int i );
|
||||||
|
|
||||||
void Init(edict_t* e, int i);
|
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
void PutInServer();
|
void PutInServer();
|
||||||
|
bool Connect(const char* connectname,const char* ipaddress);
|
||||||
bool Connect(const char* connectname, const char* ipaddress);
|
|
||||||
|
|
||||||
inline bool IsBot()
|
inline bool IsBot(){
|
||||||
{
|
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
|
||||||
if (!bot_cached)
|
|
||||||
{
|
|
||||||
bot_value = false;
|
|
||||||
if (pEdict->v.flags & FL_FAKECLIENT)
|
|
||||||
{
|
|
||||||
bot_value = true;
|
|
||||||
bot_cached = true;
|
|
||||||
} else {
|
|
||||||
const char *auth = GETPLAYERAUTHID(pEdict);
|
|
||||||
if (auth && (strcmp(auth, "BOT") == 0))
|
|
||||||
{
|
|
||||||
bot_value = true;
|
|
||||||
bot_cached = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bot_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAlive()
|
inline bool IsAlive(){
|
||||||
{
|
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
|
||||||
return ((pEdict->v.deadflag == DEAD_NO) && (pEdict->v.health > 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Authorize() { authorized = true; }
|
inline void Authorize() { authorized = true; }
|
||||||
|
|
||||||
int NextHUDChannel();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
@ -169,44 +129,40 @@ public:
|
|||||||
|
|
||||||
class Grenades
|
class Grenades
|
||||||
{
|
{
|
||||||
struct Obj
|
struct Obj
|
||||||
{
|
{
|
||||||
CPlayer* player;
|
CPlayer* player;
|
||||||
edict_t* grenade;
|
edict_t* grenade;
|
||||||
float time;
|
float time;
|
||||||
int type;
|
int type;
|
||||||
Obj* next;
|
Obj* next;
|
||||||
} *head;
|
} *head;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Grenades() { head = 0; }
|
Grenades() { head = 0; }
|
||||||
~Grenades() { clear(); }
|
~Grenades() { clear(); }
|
||||||
|
void put( edict_t* grenade, float time, int type, CPlayer* player );
|
||||||
void put(edict_t* grenade, float time, int type, CPlayer* player);
|
bool find( edict_t* enemy, CPlayer** p, int& type );
|
||||||
bool find(edict_t* enemy, CPlayer** p, int& type);
|
void clear();
|
||||||
void clear();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class ForceObject
|
// class ForceObject
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
class ForceObject {
|
||||||
class ForceObject
|
String filename;
|
||||||
{
|
FORCE_TYPE type;
|
||||||
String filename;
|
Vector mins;
|
||||||
FORCE_TYPE type;
|
Vector maxs;
|
||||||
Vector mins;
|
AMX* amx;
|
||||||
Vector maxs;
|
|
||||||
AMX* amx;
|
|
||||||
public:
|
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 const char* getFilename() { return filename.c_str(); }
|
||||||
inline AMX* getAMX() { return amx; }
|
inline AMX* getAMX() { return amx; }
|
||||||
|
|
||||||
Vector& getMin() { return mins; }
|
Vector& getMin() { return mins; }
|
||||||
Vector& getMax() { return maxs; }
|
Vector& getMax() { return maxs; }
|
||||||
|
|
||||||
inline FORCE_TYPE getForceType() { return type; }
|
inline FORCE_TYPE getForceType() { return type; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -216,92 +172,81 @@ public:
|
|||||||
|
|
||||||
class XVars
|
class XVars
|
||||||
{
|
{
|
||||||
struct XVarEle
|
struct XVarEle {
|
||||||
{
|
AMX* amx;
|
||||||
AMX* amx;
|
cell* value;
|
||||||
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:
|
public:
|
||||||
XVars() { num = 0; size = 0; head = 0; }
|
XVars() { num = 0; size = 0; head = 0; }
|
||||||
~XVars() { clear(); }
|
~XVars() { clear(); }
|
||||||
|
void clear();
|
||||||
void clear();
|
int put( AMX* a, cell* v );
|
||||||
int put(AMX* a, cell* v);
|
inline cell getValue( int a ) {
|
||||||
|
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
|
||||||
inline cell getValue(int a)
|
}
|
||||||
{
|
inline int setValue( int a, cell v ) {
|
||||||
return (a >= 0 && a < num) ? *(head[a].value) : 0;
|
if ( a >= 0 && a < num ){
|
||||||
}
|
*(head[a].value) = v;
|
||||||
|
return 0;
|
||||||
inline int setValue(int a, cell v)
|
}
|
||||||
{
|
return 1;
|
||||||
if (a >= 0 && a < num)
|
}
|
||||||
{
|
|
||||||
*(head[a].value) = v;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CScript
|
// class CScript
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
class CScript
|
class CScript
|
||||||
{
|
{
|
||||||
String filename;
|
String filename;
|
||||||
AMX* amx;
|
AMX* amx;
|
||||||
void* code;
|
void* code;
|
||||||
public:
|
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 AMX* getAMX() { return amx; }
|
||||||
inline const char* getName() { return filename.c_str(); }
|
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; }
|
inline void* getCode() { return code; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class TeamIds
|
// class TeamIds
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
class TeamIds
|
class TeamIds
|
||||||
{
|
{
|
||||||
struct TeamEle
|
struct TeamEle {
|
||||||
{
|
String name;
|
||||||
String name;
|
int id;
|
||||||
int id;
|
char tid;
|
||||||
char tid;
|
static char uid;
|
||||||
static char uid;
|
TeamEle* next;
|
||||||
TeamEle* next;
|
TeamEle(const char* n, int& i) : name(n) , id(i) , next(0) {
|
||||||
|
tid = uid++;
|
||||||
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
|
};
|
||||||
{
|
~TeamEle(){ --uid; }
|
||||||
tid = uid++;
|
} *head;
|
||||||
}
|
|
||||||
|
|
||||||
~TeamEle() { --uid; }
|
|
||||||
} *head;
|
|
||||||
|
|
||||||
int newTeam;
|
int newTeam;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TeamIds();
|
TeamIds();
|
||||||
~TeamIds();
|
~TeamIds();
|
||||||
|
void registerTeam( const char* n ,int s );
|
||||||
void registerTeam(const char* n, int s);
|
int findTeamId( const char* n);
|
||||||
int findTeamId(const char* n);
|
int findTeamIdCase( const char* n);
|
||||||
int findTeamIdCase(const char* n);
|
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||||
inline bool isNewTeam() { return newTeam ? true : false; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CMISC_H
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,10 +30,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "libraries.h"
|
|
||||||
|
|
||||||
#ifndef FAR
|
#ifndef FAR
|
||||||
#define FAR
|
#define FAR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// New
|
// New
|
||||||
@ -42,8 +41,6 @@ typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo
|
|||||||
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
||||||
typedef int (FAR *DETACHMOD_NEW)(void);
|
typedef int (FAR *DETACHMOD_NEW)(void);
|
||||||
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
||||||
typedef void (*PLUGINSUNLOADED_NEW)(void);
|
|
||||||
typedef void (*PLUGINSUNLOADING_NEW)(void);
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CModule
|
// class CModule
|
||||||
@ -58,7 +55,7 @@ CModule::CModule(const char* fname)
|
|||||||
CModule::~CModule()
|
CModule::~CModule()
|
||||||
{
|
{
|
||||||
// old & new
|
// old & new
|
||||||
if (m_Handle)
|
if ( m_Handle )
|
||||||
DLFREE(m_Handle);
|
DLFREE(m_Handle);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
@ -70,7 +67,6 @@ void CModule::clear(bool clearFilename)
|
|||||||
m_Metamod = false;
|
m_Metamod = false;
|
||||||
m_Handle = NULL;
|
m_Handle = NULL;
|
||||||
m_Status = MODULE_NONE;
|
m_Status = MODULE_NONE;
|
||||||
|
|
||||||
if (clearFilename)
|
if (clearFilename)
|
||||||
m_Filename.assign("unknown");
|
m_Filename.assign("unknown");
|
||||||
|
|
||||||
@ -82,14 +78,7 @@ void CModule::clear(bool clearFilename)
|
|||||||
m_InfoNew.reload = 0;
|
m_InfoNew.reload = 0;
|
||||||
m_MissingFunc = NULL;
|
m_MissingFunc = NULL;
|
||||||
|
|
||||||
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
|
|
||||||
{
|
|
||||||
delete [] m_Natives[m_DestroyableIndexes[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DestroyableIndexes.clear();
|
|
||||||
m_Natives.clear();
|
m_Natives.clear();
|
||||||
m_NewNatives.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||||
@ -112,53 +101,6 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this ugly function is ultimately something like O(n^4).
|
|
||||||
//sigh. it shouldn't be needed.
|
|
||||||
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
|
|
||||||
{
|
|
||||||
AMX_NATIVE_INFO *curlist;
|
|
||||||
for (size_t i=0; i<m_Natives.size(); i++)
|
|
||||||
{
|
|
||||||
curlist = m_Natives[i];
|
|
||||||
bool changed = false;
|
|
||||||
bool found = false;
|
|
||||||
CVector<size_t> newlist;
|
|
||||||
for (size_t j=0; curlist[j].func != NULL; j++)
|
|
||||||
{
|
|
||||||
found = false;
|
|
||||||
for (size_t k=0; list[k].func != NULL; k++)
|
|
||||||
{
|
|
||||||
if (strcmp(curlist[j].name, list[k].name) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found)
|
|
||||||
{
|
|
||||||
changed = true;
|
|
||||||
//don't break, we have to search it all
|
|
||||||
} else {
|
|
||||||
newlist.push_back(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
//now build the new list
|
|
||||||
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
|
|
||||||
for (size_t j=0; j<newlist.size(); j++)
|
|
||||||
{
|
|
||||||
rlist[j].func = curlist[newlist[j]].func;
|
|
||||||
rlist[j].name = curlist[newlist[j]].name;
|
|
||||||
}
|
|
||||||
rlist[newlist.size()].func = NULL;
|
|
||||||
rlist[newlist.size()].name = NULL;
|
|
||||||
m_Natives[i] = rlist;
|
|
||||||
m_DestroyableIndexes.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CModule::attachModule()
|
bool CModule::attachModule()
|
||||||
{
|
{
|
||||||
// old & new
|
// old & new
|
||||||
@ -172,7 +114,6 @@ bool CModule::attachModule()
|
|||||||
|
|
||||||
if (!AttachFunc_New)
|
if (!AttachFunc_New)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
g_ModuleCallReason = ModuleCall_Attach;
|
g_ModuleCallReason = ModuleCall_Attach;
|
||||||
g_CurrentlyCalledModule = this;
|
g_CurrentlyCalledModule = this;
|
||||||
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
||||||
@ -181,39 +122,32 @@ bool CModule::attachModule()
|
|||||||
|
|
||||||
switch (retVal)
|
switch (retVal)
|
||||||
{
|
{
|
||||||
case AMXX_OK:
|
case AMXX_OK:
|
||||||
m_Status = MODULE_LOADED;
|
m_Status = MODULE_LOADED;
|
||||||
break;
|
return true;
|
||||||
case AMXX_PARAM:
|
case AMXX_PARAM:
|
||||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||||
m_Status = MODULE_INTERROR;
|
m_Status = MODULE_INTERROR;
|
||||||
return false;
|
return false;
|
||||||
case AMXX_FUNC_NOT_PRESENT:
|
case AMXX_FUNC_NOT_PRESENT:
|
||||||
m_Status = MODULE_FUNCNOTPRESENT;
|
m_Status = MODULE_FUNCNOTPRESENT;
|
||||||
m_MissingFunc = g_LastRequestedFunc;
|
m_MissingFunc = g_LastRequestedFunc;
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Status == MODULE_LOADED)
|
|
||||||
{
|
|
||||||
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
|
|
||||||
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModule::queryModule()
|
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;
|
return false;
|
||||||
|
|
||||||
m_Handle = DLLOAD(m_Filename.c_str()); // load file
|
m_Handle = DLLOAD(m_Filename.c_str()); // load file
|
||||||
@ -229,7 +163,6 @@ bool CModule::queryModule()
|
|||||||
|
|
||||||
// Try new interface first
|
// Try new interface first
|
||||||
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
|
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
|
||||||
|
|
||||||
if (queryFunc_New)
|
if (queryFunc_New)
|
||||||
{
|
{
|
||||||
m_Amxx = true;
|
m_Amxx = true;
|
||||||
@ -239,51 +172,24 @@ bool CModule::queryModule()
|
|||||||
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||||
g_CurrentlyCalledModule = NULL;
|
g_CurrentlyCalledModule = NULL;
|
||||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
|
|
||||||
switch (retVal)
|
switch (retVal)
|
||||||
{
|
{
|
||||||
case AMXX_PARAM:
|
case AMXX_PARAM:
|
||||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||||
m_Status = MODULE_INTERROR;
|
m_Status = MODULE_INTERROR;
|
||||||
return false;
|
return false;
|
||||||
case AMXX_IFVERS:
|
case AMXX_IFVERS:
|
||||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||||
{
|
m_Status = MODULE_OLD;
|
||||||
//backwards compat for new defs
|
else
|
||||||
if (ifVers == 3)
|
m_Status = MODULE_NEWER;
|
||||||
{
|
return false;
|
||||||
g_ModuleCallReason = ModuleCall_Query;
|
case AMXX_OK:
|
||||||
g_CurrentlyCalledModule = this;
|
break;
|
||||||
retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
default:
|
||||||
g_CurrentlyCalledModule = NULL;
|
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
m_Status = MODULE_BADLOAD;
|
||||||
if (retVal == AMXX_OK)
|
return false;
|
||||||
{
|
|
||||||
m_InfoNew.library = m_InfoNew.logtag;
|
|
||||||
if (StrCaseStr(m_InfoNew.library, "sql")
|
|
||||||
|| StrCaseStr(m_InfoNew.library, "dbi"))
|
|
||||||
{
|
|
||||||
m_InfoNew.libclass = "DBI";
|
|
||||||
} else {
|
|
||||||
m_InfoNew.libclass = "";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
m_Status = MODULE_OLD;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} 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
|
// Check for attach
|
||||||
@ -295,7 +201,9 @@ bool CModule::queryModule()
|
|||||||
|
|
||||||
m_Status = MODULE_QUERY;
|
m_Status = MODULE_QUERY;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_Status = MODULE_NOQUERY;
|
m_Status = MODULE_NOQUERY;
|
||||||
m_Amxx = false;
|
m_Amxx = false;
|
||||||
return false;
|
return false;
|
||||||
@ -307,12 +215,9 @@ bool CModule::detachModule()
|
|||||||
if (m_Status != MODULE_LOADED)
|
if (m_Status != MODULE_LOADED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RemoveLibraries(this);
|
|
||||||
|
|
||||||
if (m_Amxx)
|
if (m_Amxx)
|
||||||
{
|
{
|
||||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||||
|
|
||||||
if (detachFunc_New)
|
if (detachFunc_New)
|
||||||
{
|
{
|
||||||
g_ModuleCallReason = ModuleCall_Detach;
|
g_ModuleCallReason = ModuleCall_Detach;
|
||||||
@ -322,52 +227,17 @@ bool CModule::detachModule()
|
|||||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FAKEMETA
|
#ifndef FAKEMETA
|
||||||
if (IsMetamod())
|
if (IsMetamod())
|
||||||
{
|
{
|
||||||
UnloadMetamodPlugin(m_Handle);
|
UnloadMetamodPlugin(m_Handle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DLFREE(m_Handle);
|
DLFREE(m_Handle);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModule::CallPluginsUnloaded()
|
|
||||||
{
|
|
||||||
if (m_Status != MODULE_LOADED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_Handle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
|
|
||||||
|
|
||||||
if (!func)
|
|
||||||
return;
|
|
||||||
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModule::CallPluginsUnloading()
|
|
||||||
{
|
|
||||||
if (m_Status != MODULE_LOADED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_Handle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
|
|
||||||
|
|
||||||
if (!func)
|
|
||||||
return;
|
|
||||||
|
|
||||||
func();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CModule::CallPluginsLoaded()
|
void CModule::CallPluginsLoaded()
|
||||||
{
|
{
|
||||||
if (m_Status != MODULE_LOADED)
|
if (m_Status != MODULE_LOADED)
|
||||||
@ -377,31 +247,28 @@ void CModule::CallPluginsLoaded()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
|
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
|
||||||
|
|
||||||
if (!func)
|
if (!func)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
func();
|
func();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CModule::getStatus() const
|
const char* CModule::getStatus() const
|
||||||
{
|
{
|
||||||
switch (m_Status)
|
switch(m_Status)
|
||||||
{
|
{
|
||||||
case MODULE_NONE: return "error";
|
case MODULE_NONE: return "error";
|
||||||
case MODULE_QUERY: return "pending";
|
case MODULE_QUERY: return "pending";
|
||||||
case MODULE_BADLOAD: return "bad load";
|
case MODULE_BADLOAD: return "bad load";
|
||||||
case MODULE_LOADED: return "running";
|
case MODULE_LOADED: return "running";
|
||||||
case MODULE_NOINFO: return "no info";
|
case MODULE_NOINFO: return "no info";
|
||||||
case MODULE_NOQUERY: return "no query";
|
case MODULE_NOQUERY: return "no query";
|
||||||
case MODULE_NOATTACH: return "no attach";
|
case MODULE_NOATTACH: return "no attach";
|
||||||
case MODULE_OLD: return "old";
|
case MODULE_OLD: return "old";
|
||||||
case MODULE_FUNCNOTPRESENT:
|
case MODULE_FUNCNOTPRESENT:
|
||||||
case MODULE_NEWER: return "newer";
|
case MODULE_NEWER: return "newer";
|
||||||
case MODULE_INTERROR: return "internal err";
|
case MODULE_INTERROR: return "internal err";
|
||||||
case MODULE_NOT64BIT: return "not 64bit";
|
case MODULE_NOT64BIT: return "not 64bit";
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -36,20 +36,19 @@
|
|||||||
#ifndef CMODULE_H
|
#ifndef CMODULE_H
|
||||||
#define CMODULE_H
|
#define CMODULE_H
|
||||||
|
|
||||||
enum MODULE_STATUS
|
enum MODULE_STATUS {
|
||||||
{
|
MODULE_NONE, // No module loaded
|
||||||
MODULE_NONE, // No module loaded
|
MODULE_QUERY, // Query failed
|
||||||
MODULE_QUERY, // Query failed
|
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
|
||||||
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
|
MODULE_LOADED, // Loaded
|
||||||
MODULE_LOADED, // Loaded
|
MODULE_NOINFO, // No info
|
||||||
MODULE_NOINFO, // No info
|
MODULE_NOQUERY, // No query function present
|
||||||
MODULE_NOQUERY, // No query function present
|
MODULE_NOATTACH, // No attach function present
|
||||||
MODULE_NOATTACH, // No attach function present
|
MODULE_OLD, // Old interface
|
||||||
MODULE_OLD, // Old interface
|
MODULE_NEWER, // newer interface
|
||||||
MODULE_NEWER, // newer interface
|
MODULE_INTERROR, // Internal error
|
||||||
MODULE_INTERROR, // Internal error
|
MODULE_FUNCNOTPRESENT, // Function not present
|
||||||
MODULE_FUNCNOTPRESENT, // Function not present
|
MODULE_NOT64BIT // Not 64 bit compatible
|
||||||
MODULE_NOT64BIT // Not 64 bit compatible
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amxx_module_info_s
|
struct amxx_module_info_s
|
||||||
@ -59,24 +58,21 @@ struct amxx_module_info_s
|
|||||||
const char *version;
|
const char *version;
|
||||||
int reload; // reload on mapchange when nonzero
|
int reload; // reload on mapchange when nonzero
|
||||||
const char *logtag; //added in version 2
|
const char *logtag; //added in version 2
|
||||||
const char *library; // added in version 4
|
|
||||||
const char *libclass; // added in version 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define AMXX_OK 0 /* no error */
|
#define AMXX_OK 0 /* no error */
|
||||||
#define AMXX_IFVERS 1 /* interface version */
|
#define AMXX_IFVERS 1 /* interface version */
|
||||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||||
|
|
||||||
#define AMXX_INTERFACE_VERSION 4
|
#define AMXX_INTERFACE_VERSION 3
|
||||||
|
|
||||||
class CModule
|
class CModule
|
||||||
{
|
{
|
||||||
String m_Filename; // Filename
|
String m_Filename; // Filename
|
||||||
|
|
||||||
bool m_Metamod; // Using metamod?
|
bool m_Metamod; // Using metamod?
|
||||||
bool m_Amxx; // Using new module interface?
|
bool m_Amxx; // Using new module interface?
|
||||||
|
|
||||||
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||||
DLHANDLE m_Handle; // handle
|
DLHANDLE m_Handle; // handle
|
||||||
MODULE_STATUS m_Status; // status
|
MODULE_STATUS m_Status; // status
|
||||||
@ -88,16 +84,12 @@ public:
|
|||||||
~CModule();
|
~CModule();
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
bool attachModule();
|
bool attachModule();
|
||||||
bool queryModule();
|
bool queryModule();
|
||||||
bool detachModule();
|
bool detachModule();
|
||||||
void rewriteNativeLists(AMX_NATIVE_INFO *list);
|
|
||||||
|
|
||||||
#ifndef FAKEMETA
|
#ifndef FAKEMETA
|
||||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* getStatus() const;
|
const char* getStatus() const;
|
||||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
||||||
inline const char* getAuthor() const { return m_InfoNew.author; }
|
inline const char* getAuthor() const { return m_InfoNew.author; }
|
||||||
@ -105,20 +97,18 @@ public:
|
|||||||
inline const char* getName() const { return m_InfoNew.name; }
|
inline const char* getName() const { return m_InfoNew.name; }
|
||||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||||
inline int getStatusValue() { return m_Status; }
|
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 isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
|
||||||
inline bool isAmxx() const { return m_Amxx; }
|
inline bool isAmxx() const { return m_Amxx; }
|
||||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||||
inline bool IsMetamod() { return m_Metamod; }
|
inline bool IsMetamod() { return m_Metamod; }
|
||||||
|
void CModule::CallPluginsLoaded();
|
||||||
void CallPluginsLoaded();
|
|
||||||
void CallPluginsUnloaded();
|
|
||||||
void CallPluginsUnloading();
|
|
||||||
|
|
||||||
CVector<AMX_NATIVE_INFO*> m_Natives;
|
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||||
CVector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
|
|
||||||
CVector<size_t> m_DestroyableIndexes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CMODULE_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* In addition, as a special exception, the author gives permission to
|
* In addition, as a special exception, the author gives permission to
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
* 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
|
* 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
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
@ -35,25 +35,17 @@
|
|||||||
#include "CFile.h"
|
#include "CFile.h"
|
||||||
#include "amx.h"
|
#include "amx.h"
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
|
||||||
#include "libraries.h"
|
|
||||||
|
|
||||||
extern const char *no_function;
|
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;
|
CPlugin** a = &head;
|
||||||
|
while( *a ) a = &(*a)->next;
|
||||||
while (*a)
|
*a = new CPlugin( pCounter++ ,path,name,error, debug);
|
||||||
a = &(*a)->next;
|
|
||||||
|
|
||||||
*a = new CPlugin(pCounter++, path, name, error, debug);
|
|
||||||
|
|
||||||
return (*a);
|
return (*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::unloadPlugin(CPlugin** a)
|
void CPluginMngr::unloadPlugin( CPlugin** a ) {
|
||||||
{
|
|
||||||
CPlugin* next = (*a)->next;
|
CPlugin* next = (*a)->next;
|
||||||
delete *a;
|
delete *a;
|
||||||
*a = next;
|
*a = next;
|
||||||
@ -64,10 +56,9 @@ void CPluginMngr::Finalize()
|
|||||||
{
|
{
|
||||||
if (m_Finalized)
|
if (m_Finalized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pNatives = BuildNativeTable();
|
pNatives = BuildNativeTable();
|
||||||
|
|
||||||
CPlugin *a = head;
|
CPlugin *a = head;
|
||||||
|
|
||||||
while (a)
|
while (a)
|
||||||
{
|
{
|
||||||
if (a->getStatusCode() == ps_running)
|
if (a->getStatusCode() == ps_running)
|
||||||
@ -75,23 +66,19 @@ void CPluginMngr::Finalize()
|
|||||||
amx_Register(a->getAMX(), pNatives, -1);
|
amx_Register(a->getAMX(), pNatives, -1);
|
||||||
a->Finalize();
|
a->Finalize();
|
||||||
}
|
}
|
||||||
a = a->next;
|
a=a->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Finalized = true;
|
m_Finalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||||
{
|
{
|
||||||
char file[256];
|
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 )
|
||||||
{
|
{
|
||||||
if (warn)
|
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename);
|
||||||
{
|
|
||||||
AMXXLOG_Error("[AMXX] Plugins list not found (file \"%s\")", filename);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,70 +89,29 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
|||||||
|
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
List<String *>::iterator block_iter;
|
while ( !feof(fp) )
|
||||||
|
|
||||||
while (!feof(fp))
|
|
||||||
{
|
{
|
||||||
pluginName[0] = '\0';
|
pluginName[0] = '\0';
|
||||||
|
|
||||||
debug[0] = '\0';
|
debug[0] = '\0';
|
||||||
debugFlag = 0;
|
debugFlag = 0;
|
||||||
|
|
||||||
line.clear();
|
line.clear();
|
||||||
line._fread(fp);
|
line._fread(fp);
|
||||||
/** quick hack */
|
sscanf(line.c_str(),"%s %s",pluginName, debug);
|
||||||
char *ptr = const_cast<char *>(line.c_str());
|
if (!isalnum(*pluginName)) continue;
|
||||||
while (*ptr)
|
|
||||||
{
|
|
||||||
if (*ptr == ';')
|
|
||||||
{
|
|
||||||
*ptr = '\0';
|
|
||||||
} else {
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sscanf(line.c_str(), "%s %s", pluginName, debug);
|
|
||||||
|
|
||||||
if (!isalnum(*pluginName))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isalnum(*debug) && !strcmp(debug, "debug"))
|
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
||||||
{
|
{
|
||||||
debugFlag = 1;
|
debugFlag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skip = false;
|
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error, debugFlag);
|
||||||
for (block_iter = m_BlockList.begin();
|
|
||||||
block_iter != m_BlockList.end();
|
|
||||||
block_iter++)
|
|
||||||
{
|
|
||||||
if ((*block_iter)->compare(pluginName) == 0)
|
|
||||||
{
|
|
||||||
skip = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip || !strcmp(debug, "disabled"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findPlugin(pluginName) != NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
|
|
||||||
|
|
||||||
if (plugin->getStatusCode() == ps_bad_load)
|
if (plugin->getStatusCode() == ps_bad_load)
|
||||||
{
|
{
|
||||||
char errorMsg[255];
|
char errorMsg[255];
|
||||||
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
|
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
|
||||||
plugin->setError(errorMsg);
|
plugin->setError(errorMsg);
|
||||||
AMXXLOG_Error("[AMXX] %s", plugin->getError());
|
AMXXLOG_Log("[AMXX] %s", plugin->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,134 +120,91 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
|||||||
return pCounter;
|
return pCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::clear()
|
void CPluginMngr::clear() {
|
||||||
{
|
|
||||||
CPlugin**a = &head;
|
CPlugin**a = &head;
|
||||||
|
while ( *a )
|
||||||
while (*a)
|
|
||||||
unloadPlugin(a);
|
unloadPlugin(a);
|
||||||
|
|
||||||
m_Finalized = false;
|
m_Finalized = false;
|
||||||
|
|
||||||
if (pNatives)
|
if (pNatives)
|
||||||
{
|
{
|
||||||
delete [] pNatives;
|
delete [] pNatives;
|
||||||
pNatives = NULL;
|
pNatives = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String *>::iterator iter = m_BlockList.begin();
|
|
||||||
while (iter != m_BlockList.end())
|
|
||||||
{
|
|
||||||
delete (*iter);
|
|
||||||
iter = m_BlockList.erase(iter);
|
|
||||||
}
|
|
||||||
m_BlockList.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
|
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||||
{
|
{
|
||||||
|
return (CPlugin*)(amx->userdata[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
|
||||||
CPlugin*a = head;
|
CPlugin*a = head;
|
||||||
|
while ( a && &a->amx != amx )
|
||||||
while (a && &a->amx != amx)
|
a=a->next;
|
||||||
a = a->next;
|
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index)
|
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){
|
||||||
{
|
|
||||||
CPlugin*a = head;
|
CPlugin*a = head;
|
||||||
|
while ( a && index--)
|
||||||
while (a && index--)
|
a=a->next;
|
||||||
a = a->next;
|
|
||||||
|
|
||||||
return a;
|
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);
|
int len = strlen(name);
|
||||||
|
if (!len) return 0;
|
||||||
if (!len)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
CPlugin*a = head;
|
CPlugin*a = head;
|
||||||
|
while( a && strncmp(a->name.c_str(), name,len) )
|
||||||
while (a && strncmp(a->name.c_str(), name, len))
|
a=a->next;
|
||||||
a = a->next;
|
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::AddToFailCounter(unsigned int i)
|
const char* CPluginMngr::CPlugin::getStatus() const {
|
||||||
{
|
switch(status){
|
||||||
failcounter += i;
|
case ps_running:
|
||||||
if ((failcounter >= 3)
|
|
||||||
&& (status ))
|
|
||||||
{
|
|
||||||
errorMsg.assign("This plugin is non-GPL which violates AMX Mod X's license.");
|
|
||||||
status = ps_bad_load;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* CPluginMngr::CPlugin::getStatus() const
|
|
||||||
{
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case ps_running:
|
|
||||||
{
|
|
||||||
if (m_Debug)
|
|
||||||
{
|
{
|
||||||
return "debug";
|
if (m_Debug)
|
||||||
} else {
|
{
|
||||||
return "running";
|
return "debug";
|
||||||
|
} else {
|
||||||
|
return "running";
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case ps_paused: return "paused";
|
||||||
}
|
case ps_bad_load: return "bad load";
|
||||||
case ps_paused: return "paused";
|
case ps_stopped: return "stopped";
|
||||||
case ps_bad_load: return "bad load";
|
case ps_locked: return "locked";
|
||||||
case ps_stopped: return "stopped";
|
|
||||||
case ps_locked: return "locked";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "error";
|
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";
|
const char* unk = "unknown";
|
||||||
|
|
||||||
failcounter = 0;
|
|
||||||
title.assign(unk);
|
title.assign(unk);
|
||||||
author.assign(unk);
|
author.assign(unk);
|
||||||
version.assign(unk);
|
version.assign(unk);
|
||||||
|
|
||||||
char file[256];
|
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;
|
code = 0;
|
||||||
memset(&amx, 0, sizeof(AMX));
|
memset(&amx, 0, sizeof(AMX));
|
||||||
int err = load_amxscript(&amx, &code, path, e, d);
|
int err = load_amxscript(&amx,&code,path,e, d);
|
||||||
|
if ( err == AMX_ERR_NONE )
|
||||||
if (err == AMX_ERR_NONE)
|
|
||||||
{
|
{
|
||||||
status = ps_running;
|
status = ps_running;
|
||||||
} else {
|
} else {
|
||||||
status = ps_bad_load;
|
status = ps_bad_load;
|
||||||
}
|
}
|
||||||
|
amx.userdata[3] = this;
|
||||||
amx.userdata[UD_FINDPLUGIN] = this;
|
|
||||||
paused_fun = 0;
|
paused_fun = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
id = i;
|
id = i;
|
||||||
|
|
||||||
if (status == ps_running)
|
if (status == ps_running)
|
||||||
{
|
{
|
||||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE);
|
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE);
|
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||||
|
|
||||||
if (amx.flags & AMX_FLAG_DEBUG)
|
if (amx.flags & AMX_FLAG_DEBUG)
|
||||||
{
|
{
|
||||||
m_Debug = true;
|
m_Debug = true;
|
||||||
@ -311,109 +214,51 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = (int)(_INT_PTR)(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))
|
|
||||||
{
|
|
||||||
amx->usertags[UT_NATIVE] = (void *)native;
|
|
||||||
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()
|
void CPluginMngr::CPlugin::Finalize()
|
||||||
{
|
{
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
|
||||||
int old_status = status;
|
int old_status = status;
|
||||||
|
|
||||||
if (CheckModules(&amx, buffer))
|
if (CheckModules(&amx, buffer))
|
||||||
{
|
{
|
||||||
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
|
if ( amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE )
|
||||||
{
|
{
|
||||||
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
|
status = ps_bad_load;
|
||||||
int res = 0;
|
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||||
|
errorMsg.assign(buffer);
|
||||||
if (pHandler->IsNativeFiltering())
|
amx.error = AMX_ERR_NOTFOUND;
|
||||||
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 {
|
} else {
|
||||||
status = ps_bad_load;
|
status = ps_bad_load;
|
||||||
errorMsg.assign(buffer);
|
errorMsg.assign(buffer);
|
||||||
amx.error = AMX_ERR_NOTFOUND;
|
amx.error = AMX_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_status != status)
|
if (old_status != status)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
|
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 ) {
|
||||||
{
|
if (isValid()){
|
||||||
|
paused_fun |= (1<<id);
|
||||||
|
g_commands.clearBufforedInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::unpauseFunction(int id)
|
void CPluginMngr::CPlugin::unpauseFunction( int id ) {
|
||||||
{
|
if (isValid()) {
|
||||||
|
paused_fun &= ~(1<<id);
|
||||||
|
g_commands.clearBufforedInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::setStatus(int a)
|
void CPluginMngr::CPlugin::setStatus( int a ) {
|
||||||
{
|
|
||||||
status = a;
|
status = a;
|
||||||
g_commands.clearBufforedInfo(); // ugly way
|
g_commands.clearBufforedInfo(); // ugly way
|
||||||
}
|
}
|
||||||
@ -434,286 +279,13 @@ void CPluginMngr::CPlugin::pausePlugin()
|
|||||||
// Unpause a plugin
|
// Unpause a plugin
|
||||||
void CPluginMngr::CPlugin::unpausePlugin()
|
void CPluginMngr::CPlugin::unpausePlugin()
|
||||||
{
|
{
|
||||||
if (isValid() && (getStatusCode() != ps_stopped))
|
if (isValid())
|
||||||
{
|
{
|
||||||
// set status first so the function will be marked executable
|
// set status first so the function will be marked executable
|
||||||
|
|
||||||
setStatus(ps_running);
|
setStatus(ps_running);
|
||||||
|
|
||||||
// call plugin_unpause if provided
|
// call plugin_unpause if provided
|
||||||
if (m_UnpauseFwd != -1)
|
if (m_UnpauseFwd != -1)
|
||||||
{
|
|
||||||
executeForwards(m_UnpauseFwd);
|
executeForwards(m_UnpauseFwd);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
|
||||||
{
|
|
||||||
List<plcache_entry *>::iterator iter;
|
|
||||||
plcache_entry *pl;
|
|
||||||
|
|
||||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
|
||||||
{
|
|
||||||
pl = (*iter);
|
|
||||||
if (pl->path.compare(file) == 0)
|
|
||||||
{
|
|
||||||
bufsize = pl->bufsize;
|
|
||||||
return pl->buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pl = new plcache_entry;
|
|
||||||
|
|
||||||
pl->file = new CAmxxReader(file, sizeof(cell));
|
|
||||||
pl->buffer = NULL;
|
|
||||||
if (pl->file->GetStatus() != CAmxxReader::Err_None ||
|
|
||||||
pl->file->IsOldFile())
|
|
||||||
{
|
|
||||||
delete pl->file;
|
|
||||||
delete pl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pl->bufsize = pl->file->GetBufferSize();
|
|
||||||
if (pl->bufsize)
|
|
||||||
{
|
|
||||||
pl->buffer = new char[pl->bufsize];
|
|
||||||
pl->file->GetSection(pl->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pl->buffer || pl->file->GetStatus() != CAmxxReader::Err_None)
|
|
||||||
{
|
|
||||||
delete [] pl->buffer;
|
|
||||||
delete pl->file;
|
|
||||||
delete pl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pl->path.assign(file);
|
|
||||||
|
|
||||||
bufsize = pl->bufsize;
|
|
||||||
|
|
||||||
m_plcache.push_back(pl);
|
|
||||||
|
|
||||||
return pl->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::InvalidateCache()
|
|
||||||
{
|
|
||||||
List<plcache_entry *>::iterator iter;
|
|
||||||
plcache_entry *pl;
|
|
||||||
|
|
||||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
|
||||||
{
|
|
||||||
pl = (*iter);
|
|
||||||
delete [] pl->buffer;
|
|
||||||
delete pl->file;
|
|
||||||
delete pl;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_plcache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf)
|
|
||||||
{
|
|
||||||
List<plcache_entry *>::iterator iter;
|
|
||||||
plcache_entry *pl;
|
|
||||||
|
|
||||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
|
||||||
{
|
|
||||||
pl = (*iter);
|
|
||||||
if (pl->path.compare(file) == 0)
|
|
||||||
{
|
|
||||||
if (freebuf)
|
|
||||||
delete [] pl->buffer;
|
|
||||||
delete pl->file;
|
|
||||||
delete pl;
|
|
||||||
m_plcache.erase(iter);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CacheAndLoadModules(const char *plugin)
|
|
||||||
{
|
|
||||||
size_t progsize;
|
|
||||||
char *prog = ReadIntoOrFromCache(plugin, progsize);
|
|
||||||
|
|
||||||
if (!prog)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AMX_HEADER hdr;
|
|
||||||
memcpy(&hdr, prog, sizeof(AMX_HEADER));
|
|
||||||
|
|
||||||
uint16_t magic = hdr.magic;
|
|
||||||
amx_Align16(&magic);
|
|
||||||
|
|
||||||
if (magic != AMX_MAGIC)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr.file_version < MIN_FILE_VERSION ||
|
|
||||||
hdr.file_version > CUR_FILE_VERSION)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) &&
|
|
||||||
(hdr.defsize != sizeof(AMX_FUNCSTUBNT)))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
amx_Align32((uint32_t*)&hdr.nametable);
|
|
||||||
uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable);
|
|
||||||
amx_Align16(namelength);
|
|
||||||
if (*namelength>sNAMEMAX)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr.stp <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX amx;
|
|
||||||
memset(&amx, 0, sizeof(AMX));
|
|
||||||
amx.base = (unsigned char *)prog;
|
|
||||||
|
|
||||||
int num;
|
|
||||||
char name[sNAMEMAX+1];
|
|
||||||
|
|
||||||
num = amx_GetLibraries(&amx);
|
|
||||||
for (int i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
amx_GetLibrary(&amx, i, name, sNAMEMAX);
|
|
||||||
if (stricmp(name, "Float")==0)
|
|
||||||
continue;
|
|
||||||
//awful backwards compat hack
|
|
||||||
if (stricmp(name, "socket")==0)
|
|
||||||
strcpy(name, "sockets");
|
|
||||||
//we don't want to report failed modules here...
|
|
||||||
LoadModule(name, PT_ANYTIME, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
cell tag_id;
|
|
||||||
amx_NumTags(&amx, &num);
|
|
||||||
|
|
||||||
CVector<LibDecoder *> expects;
|
|
||||||
CVector<LibDecoder *> defaults;
|
|
||||||
CStack<LibDecoder *> delstack;
|
|
||||||
for (int i=0; i<num; i++)
|
|
||||||
{
|
|
||||||
amx_GetTag(&amx, i, name, &tag_id);
|
|
||||||
if (name[0] == '?')
|
|
||||||
{
|
|
||||||
LibDecoder *dc = new LibDecoder;
|
|
||||||
delstack.push(dc);
|
|
||||||
if (DecodeLibCmdString(name, dc))
|
|
||||||
{
|
|
||||||
if (dc->cmd == LibCmd_ForceLib)
|
|
||||||
{
|
|
||||||
RunLibCommand(dc);
|
|
||||||
} else if ( (dc->cmd == LibCmd_ExpectClass) ||
|
|
||||||
(dc->cmd == LibCmd_ExpectLib) )
|
|
||||||
{
|
|
||||||
expects.push_back(dc);
|
|
||||||
} else if (dc->cmd == LibCmd_DefaultLib) {
|
|
||||||
defaults.push_back(dc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i=0; i<expects.size(); i++)
|
|
||||||
{
|
|
||||||
RunLibCommand(expects[i]);
|
|
||||||
}
|
|
||||||
for (size_t i=0; i<defaults.size(); i++)
|
|
||||||
{
|
|
||||||
RunLibCommand(defaults[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
expects.clear();
|
|
||||||
defaults.clear();
|
|
||||||
|
|
||||||
while (!delstack.empty())
|
|
||||||
{
|
|
||||||
delete delstack.front();
|
|
||||||
delstack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CALMFromFile(const char *file)
|
|
||||||
{
|
|
||||||
char filename[256];
|
|
||||||
FILE *fp = fopen(build_pathname_r(filename, sizeof(filename) - 1, "%s", file), "rt");
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find now folder
|
|
||||||
char pluginName[256];
|
|
||||||
char line[256];
|
|
||||||
String rline;
|
|
||||||
|
|
||||||
while (!feof(fp))
|
|
||||||
{
|
|
||||||
fgets(line, sizeof(line)-1, fp);
|
|
||||||
if (line[0] == ';' || line[0] == '\n' || line[0] == '\0')
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** quick hack */
|
|
||||||
char *ptr = line;
|
|
||||||
while (*ptr)
|
|
||||||
{
|
|
||||||
if (*ptr == ';')
|
|
||||||
{
|
|
||||||
*ptr = '\0';
|
|
||||||
} else {
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rline.assign(line);
|
|
||||||
rline.trim();
|
|
||||||
pluginName[0] = '\0';
|
|
||||||
sscanf(rline.c_str(), "%s", pluginName);
|
|
||||||
|
|
||||||
/* HACK: see if there's a 'disabled' coming up
|
|
||||||
* new block for scopying flexibility
|
|
||||||
*/
|
|
||||||
if (1)
|
|
||||||
{
|
|
||||||
const char *_ptr = rline.c_str() + strlen(pluginName);
|
|
||||||
while (*_ptr != '\0' && isspace(*_ptr))
|
|
||||||
{
|
|
||||||
_ptr++;
|
|
||||||
}
|
|
||||||
if ((*_ptr != '\0') && !strcmp(_ptr, "disabled"))
|
|
||||||
{
|
|
||||||
String *pString = new String(pluginName);
|
|
||||||
m_BlockList.push_back(pString);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isalnum(*pluginName))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
build_pathname_r(filename, sizeof(filename)-1, "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName);
|
|
||||||
|
|
||||||
CacheAndLoadModules(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
@ -32,27 +32,22 @@
|
|||||||
#ifndef PLUGIN_H
|
#ifndef PLUGIN_H
|
||||||
#define PLUGIN_H
|
#define PLUGIN_H
|
||||||
|
|
||||||
#include "CString.h"
|
|
||||||
#include "sh_list.h"
|
|
||||||
#include "amx.h"
|
|
||||||
#include "amxxfile.h"
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPluginMngr
|
// class CPluginMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
ps_bad_load,
|
||||||
ps_bad_load, //Load failed
|
ps_error,
|
||||||
ps_error, //Erroneous state
|
ps_paused,
|
||||||
ps_locked, //UNUSED
|
ps_running,
|
||||||
ps_paused, //Plugin is temporarily paused
|
ps_stopped,
|
||||||
ps_stopped, //Plugin is ... more temporarily paused
|
ps_locked,
|
||||||
ps_running, //Plugin is running
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPluginMngr
|
class CPluginMngr
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class iterator;
|
class iterator;
|
||||||
@ -64,26 +59,23 @@ public:
|
|||||||
|
|
||||||
AMX amx;
|
AMX amx;
|
||||||
void* code;
|
void* code;
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
String version;
|
String version;
|
||||||
String title;
|
String title;
|
||||||
String author;
|
String author;
|
||||||
String errorMsg;
|
String errorMsg;
|
||||||
|
|
||||||
unsigned int failcounter;
|
|
||||||
int m_PauseFwd;
|
int m_PauseFwd;
|
||||||
int m_UnpauseFwd;
|
int m_UnpauseFwd;
|
||||||
int paused_fun;
|
int paused_fun;
|
||||||
int status;
|
int status;
|
||||||
CPlugin* next;
|
CPlugin* next;
|
||||||
int id;
|
int id;
|
||||||
|
CPlugin(int i , const char* p,const char* n, char* e, int d);
|
||||||
CPlugin(int i, const char* p, const char* n, char* e, int d);
|
~CPlugin( );
|
||||||
~CPlugin();
|
|
||||||
|
|
||||||
bool m_Debug;
|
bool m_Debug;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline const char* getName() { return name.c_str();}
|
inline const char* getName() { return name.c_str();}
|
||||||
inline const char* getVersion() { return version.c_str();}
|
inline const char* getVersion() { return version.c_str();}
|
||||||
inline const char* getTitle() { return title.c_str();}
|
inline const char* getTitle() { return title.c_str();}
|
||||||
@ -93,23 +85,20 @@ public:
|
|||||||
inline int getId() const { return id; }
|
inline int getId() const { return id; }
|
||||||
inline AMX* getAMX() { return &amx; }
|
inline AMX* getAMX() { return &amx; }
|
||||||
inline const AMX* getAMX() const { return &amx; }
|
inline const AMX* getAMX() const { return &amx; }
|
||||||
inline void setTitle(const char* n) { title.assign(n); }
|
inline void setTitle( const char* n ) { title.assign(n); }
|
||||||
inline void setAuthor(const char* n) { author.assign(n); }
|
inline void setAuthor( const char* n ) { author.assign(n); }
|
||||||
inline void setVersion(const char* n) { version.assign(n); }
|
inline void setVersion( const char* n ) { version.assign(n); }
|
||||||
inline void setError(const char* n) { errorMsg.assign(n); }
|
inline void setError( const char* n ) { errorMsg.assign(n); }
|
||||||
inline bool isValid() const { return (status >= ps_paused); }
|
inline bool isValid() const { return ((status == ps_running) && (status != ps_locked)); }
|
||||||
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
|
inline bool isPaused() const { return ( (status == ps_paused) ); }
|
||||||
inline bool isStopped() const { return (status == ps_stopped); }
|
//inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||||
|
|
||||||
void Finalize();
|
void Finalize();
|
||||||
void AddToFailCounter(unsigned int i);
|
|
||||||
void pausePlugin();
|
void pausePlugin();
|
||||||
void unpausePlugin();
|
void unpausePlugin();
|
||||||
void pauseFunction(int id);
|
void pauseFunction( int id );
|
||||||
void unpauseFunction(int id);
|
void unpauseFunction( int id );
|
||||||
void setStatus(int a);
|
void setStatus( int a );
|
||||||
|
|
||||||
const char* getStatus() const;
|
const char* getStatus() const;
|
||||||
inline bool isDebug() const { return m_Debug; }
|
inline bool isDebug() const { return m_Debug; }
|
||||||
};
|
};
|
||||||
@ -117,9 +106,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
CPlugin *head;
|
CPlugin *head;
|
||||||
int pCounter;
|
int pCounter;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||||
~CPluginMngr() { clear(); InvalidateCache(); }
|
~CPluginMngr() { clear(); }
|
||||||
|
|
||||||
bool m_Finalized;
|
bool m_Finalized;
|
||||||
AMX_NATIVE_INFO *pNatives;
|
AMX_NATIVE_INFO *pNatives;
|
||||||
@ -127,20 +118,17 @@ public:
|
|||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
||||||
void unloadPlugin(CPlugin** a);
|
void unloadPlugin( CPlugin** a );
|
||||||
int loadPluginsFromFile(const char* filename, bool warn=true);
|
int loadPluginsFromFile( const char* filename );
|
||||||
|
CPlugin* findPluginFast(AMX *amx);
|
||||||
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); }
|
|
||||||
CPlugin* findPlugin(AMX *amx);
|
CPlugin* findPlugin(AMX *amx);
|
||||||
CPlugin* findPlugin(int index);
|
CPlugin* findPlugin(int index);
|
||||||
CPlugin* findPlugin(const char* name);
|
CPlugin* findPlugin(const char* name);
|
||||||
|
|
||||||
inline int getPluginsNum() const { return pCounter; }
|
inline int getPluginsNum() const { return pCounter; }
|
||||||
void Finalize();
|
void Finalize();
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
class iterator
|
class iterator {
|
||||||
{
|
|
||||||
CPlugin *a;
|
CPlugin *a;
|
||||||
public:
|
public:
|
||||||
iterator(CPlugin*aa) : a(aa) {}
|
iterator(CPlugin*aa) : a(aa) {}
|
||||||
@ -150,25 +138,10 @@ public:
|
|||||||
operator bool () const { return a ? true : false; }
|
operator bool () const { return a ? true : false; }
|
||||||
CPlugin& operator*() { return *a; }
|
CPlugin& operator*() { return *a; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline iterator begin() const { return iterator(head); }
|
inline iterator begin() const { return iterator(head); }
|
||||||
inline iterator end() const { return iterator(0); }
|
inline iterator end() const { return iterator(0); }
|
||||||
public:
|
|
||||||
struct plcache_entry
|
|
||||||
{
|
|
||||||
CAmxxReader *file;
|
|
||||||
size_t bufsize;
|
|
||||||
char *buffer;
|
|
||||||
String path;
|
|
||||||
};
|
|
||||||
char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
|
|
||||||
void InvalidateCache();
|
|
||||||
void InvalidateFileInCache(const char *file, bool freebuf);
|
|
||||||
void CacheAndLoadModules(const char *plugin);
|
|
||||||
void CALMFromFile(const char *file);
|
|
||||||
private:
|
|
||||||
List<plcache_entry *> m_plcache;
|
|
||||||
List<String *> m_BlockList;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PLUGIN_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,17 +45,14 @@ public:
|
|||||||
item = i;
|
item = i;
|
||||||
next = n;
|
next = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
CQueueItem *GetNext()
|
CQueueItem *GetNext()
|
||||||
{
|
{
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
T & GetItem()
|
T & GetItem()
|
||||||
{
|
{
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNext(CQueueItem *n)
|
void SetNext(CQueueItem *n)
|
||||||
{
|
{
|
||||||
next = n;
|
next = n;
|
||||||
@ -74,7 +71,7 @@ public:
|
|||||||
|
|
||||||
bool empty()
|
bool empty()
|
||||||
{
|
{
|
||||||
return ((mSize == 0) ? true : false);
|
return ((mSize==0)?true:false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void push(const T &v)
|
void push(const T &v)
|
||||||
@ -122,8 +119,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
CQueueItem *mFirst;
|
CQueueItem *mFirst;
|
||||||
CQueueItem *mLast;
|
CQueueItem *mLast;
|
||||||
|
|
||||||
unsigned int mSize;
|
unsigned int mSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_CQUEUE_H
|
#endif //_INCLUDE_CQUEUE_H
|
||||||
|
|
||||||
|
152
amxmodx/nongpl_matches.h → amxmodx/CStack.h
Normal file → Executable file
152
amxmodx/nongpl_matches.h → amxmodx/CStack.h
Normal file → Executable file
@ -1,51 +1,101 @@
|
|||||||
/* AMX Mod X
|
/* AMX Mod X
|
||||||
*
|
*
|
||||||
* by the AMX Mod X Development Team
|
* by the AMX Mod X Development Team
|
||||||
* originally developed by OLO
|
* originally developed by OLO
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
* Free Software Foundation; either version 2 of the License, or (at
|
||||||
* your option) any later version.
|
* your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but
|
* This program is distributed in the hope that it will be useful, but
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* In addition, as a special exception, the author gives permission to
|
* In addition, as a special exception, the author gives permission to
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
* 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
|
* 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
|
* 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
|
* 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
|
* you do not wish to do so, delete this exception statement from your
|
||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
//by David "BAILOPAN" Anderson
|
||||||
#define _INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
#ifndef _INCLUDE_CSTACK_H
|
||||||
|
#define _INCLUDE_CSTACK_H
|
||||||
struct NONGPL_PLUGIN_T
|
|
||||||
{
|
template <class T>
|
||||||
const char *author;
|
class CStack
|
||||||
const char *title;
|
{
|
||||||
const char *filename;
|
public:
|
||||||
};
|
struct CStackItem
|
||||||
|
{
|
||||||
struct NONGPL_CVAR_T
|
public:
|
||||||
{
|
T item;
|
||||||
const char *cvar;
|
CStackItem *prev;
|
||||||
int type;
|
};
|
||||||
};
|
public:
|
||||||
|
CStack()
|
||||||
extern NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[];
|
{
|
||||||
extern NONGPL_CVAR_T NONGPL_CVAR_LIST[];
|
mSize = 0;
|
||||||
|
mStack = NULL;
|
||||||
#endif //_INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
}
|
||||||
|
~CStack()
|
||||||
|
{
|
||||||
|
CStackItem *p, *t;
|
||||||
|
p = mStack;
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
t = p->prev;
|
||||||
|
delete p;
|
||||||
|
p = t;
|
||||||
|
}
|
||||||
|
mStack = NULL;
|
||||||
|
}
|
||||||
|
bool empty()
|
||||||
|
{
|
||||||
|
return (mSize==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(const T & v)
|
||||||
|
{
|
||||||
|
CStackItem *p = new CStackItem;
|
||||||
|
p->item = v;
|
||||||
|
p->prev = mStack;
|
||||||
|
mStack = p;
|
||||||
|
mSize++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
CStackItem *p = mStack;
|
||||||
|
mStack = p->prev;
|
||||||
|
delete p;
|
||||||
|
mSize--;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & top()
|
||||||
|
{
|
||||||
|
return mStack->item;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size()
|
||||||
|
{
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
CStackItem *mStack;
|
||||||
|
size_t mSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_CQUEUE_H
|
||||||
|
|
@ -66,7 +66,7 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
String(const String &src)
|
String(String &src)
|
||||||
{
|
{
|
||||||
v = NULL;
|
v = NULL;
|
||||||
a_size = 0;
|
a_size = 0;
|
||||||
@ -107,10 +107,8 @@ public:
|
|||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
} else {
|
} else {
|
||||||
size_t len = strlen(d);
|
Grow(strlen(d) + 1, false);
|
||||||
Grow(len + 1, false);
|
strcpy(v, d);
|
||||||
memcpy(v, d, len);
|
|
||||||
v[len] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +118,7 @@ public:
|
|||||||
v[0] = '\0';
|
v[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare (const char *d) const
|
int compare (const char *d)
|
||||||
{
|
{
|
||||||
if (!v)
|
if (!v)
|
||||||
return strcmp("", d);
|
return strcmp("", d);
|
||||||
@ -150,13 +148,13 @@ public:
|
|||||||
|
|
||||||
int find(const char c, int index = 0)
|
int find(const char c, int index = 0)
|
||||||
{
|
{
|
||||||
int len = static_cast<int>(size());
|
size_t len = size();
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
return npos;
|
return npos;
|
||||||
if (index >= len || index < 0)
|
if (index >= (int)len || index < 0)
|
||||||
return npos;
|
return npos;
|
||||||
int i = 0;
|
unsigned int i = 0;
|
||||||
for (i=index; i<len; i++)
|
for (i=index; i<(int)len; i++)
|
||||||
{
|
{
|
||||||
if (v[i] == c)
|
if (v[i] == c)
|
||||||
{
|
{
|
||||||
@ -178,30 +176,6 @@ public:
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reparse_newlines()
|
|
||||||
{
|
|
||||||
size_t len = size();
|
|
||||||
int offs = 0;
|
|
||||||
char c;
|
|
||||||
if (!len)
|
|
||||||
return;
|
|
||||||
for (size_t i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
c = v[i];
|
|
||||||
if (c == '^' && (i != len-1))
|
|
||||||
{
|
|
||||||
c = v[++i];
|
|
||||||
if (c == 'n')
|
|
||||||
c = '\n';
|
|
||||||
else if (c == 't')
|
|
||||||
c = '\t';
|
|
||||||
offs++;
|
|
||||||
}
|
|
||||||
v[i-offs] = c;
|
|
||||||
}
|
|
||||||
v[len-offs] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void trim()
|
void trim()
|
||||||
{
|
{
|
||||||
@ -273,7 +247,7 @@ public:
|
|||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
size_t len = size();
|
size_t len = size();
|
||||||
//check for bounds
|
//check for bounds
|
||||||
if (num == npos || start+num > len-start)
|
if (num == npos || start+num > len-num+1)
|
||||||
num = len - start;
|
num = len - start;
|
||||||
//do the erasing
|
//do the erasing
|
||||||
bool copyflag = false;
|
bool copyflag = false;
|
||||||
@ -323,7 +297,7 @@ public:
|
|||||||
num = len - index;
|
num = len - index;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0, j=0;
|
||||||
unsigned int nslen = num + 2;
|
unsigned int nslen = num + 2;
|
||||||
|
|
||||||
ns.Grow(nslen);
|
ns.Grow(nslen);
|
||||||
|
@ -33,8 +33,17 @@
|
|||||||
#include "CTask.h"
|
#include "CTask.h"
|
||||||
|
|
||||||
/*********************** CTask ***********************/
|
/*********************** CTask ***********************/
|
||||||
|
int CTaskMngr::CTask::getTaskId() const
|
||||||
|
{
|
||||||
|
return m_iId;
|
||||||
|
}
|
||||||
|
|
||||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
|
||||||
|
{
|
||||||
|
return m_pPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
m_bFree = false;
|
m_bFree = false;
|
||||||
@ -43,21 +52,11 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
|||||||
m_iFunc = iFunc;
|
m_iFunc = iFunc;
|
||||||
m_iId = iId;
|
m_iId = iId;
|
||||||
m_fBase = fBase;
|
m_fBase = fBase;
|
||||||
m_bInExecute = false;
|
|
||||||
|
|
||||||
if (iFlags & 2)
|
m_iRepeat = (iFlags & 1) ? iRepeat : 0;
|
||||||
{
|
m_bLoop = (iFlags & 2) ? true : false;
|
||||||
m_bLoop = true;
|
m_bAfterStart = (iFlags & 4) ? true : false;
|
||||||
m_iRepeat = -1;
|
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
||||||
}
|
|
||||||
else if (iFlags & 1)
|
|
||||||
{
|
|
||||||
m_bLoop = true;
|
|
||||||
m_iRepeat = iRepeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bAfterStart = (iFlags & 4) ? true : false;
|
|
||||||
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
|
||||||
|
|
||||||
m_fNextExecTime = fCurrentTime + m_fBase;
|
m_fNextExecTime = fCurrentTime + m_fBase;
|
||||||
|
|
||||||
@ -93,10 +92,10 @@ void CTaskMngr::CTask::clear()
|
|||||||
m_iId = 0;
|
m_iId = 0;
|
||||||
m_fBase = 0.0f;
|
m_fBase = 0.0f;
|
||||||
|
|
||||||
m_iRepeat = 0;
|
m_iRepeat = 0;
|
||||||
m_bLoop = false;
|
m_bLoop = false;
|
||||||
m_bAfterStart = false;
|
m_bAfterStart = false;
|
||||||
m_bBeforeEnd = false;
|
m_bBeforeEnd = false;
|
||||||
|
|
||||||
m_fNextExecTime = 0.0f;
|
m_fNextExecTime = 0.0f;
|
||||||
}
|
}
|
||||||
@ -118,9 +117,7 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
|
|||||||
|
|
||||||
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
|
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
|
||||||
{
|
{
|
||||||
bool execute = false;
|
bool execute=false;
|
||||||
bool done = false;
|
|
||||||
|
|
||||||
if (m_bAfterStart)
|
if (m_bAfterStart)
|
||||||
{
|
{
|
||||||
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
|
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
|
||||||
@ -132,44 +129,30 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
|||||||
execute = true;
|
execute = true;
|
||||||
}
|
}
|
||||||
else if (m_fNextExecTime <= fCurrentTime)
|
else if (m_fNextExecTime <= fCurrentTime)
|
||||||
{
|
|
||||||
execute = true;
|
execute = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (execute)
|
if (execute)
|
||||||
{
|
{
|
||||||
//only bother calling if we have something to call
|
if (m_iParamLen) // call with parameters
|
||||||
if (!(m_bLoop && !m_iRepeat))
|
|
||||||
{
|
{
|
||||||
m_bInExecute = true;
|
cell arr = prepareCellArray(m_pParams, m_iParamLen);
|
||||||
if (m_iParamLen) // call with parameters
|
executeForwards(m_iFunc, arr, m_iId);
|
||||||
{
|
} else {
|
||||||
cell arr = prepareCellArray(m_pParams, m_iParamLen);
|
executeForwards(m_iFunc, m_iId);
|
||||||
executeForwards(m_iFunc, arr, m_iId);
|
|
||||||
} else {
|
|
||||||
executeForwards(m_iFunc, m_iId);
|
|
||||||
}
|
|
||||||
m_bInExecute = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFree())
|
if (isFree())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// set new exec time OR remove the task if needed
|
// set new exec time OR remove the task if needed
|
||||||
if (m_bLoop)
|
if (m_bLoop || (m_iRepeat-- > 0))
|
||||||
{
|
{
|
||||||
if (m_iRepeat != -1 && --m_iRepeat <= 0)
|
|
||||||
done = true;
|
|
||||||
} else {
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
} else {
|
|
||||||
m_fNextExecTime += m_fBase;
|
m_fNextExecTime += m_fBase;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clear(); // hamster
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,11 +165,10 @@ CTaskMngr::CTask::CTask()
|
|||||||
m_iId = 0;
|
m_iId = 0;
|
||||||
m_fBase = 0.0f;
|
m_fBase = 0.0f;
|
||||||
|
|
||||||
m_iRepeat = 0;
|
m_iRepeat = 0;
|
||||||
m_bLoop = false;
|
m_bLoop = false;
|
||||||
m_bAfterStart = false;
|
m_bAfterStart = false;
|
||||||
m_bBeforeEnd = false;
|
m_bBeforeEnd = false;
|
||||||
m_bInExecute = false;
|
|
||||||
|
|
||||||
m_fNextExecTime = 0.0f;
|
m_fNextExecTime = 0.0f;
|
||||||
|
|
||||||
@ -200,7 +182,6 @@ CTaskMngr::CTask::~CTask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*********************** CTaskMngr ***********************/
|
/*********************** CTaskMngr ***********************/
|
||||||
|
|
||||||
CTaskMngr::CTaskMngr()
|
CTaskMngr::CTaskMngr()
|
||||||
{
|
{
|
||||||
m_pTmr_CurrentTime = NULL;
|
m_pTmr_CurrentTime = NULL;
|
||||||
@ -220,22 +201,21 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT
|
|||||||
m_pTmr_TimeLeft = pTimeLeft;
|
m_pTmr_TimeLeft = pTimeLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
||||||
{
|
{
|
||||||
// first, search for free tasks
|
// first, search for free tasks
|
||||||
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
||||||
|
|
||||||
if (iter)
|
if (iter)
|
||||||
{
|
{
|
||||||
// found: reuse it
|
// found: reuse it
|
||||||
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// not found: make a new one
|
// not found: make a new one
|
||||||
CTask *pTmp = new CTask;
|
CTask *pTmp = new CTask;
|
||||||
|
|
||||||
if (!pTmp)
|
if (!pTmp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||||
m_Tasks.put(pTmp);
|
m_Tasks.put(pTmp);
|
||||||
}
|
}
|
||||||
@ -245,15 +225,13 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
|
|||||||
{
|
{
|
||||||
CTaskDescriptor descriptor(iId, pAmx);
|
CTaskDescriptor descriptor(iId, pAmx);
|
||||||
TaskListIter iter = m_Tasks.find(descriptor);
|
TaskListIter iter = m_Tasks.find(descriptor);
|
||||||
int i = 0;
|
int i=0;
|
||||||
|
|
||||||
while (iter)
|
while (iter)
|
||||||
{
|
{
|
||||||
iter->clear();
|
iter->clear();
|
||||||
++i;
|
++i;
|
||||||
iter = m_Tasks.find(++iter, descriptor);
|
iter = m_Tasks.find(++iter, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,16 +239,14 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
|
|||||||
{
|
{
|
||||||
CTaskDescriptor descriptor(iId, pAmx);
|
CTaskDescriptor descriptor(iId, pAmx);
|
||||||
TaskListIter iter = m_Tasks.find(descriptor);
|
TaskListIter iter = m_Tasks.find(descriptor);
|
||||||
int i = 0;
|
int i=0;
|
||||||
|
|
||||||
while (iter)
|
while (iter)
|
||||||
{
|
{
|
||||||
iter->changeBase(fNewBase);
|
iter->changeBase(fNewBase);
|
||||||
iter->resetNextExecTime(*m_pTmr_CurrentTime);
|
iter->resetNextExecTime(*m_pTmr_CurrentTime);
|
||||||
++i;
|
++i;
|
||||||
iter = m_Tasks.find(++iter, descriptor);
|
iter = m_Tasks.find(++iter, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,40 +39,34 @@ private:
|
|||||||
class CTask
|
class CTask
|
||||||
{
|
{
|
||||||
// task settings
|
// task settings
|
||||||
|
|
||||||
CPluginMngr::CPlugin *m_pPlugin;
|
CPluginMngr::CPlugin *m_pPlugin;
|
||||||
cell m_iId;
|
int m_iId;
|
||||||
int m_iFunc;
|
int m_iFunc;
|
||||||
int m_iRepeat;
|
int m_iRepeat;
|
||||||
|
|
||||||
bool m_bInExecute;
|
|
||||||
bool m_bLoop;
|
bool m_bLoop;
|
||||||
bool m_bAfterStart;
|
bool m_bAfterStart;
|
||||||
bool m_bBeforeEnd;
|
bool m_bBeforeEnd;
|
||||||
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
|
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
|
||||||
int m_iParamLen;
|
int m_iParamLen;
|
||||||
|
|
||||||
cell *m_pParams;
|
cell *m_pParams;
|
||||||
bool m_bFree;
|
bool m_bFree;
|
||||||
|
|
||||||
// execution
|
// execution
|
||||||
float m_fNextExecTime;
|
float m_fNextExecTime;
|
||||||
public:
|
public:
|
||||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||||
void clear();
|
void clear();
|
||||||
bool isFree() const;
|
bool isFree() const;
|
||||||
|
|
||||||
inline CPluginMngr::CPlugin *getPlugin() const { return m_pPlugin; }
|
CPluginMngr::CPlugin *getPlugin() const;
|
||||||
inline AMX *getAMX() const { return m_pPlugin->getAMX(); }
|
int getTaskId() const;
|
||||||
inline int getTaskId() const { return m_iId; }
|
|
||||||
|
|
||||||
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 changeBase(float fNewBase);
|
||||||
void resetNextExecTime(float fCurrentTime);
|
void resetNextExecTime(float fCurrentTime);
|
||||||
inline bool inExecute() const { return m_bInExecute; }
|
|
||||||
|
|
||||||
bool shouldRepeat();
|
bool shouldRepeat();
|
||||||
|
|
||||||
CTask();
|
CTask();
|
||||||
~CTask();
|
~CTask();
|
||||||
@ -81,7 +75,7 @@ private:
|
|||||||
class CTaskDescriptor
|
class CTaskDescriptor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cell m_iId;
|
int m_iId;
|
||||||
AMX *m_pAmx;
|
AMX *m_pAmx;
|
||||||
bool m_bFree;
|
bool m_bFree;
|
||||||
|
|
||||||
@ -95,20 +89,18 @@ private:
|
|||||||
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
|
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
|
||||||
{
|
{
|
||||||
if (right.m_bFree)
|
if (right.m_bFree)
|
||||||
return (left.isFree() && !left.inExecute());
|
return left.isFree();
|
||||||
|
|
||||||
return (!left.isFree()) &&
|
return !left.isFree() &&
|
||||||
(right.m_pAmx ? left.getAMX() == right.m_pAmx : true) &&
|
(right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) &&
|
||||||
(left.getTaskId() == right.m_iId);
|
left.getTaskId() == right.m_iId;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** CTaskMngr priv members ***/
|
/*** CTaskMngr priv members ***/
|
||||||
typedef CList<CTask, CTaskDescriptor> TaskList;
|
typedef CList<CTask, CTaskDescriptor> TaskList;
|
||||||
typedef TaskList::iterator TaskListIter;
|
typedef TaskList::iterator TaskListIter;
|
||||||
|
|
||||||
TaskList m_Tasks;
|
TaskList m_Tasks;
|
||||||
|
|
||||||
float *m_pTmr_CurrentTime;
|
float *m_pTmr_CurrentTime;
|
||||||
float *m_pTmr_TimeLimit;
|
float *m_pTmr_TimeLimit;
|
||||||
float *m_pTmr_TimeLeft;
|
float *m_pTmr_TimeLeft;
|
||||||
@ -117,14 +109,14 @@ public:
|
|||||||
~CTaskMngr();
|
~CTaskMngr();
|
||||||
|
|
||||||
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
|
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, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
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 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 changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
|
|
||||||
bool taskExists(int iId, AMX *pAmx);
|
bool taskExists(int iId, AMX *pAmx);
|
||||||
|
|
||||||
void startFrame();
|
void startFrame();
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CTASK_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,47 +39,46 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class Vault
|
// class Vault
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
bool Vault::exists( const char* k )
|
||||||
bool Vault::exists(const char* k)
|
|
||||||
{
|
{
|
||||||
if (*k == 0) return false;
|
if ( *k == 0 ) return false;
|
||||||
|
|
||||||
return *find(k) != 0;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Obj** a = find(k);
|
Obj** a = find( k );
|
||||||
|
|
||||||
if (*a)
|
if ( *a )
|
||||||
{
|
{
|
||||||
(*a)->value.assign(v);
|
(*a)->value.assign(v);
|
||||||
(*a)->number = atoi(v);
|
(*a)->number = atoi( v );
|
||||||
}
|
}
|
||||||
else
|
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);
|
number = atoi(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vault::Obj** Vault::find(const char* n)
|
Vault::Obj** Vault::find( const char* n )
|
||||||
{
|
{
|
||||||
Obj** a = &head;
|
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;
|
return a;
|
||||||
|
|
||||||
a = &(*a)->next;
|
a = &(*a)->next;
|
||||||
@ -89,89 +88,90 @@ 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;
|
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();
|
return b->value.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vault::clear()
|
void Vault::clear()
|
||||||
{
|
{
|
||||||
while (head)
|
while ( head )
|
||||||
{
|
{
|
||||||
Obj* a = head->next;
|
Obj* a = head->next;
|
||||||
delete head;
|
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;
|
Obj* a = (*b)->next;
|
||||||
delete *b;
|
delete *b;
|
||||||
*b = a;
|
*b = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vault::setSource(const char* n)
|
void Vault::setSource( const char* n )
|
||||||
{
|
{
|
||||||
path.assign(n);
|
path.assign(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Vault::loadVault()
|
|
||||||
|
bool Vault::loadVault( )
|
||||||
{
|
{
|
||||||
if (path.empty()) return false;
|
if ( path.empty() ) return false;
|
||||||
|
|
||||||
clear();
|
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;
|
const int sz = 512;
|
||||||
char value[sz + 1];
|
char value[sz+1];
|
||||||
char key[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))
|
if ( isalpha ( *key ) )
|
||||||
put(key, value);
|
put( key, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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';
|
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';
|
a << b->key << '\t' << b->value << '\n';
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -41,55 +41,53 @@
|
|||||||
|
|
||||||
class Vault
|
class Vault
|
||||||
{
|
{
|
||||||
struct Obj
|
struct Obj
|
||||||
{
|
{
|
||||||
String key;
|
String key;
|
||||||
String value;
|
String value;
|
||||||
|
int number;
|
||||||
int number;
|
Obj *next;
|
||||||
Obj *next;
|
Obj( const char* k, const char* v);
|
||||||
Obj(const char* k, const char* v);
|
} *head;
|
||||||
} *head;
|
|
||||||
|
|
||||||
String path;
|
String path;
|
||||||
|
|
||||||
Obj** find(const char* n);
|
Obj** find( const char* n );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Vault() { head = 0; }
|
Vault() {head=0;}
|
||||||
~Vault() { clear(); }
|
~Vault() { clear();}
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
bool exists(const char* k);
|
bool exists( const char* k );
|
||||||
|
void put(const char* k, const char* v);
|
||||||
void put(const char* k, const char* v);
|
void remove( const char* k );
|
||||||
void remove(const char* k);
|
const char* get( const char* n );
|
||||||
|
int get_number( const char* n );
|
||||||
const char* get(const char* n);
|
void setSource( const char* n );
|
||||||
int get_number(const char* n);
|
bool loadVault( );
|
||||||
void setSource(const char* n);
|
bool saveVault( );
|
||||||
|
void clear();
|
||||||
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); }
|
class iterator {
|
||||||
inline iterator end() const { return iterator(0); }
|
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 //VAULT_CUSTOM_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,58 +70,32 @@ template <class T> class CVector
|
|||||||
// change size
|
// change size
|
||||||
if (size == m_Size)
|
if (size == m_Size)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!size)
|
|
||||||
{
|
|
||||||
if (m_Data)
|
|
||||||
{
|
|
||||||
delete [] m_Data;
|
|
||||||
m_Data = NULL;
|
|
||||||
m_Size = 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
T *newData = new T[size];
|
T *newData = new T[size];
|
||||||
if (!newData)
|
if (!newData)
|
||||||
return false;
|
return false;
|
||||||
if (m_Data)
|
if (m_Data)
|
||||||
{
|
{
|
||||||
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
|
size_t end = (m_Size < size) ? (m_Size) : size;
|
||||||
for (size_t i=0; i<end; i++)
|
for (size_t i=0; i<end; i++)
|
||||||
newData[i] = m_Data[i];
|
newData[i] = m_Data[i];
|
||||||
delete [] m_Data;
|
delete [] m_Data;
|
||||||
}
|
}
|
||||||
|
if (m_Size < size)
|
||||||
|
m_CurrentSize = size;
|
||||||
m_Data = newData;
|
m_Data = newData;
|
||||||
m_Size = size;
|
m_Size = size;
|
||||||
if (m_CurrentUsedSize > m_Size)
|
|
||||||
m_CurrentUsedSize = m_Size;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeMemIfPossible()
|
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:
|
protected:
|
||||||
T *m_Data;
|
T *m_Data;
|
||||||
size_t m_Size;
|
size_t m_Size;
|
||||||
size_t m_CurrentUsedSize;
|
size_t m_CurrentUsedSize;
|
||||||
|
size_t m_CurrentSize;
|
||||||
public:
|
public:
|
||||||
class iterator
|
class iterator
|
||||||
{
|
{
|
||||||
@ -215,7 +189,7 @@ public:
|
|||||||
|
|
||||||
iterator & operator-=(size_t offset)
|
iterator & operator-=(size_t offset)
|
||||||
{
|
{
|
||||||
m_Ptr -= offset;
|
m_Ptr += offset;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,10 +203,10 @@ public:
|
|||||||
iterator operator-(size_t offset) const
|
iterator operator-(size_t offset) const
|
||||||
{
|
{
|
||||||
iterator tmp(*this);
|
iterator tmp(*this);
|
||||||
tmp.m_Ptr -= offset;
|
tmp.m_Ptr += offset;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
T & operator[](size_t offset)
|
T & operator[](size_t offset)
|
||||||
{
|
{
|
||||||
return (*(*this + offset));
|
return (*(*this + offset));
|
||||||
@ -303,12 +277,12 @@ public:
|
|||||||
return m_Size;
|
return m_Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin() const
|
iterator begin()
|
||||||
{
|
{
|
||||||
return iterator(m_Data);
|
return iterator(m_Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end() const
|
iterator end()
|
||||||
{
|
{
|
||||||
return iterator(m_Data + m_CurrentUsedSize);
|
return iterator(m_Data + m_CurrentUsedSize);
|
||||||
}
|
}
|
||||||
@ -322,9 +296,7 @@ public:
|
|||||||
|
|
||||||
bool reserve(size_t newSize)
|
bool reserve(size_t newSize)
|
||||||
{
|
{
|
||||||
if (newSize > m_Size)
|
return ChangeSize(newSize);
|
||||||
return ChangeSize(newSize);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool push_back(const T & elem)
|
bool push_back(const T & elem)
|
||||||
@ -345,15 +317,14 @@ public:
|
|||||||
--m_CurrentUsedSize;
|
--m_CurrentUsedSize;
|
||||||
if (m_CurrentUsedSize < 0)
|
if (m_CurrentUsedSize < 0)
|
||||||
m_CurrentUsedSize = 0;
|
m_CurrentUsedSize = 0;
|
||||||
|
// :TODO: free memory sometimes
|
||||||
FreeMemIfPossible();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool resize(size_t newSize)
|
bool resize(size_t newSize)
|
||||||
{
|
{
|
||||||
if (!ChangeSize(newSize))
|
if (!ChangeSize(newSize))
|
||||||
return false;
|
return false;
|
||||||
m_CurrentUsedSize = newSize;
|
FreeMemIfPossible();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,13 +397,15 @@ public:
|
|||||||
return m_Data[m_CurrentUsedSize - 1];
|
return m_Data[m_CurrentUsedSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(iterator where, const T & value)
|
bool 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
|
// validate iter
|
||||||
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
|
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||||
return iterator(0);
|
return false;
|
||||||
|
|
||||||
size_t ofs = where - begin();
|
|
||||||
|
|
||||||
++m_CurrentUsedSize;
|
++m_CurrentUsedSize;
|
||||||
if (!GrowIfNeeded())
|
if (!GrowIfNeeded())
|
||||||
@ -441,49 +414,33 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
where = begin() + ofs;
|
memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data));
|
||||||
|
memcpy(where.base(), &value, sizeof(T));
|
||||||
// Move subsequent entries
|
return true;
|
||||||
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
|
|
||||||
*(ptr + 1) = *ptr;
|
|
||||||
|
|
||||||
*where.base() = value;
|
|
||||||
|
|
||||||
return where;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator erase(iterator where)
|
void erase(iterator where)
|
||||||
{
|
{
|
||||||
// validate iter
|
// validate iter
|
||||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||||
return iterator(0);
|
return false;
|
||||||
|
|
||||||
size_t ofs = where - begin();
|
|
||||||
|
|
||||||
if (m_CurrentUsedSize > 1)
|
if (m_CurrentUsedSize > 1)
|
||||||
{
|
{
|
||||||
// move
|
// move
|
||||||
T *theend = m_Data + m_CurrentUsedSize;
|
memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1);
|
||||||
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
|
|
||||||
*(ptr - 1) = *ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--m_CurrentUsedSize;
|
--m_CurrentUsedSize;
|
||||||
|
// :TODO: free memory sometimes
|
||||||
FreeMemIfPossible();
|
|
||||||
|
|
||||||
return begin() + ofs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
m_Size = 0;
|
m_Size = 0;
|
||||||
m_CurrentUsedSize = 0;
|
m_CurrentUsedSize = 0;
|
||||||
if (m_Data)
|
delete [] m_Data;
|
||||||
{
|
m_Data = NULL;
|
||||||
delete [] m_Data;
|
|
||||||
m_Data = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,38 +1,27 @@
|
|||||||
#(C)2004-2005 AMX Mod X Development Team
|
#(C)2004-2005 AMX Mod X Development Team
|
||||||
# Makefile written by David "BAILOPAN" Anderson
|
# Makefile written by David "BAILOPAN" Anderson
|
||||||
|
|
||||||
HLSDK = ../../hlsdk
|
HLSDK = ../hlsdk/SourceCode
|
||||||
MM_ROOT = ../metamod/metamod
|
MM_ROOT = ../metamod/metamod
|
||||||
|
|
||||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||||
|
|
||||||
OPT_FLAGS = -O2 -fno-strict-aliasing -funroll-loops -s -fomit-frame-pointer -pipe
|
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
|
||||||
DEBUG_FLAGS = -g -ggdb3
|
DEBUG_FLAGS = -g -ggdb3
|
||||||
CPP = gcc-4.1
|
CPP = gcc
|
||||||
NAME = amxmodx
|
NAME = amxmodx_mm
|
||||||
|
|
||||||
BIN_SUFFIX_32 = mm_i386.so
|
|
||||||
BIN_SUFFIX_64 = mm_amd64.so
|
|
||||||
|
|
||||||
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
||||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
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 \
|
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 \
|
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 debugger.cpp \
|
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp \
|
||||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
|
||||||
amxmod_compat.cpp nongpl_matches.cpp
|
|
||||||
|
|
||||||
LINK = -lgcc -static-libgcc
|
LINK = -lz
|
||||||
|
|
||||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
||||||
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
||||||
|
|
||||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
|
||||||
|
|
||||||
ifeq "$(GCC_VERSION)" "4"
|
|
||||||
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(DEBUG)" "true"
|
ifeq "$(DEBUG)" "true"
|
||||||
BIN_DIR = Debug
|
BIN_DIR = Debug
|
||||||
CFLAGS = $(DEBUG_FLAGS)
|
CFLAGS = $(DEBUG_FLAGS)
|
||||||
@ -41,27 +30,22 @@ else
|
|||||||
CFLAGS = $(OPT_FLAGS)
|
CFLAGS = $(OPT_FLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(BINLOG)" "true"
|
ifeq "$(MMGR)" "true"
|
||||||
NAME := $(NAME)_bl
|
OBJECTS += MMGR/MMGR.CPP
|
||||||
BIN_DIR := $(BIN_DIR)BinLog
|
|
||||||
OBJECTS += binlog.cpp
|
|
||||||
CFLAGS += -DBINLOG_ENABLED
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -DLINUX -DNDEBUG -DAMX_NOPROPLIST -fPIC -Wall -Werror -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
|
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H
|
||||||
|
|
||||||
ifeq "$(AMD64)" "true"
|
ifeq "$(AMD64)" "true"
|
||||||
BINARY = $(NAME)_$(BIN_SUFFIX_64)
|
BINARY = $(NAME)_amd64.so
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64
|
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
|
||||||
LINK += -lz64
|
|
||||||
OBJECTS += JIT/natives-amd64.o
|
OBJECTS += JIT/natives-amd64.o
|
||||||
|
LINK += -lstdc++
|
||||||
else
|
else
|
||||||
BINARY = $(NAME)_$(BIN_SUFFIX_32)
|
BINARY = $(NAME)_i386.so
|
||||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
||||||
OBJECTS += JIT/helpers-x86.o
|
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||||
LINK += -lz
|
OPT_FLAGS += -march=i686
|
||||||
OPT_FLAGS += -march=i586
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||||
@ -77,23 +61,23 @@ amd64:
|
|||||||
rm -f zlib/libz.a
|
rm -f zlib/libz.a
|
||||||
$(MAKE) all AMD64=true
|
$(MAKE) all AMD64=true
|
||||||
|
|
||||||
|
amd64_mmgr:
|
||||||
|
rm -f zlib/libz.a
|
||||||
|
$(MAKE) all AMD64=true MMGR=true
|
||||||
|
|
||||||
|
amd64_debug_mmgr:
|
||||||
|
rm -f zlib/libz.a
|
||||||
|
$(MAKE) all AMD64=true DEBUG=true MMGR=true
|
||||||
|
|
||||||
amd64_debug:
|
amd64_debug:
|
||||||
rm -f zlib/libz.a
|
rm -f zlib/libz.a
|
||||||
$(MAKE) all AMD64=true DEBUG=true
|
$(MAKE) all AMD64=true DEBUG=true
|
||||||
|
|
||||||
amd64_binlog:
|
mmgr:
|
||||||
rm -f zlib/libz.a
|
$(MAKE) all MMGR=true
|
||||||
$(MAKE) all AMD64=true BINLOG=true
|
|
||||||
|
|
||||||
amd64_binlog_debug:
|
debug_mmgr:
|
||||||
rm -f zlib/libz.a
|
$(MAKE) all MMGR=true DEBUG=true
|
||||||
$(MAKE) all AMD64=true BINLOG=true DEBUG=true
|
|
||||||
|
|
||||||
binlog:
|
|
||||||
$(MAKE) all BINLOG=true
|
|
||||||
|
|
||||||
binlog_debug:
|
|
||||||
$(MAKE) all BINLOG=true DEBUG=true
|
|
||||||
|
|
||||||
amxmodx: $(OBJ_LINUX)
|
amxmodx: $(OBJ_LINUX)
|
||||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||||
@ -105,14 +89,7 @@ default: all
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf Release/*.o
|
rm -rf Release/*.o
|
||||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX_32)
|
rm -rf Release/$(BINARY)
|
||||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX_64)
|
|
||||||
rm -rf ReleaseBinLog/*.o
|
|
||||||
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
|
|
||||||
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
|
|
||||||
rm -rf Debug/*.o
|
rm -rf Debug/*.o
|
||||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_32)
|
rm -rf Debug/$(BINARY)
|
||||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_64)
|
|
||||||
rm -rf DebugBinLog/*.o
|
|
||||||
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
|
|
||||||
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
|
|
||||||
|
515
amxmodx/amx.cpp
515
amxmodx/amx.cpp
@ -10,7 +10,7 @@
|
|||||||
* including commercial applications, and to alter it and redistribute it
|
* including commercial applications, and to alter it and redistribute it
|
||||||
* freely, subject to the following restrictions:
|
* freely, subject to the following restrictions:
|
||||||
*
|
*
|
||||||
* 1. The origin of this software must not be misreprfesented; you must not
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
* claim that you wrote the original software. If you use this software in
|
* claim that you wrote the original software. If you use this software in
|
||||||
* a product, an acknowledgment in the product documentation would be
|
* a product, an acknowledgment in the product documentation would be
|
||||||
* appreciated but is not required.
|
* appreciated but is not required.
|
||||||
@ -22,9 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define AMX_NODYNALOAD
|
#define AMX_NODYNALOAD
|
||||||
#define AMX_ANSIONLY
|
#define AMX_ANSIONLY
|
||||||
|
|
||||||
#if !defined __linux__ && BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64
|
#if BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64
|
||||||
/* bad bad workaround but we have to prevent a compiler crash :/ */
|
/* bad bad workaround but we have to prevent a compiler crash :/ */
|
||||||
#pragma optimize("g",off)
|
#pragma optimize("g",off)
|
||||||
#endif
|
#endif
|
||||||
@ -46,7 +46,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
|
||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
@ -266,13 +265,6 @@ typedef enum {
|
|||||||
OP_SYSREQ_D,
|
OP_SYSREQ_D,
|
||||||
OP_SYMTAG, /* obsolete */
|
OP_SYMTAG, /* obsolete */
|
||||||
OP_BREAK,
|
OP_BREAK,
|
||||||
OP_FLOAT_MUL,
|
|
||||||
OP_FLOAT_DIV,
|
|
||||||
OP_FLOAT_ADD,
|
|
||||||
OP_FLOAT_SUB,
|
|
||||||
OP_FLOAT_TO,
|
|
||||||
OP_FLOAT_ROUND,
|
|
||||||
OP_FLOAT_CMP,
|
|
||||||
/* ----- */
|
/* ----- */
|
||||||
OP_NUM_OPCODES
|
OP_NUM_OPCODES
|
||||||
} OPCODE;
|
} OPCODE;
|
||||||
@ -433,7 +425,10 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
|||||||
AMX_FUNCSTUB *func;
|
AMX_FUNCSTUB *func;
|
||||||
AMX_NATIVE f;
|
AMX_NATIVE f;
|
||||||
|
|
||||||
|
assert(amx!=NULL);
|
||||||
hdr=(AMX_HEADER *)amx->base;
|
hdr=(AMX_HEADER *)amx->base;
|
||||||
|
assert(hdr!=NULL);
|
||||||
|
assert(hdr->magic==AMX_MAGIC);
|
||||||
assert(hdr->natives<=hdr->libraries);
|
assert(hdr->natives<=hdr->libraries);
|
||||||
#if defined AMX_NATIVETABLE
|
#if defined AMX_NATIVETABLE
|
||||||
if (index<NULL) {
|
if (index<NULL) {
|
||||||
@ -449,10 +444,34 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
|||||||
#endif
|
#endif
|
||||||
assert(f!=NULL);
|
assert(f!=NULL);
|
||||||
|
|
||||||
/* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
|
/* Now that we have found the function, patch the program so that any
|
||||||
* Otherwise, we'd have no way of knowing the last native to be used.
|
* 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.
|
||||||
*/
|
*/
|
||||||
amx->usertags[UT_NATIVE] = (void *)index;
|
#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 */
|
||||||
|
|
||||||
/* Note:
|
/* Note:
|
||||||
* params[0] == number of bytes for the additional parameters passed to the native function
|
* params[0] == number of bytes for the additional parameters passed to the native function
|
||||||
@ -461,25 +480,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
amx->error=AMX_ERR_NONE;
|
amx->error=AMX_ERR_NONE;
|
||||||
|
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
binlogfuncs_t *logfuncs = (binlogfuncs_t *)amx->usertags[UT_BINLOGS];
|
|
||||||
if (logfuncs)
|
|
||||||
{
|
|
||||||
logfuncs->pfnLogNative(amx, index, (int)(params[0] / sizeof(cell)));
|
|
||||||
logfuncs->pfnLogParams(amx, params);
|
|
||||||
}
|
|
||||||
#endif //BINLOG_ENABLED
|
|
||||||
|
|
||||||
*result = f(amx,params);
|
*result = f(amx,params);
|
||||||
|
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
if (logfuncs)
|
|
||||||
{
|
|
||||||
logfuncs->pfnLogReturn(amx, *result);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return amx->error;
|
return amx->error;
|
||||||
}
|
}
|
||||||
#endif /* defined AMX_INIT */
|
#endif /* defined AMX_INIT */
|
||||||
@ -511,7 +512,6 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
cell cip;
|
cell cip;
|
||||||
long codesize;
|
long codesize;
|
||||||
OPCODE op;
|
OPCODE op;
|
||||||
BROWSEHOOK hook = NULL;
|
|
||||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
#if defined __GNUC__ || defined ASM32 || defined JIT
|
||||||
cell *opcode_list;
|
cell *opcode_list;
|
||||||
#endif
|
#endif
|
||||||
@ -527,7 +527,6 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
code=amx->base+(int)hdr->cod;
|
code=amx->base+(int)hdr->cod;
|
||||||
codesize=hdr->dat - hdr->cod;
|
codesize=hdr->dat - hdr->cod;
|
||||||
amx->flags|=AMX_FLAG_BROWSE;
|
amx->flags|=AMX_FLAG_BROWSE;
|
||||||
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
|
||||||
|
|
||||||
/* sanity checks */
|
/* sanity checks */
|
||||||
assert(OP_PUSH_PRI==36);
|
assert(OP_PUSH_PRI==36);
|
||||||
@ -548,7 +547,6 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
*/
|
*/
|
||||||
if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell))
|
if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell))
|
||||||
amx->sysreq_d=opcode_list[OP_SYSREQ_D];
|
amx->sysreq_d=opcode_list[OP_SYSREQ_D];
|
||||||
amx->userdata[UD_OPCODELIST] = (void *)opcode_list;
|
|
||||||
#else
|
#else
|
||||||
/* ANSI C
|
/* ANSI C
|
||||||
* to use direct system requests, a function pointer must fit in a cell;
|
* to use direct system requests, a function pointer must fit in a cell;
|
||||||
@ -556,7 +554,6 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
*/
|
*/
|
||||||
if (sizeof(AMX_NATIVE)<=sizeof(cell))
|
if (sizeof(AMX_NATIVE)<=sizeof(cell))
|
||||||
amx->sysreq_d=OP_SYSREQ_D;
|
amx->sysreq_d=OP_SYSREQ_D;
|
||||||
amx->userdata[UD_OPCODELIST] = (long)NULL;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* start browsing code */
|
/* start browsing code */
|
||||||
@ -633,22 +630,11 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
case OP_FILL:
|
case OP_FILL:
|
||||||
case OP_HALT:
|
case OP_HALT:
|
||||||
case OP_BOUNDS:
|
case OP_BOUNDS:
|
||||||
|
case OP_SYSREQ_C:
|
||||||
case OP_PUSHADDR:
|
case OP_PUSHADDR:
|
||||||
case OP_SYSREQ_D:
|
case OP_SYSREQ_D:
|
||||||
cip+=sizeof(cell);
|
cip+=sizeof(cell);
|
||||||
break;
|
break;
|
||||||
case OP_SYSREQ_C:
|
|
||||||
{
|
|
||||||
if (hook)
|
|
||||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
|
||||||
hook(amx, opcode_list, &cip);
|
|
||||||
#else
|
|
||||||
hook(amx, NULL, &cip);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
cip+=sizeof(cell);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OP_LOAD_I: /* instructions without parameters */
|
case OP_LOAD_I: /* instructions without parameters */
|
||||||
case OP_STOR_I:
|
case OP_STOR_I:
|
||||||
@ -709,13 +695,6 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
case OP_SWAP_ALT:
|
case OP_SWAP_ALT:
|
||||||
case OP_NOP:
|
case OP_NOP:
|
||||||
case OP_BREAK:
|
case OP_BREAK:
|
||||||
case OP_FLOAT_MUL:
|
|
||||||
case OP_FLOAT_DIV:
|
|
||||||
case OP_FLOAT_ADD:
|
|
||||||
case OP_FLOAT_SUB:
|
|
||||||
case OP_FLOAT_TO:
|
|
||||||
case OP_FLOAT_ROUND:
|
|
||||||
case OP_FLOAT_CMP:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CALL: /* opcodes that need relocation */
|
case OP_CALL: /* opcodes that need relocation */
|
||||||
@ -840,10 +819,22 @@ static void expand(unsigned char *code, long codesize, long memsize)
|
|||||||
}
|
}
|
||||||
#endif /* defined AMX_INIT */
|
#endif /* defined AMX_INIT */
|
||||||
|
|
||||||
int AMXAPI amx_Init(AMX *amx, void *program)
|
int AMXAPI amx_Init(AMX *amx,void *program)
|
||||||
{
|
{
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
BROWSEHOOK hook = NULL;
|
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||||
|
char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */
|
||||||
|
#if defined _Windows
|
||||||
|
typedef int (FAR WINAPI *AMX_ENTRY)(AMX _FAR *amx);
|
||||||
|
HINSTANCE hlib;
|
||||||
|
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
typedef int (*AMX_ENTRY)(AMX *amx);
|
||||||
|
void *hlib;
|
||||||
|
#endif
|
||||||
|
int numlibraries,i;
|
||||||
|
AMX_FUNCSTUB *lib;
|
||||||
|
AMX_ENTRY libinit;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((amx->flags & AMX_FLAG_RELOC)!=0)
|
if ((amx->flags & AMX_FLAG_RELOC)!=0)
|
||||||
return AMX_ERR_INIT; /* already initialized (may not do so twice) */
|
return AMX_ERR_INIT; /* already initialized (may not do so twice) */
|
||||||
@ -853,6 +844,22 @@ int AMXAPI amx_Init(AMX *amx, void *program)
|
|||||||
* multi-byte words
|
* multi-byte words
|
||||||
*/
|
*/
|
||||||
assert(check_endian());
|
assert(check_endian());
|
||||||
|
#if BYTE_ORDER==BIG_ENDIAN
|
||||||
|
amx_Align32((uint32_t*)&hdr->size);
|
||||||
|
amx_Align16(&hdr->magic);
|
||||||
|
amx_Align16((uint16_t*)&hdr->flags);
|
||||||
|
amx_Align16((uint16_t*)&hdr->defsize);
|
||||||
|
amx_Align32((uint32_t*)&hdr->cod);
|
||||||
|
amx_Align32((uint32_t*)&hdr->dat);
|
||||||
|
amx_Align32((uint32_t*)&hdr->hea);
|
||||||
|
amx_Align32((uint32_t*)&hdr->stp);
|
||||||
|
amx_Align32((uint32_t*)&hdr->cip);
|
||||||
|
amx_Align32((uint32_t*)&hdr->publics);
|
||||||
|
amx_Align32((uint32_t*)&hdr->natives);
|
||||||
|
amx_Align32((uint32_t*)&hdr->libraries);
|
||||||
|
amx_Align32((uint32_t*)&hdr->pubvars);
|
||||||
|
amx_Align32((uint32_t*)&hdr->tags);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (hdr->magic!=AMX_MAGIC)
|
if (hdr->magic!=AMX_MAGIC)
|
||||||
return AMX_ERR_FORMAT;
|
return AMX_ERR_FORMAT;
|
||||||
@ -873,7 +880,13 @@ int AMXAPI amx_Init(AMX *amx, void *program)
|
|||||||
} /* if */
|
} /* if */
|
||||||
if (hdr->stp<=0)
|
if (hdr->stp<=0)
|
||||||
return AMX_ERR_FORMAT;
|
return AMX_ERR_FORMAT;
|
||||||
|
#if BYTE_ORDER==BIG_ENDIAN
|
||||||
|
if ((hdr->flags & AMX_FLAG_COMPACT)==0) {
|
||||||
|
ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod);
|
||||||
|
while (code<(ucell *)((unsigned char *)program+(int)hdr->hea))
|
||||||
|
swapcell(code++);
|
||||||
|
} /* if */
|
||||||
|
#endif
|
||||||
assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size);
|
assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size);
|
||||||
if ((hdr->flags & AMX_FLAG_COMPACT)!=0) {
|
if ((hdr->flags & AMX_FLAG_COMPACT)!=0) {
|
||||||
#if AMX_COMPACTMARGIN > 2
|
#if AMX_COMPACTMARGIN > 2
|
||||||
@ -900,18 +913,111 @@ int AMXAPI amx_Init(AMX *amx, void *program)
|
|||||||
amx->callback=amx_Callback;
|
amx->callback=amx_Callback;
|
||||||
amx->data=NULL;
|
amx->data=NULL;
|
||||||
|
|
||||||
|
/* also align all addresses in the public function, public variable,
|
||||||
|
* public tag and native function tables --offsets into the name table
|
||||||
|
* (if present) must also be swapped.
|
||||||
|
*/
|
||||||
|
#if BYTE_ORDER==BIG_ENDIAN
|
||||||
|
{ /* local */
|
||||||
|
AMX_FUNCSTUB *fs;
|
||||||
|
int i,num;
|
||||||
|
|
||||||
|
fs=GETENTRY(hdr,natives,0);
|
||||||
|
num=NUMENTRIES(hdr,natives,libraries);
|
||||||
|
for (i=0; i<num; i++) {
|
||||||
|
amx_AlignCell(&fs->address); /* redundant, because it should be zero */
|
||||||
|
if (USENAMETABLE(hdr))
|
||||||
|
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||||
|
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
fs=GETENTRY(hdr,publics,0);
|
||||||
|
assert(hdr->publics<=hdr->natives);
|
||||||
|
num=NUMENTRIES(hdr,publics,natives);
|
||||||
|
for (i=0; i<num; i++) {
|
||||||
|
amx_AlignCell(&fs->address);
|
||||||
|
if (USENAMETABLE(hdr))
|
||||||
|
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||||
|
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
fs=GETENTRY(hdr,pubvars,0);
|
||||||
|
assert(hdr->pubvars<=hdr->tags);
|
||||||
|
num=NUMENTRIES(hdr,pubvars,tags);
|
||||||
|
for (i=0; i<num; i++) {
|
||||||
|
amx_AlignCell(&fs->address);
|
||||||
|
if (USENAMETABLE(hdr))
|
||||||
|
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||||
|
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
fs=GETENTRY(hdr,tags,0);
|
||||||
|
if (hdr->file_version<7) {
|
||||||
|
assert(hdr->tags<=hdr->cod);
|
||||||
|
num=NUMENTRIES(hdr,tags,cod);
|
||||||
|
} else {
|
||||||
|
assert(hdr->tags<=hdr->nametable);
|
||||||
|
num=NUMENTRIES(hdr,tags,nametable);
|
||||||
|
} /* if */
|
||||||
|
for (i=0; i<num; i++) {
|
||||||
|
amx_AlignCell(&fs->address);
|
||||||
|
if (USENAMETABLE(hdr))
|
||||||
|
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||||
|
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||||
|
} /* for */
|
||||||
|
} /* local */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* relocate call and jump instructions */
|
/* relocate call and jump instructions */
|
||||||
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
|
||||||
if (hook)
|
|
||||||
hook(amx, NULL, NULL);
|
|
||||||
amx_BrowseRelocate(amx);
|
amx_BrowseRelocate(amx);
|
||||||
|
|
||||||
|
/* load any extension modules that the AMX refers to */
|
||||||
|
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||||
|
hdr=(AMX_HEADER *)amx->base;
|
||||||
|
numlibraries=NUMENTRIES(hdr,libraries,pubvars);
|
||||||
|
for (i=0; i<numlibraries; i++) {
|
||||||
|
lib=GETENTRY(hdr,libraries,i);
|
||||||
|
strcpy(libname,"amx");
|
||||||
|
strcat(libname,GETENTRYNAME(hdr,lib));
|
||||||
|
#if defined _Windows
|
||||||
|
strcat(libname,".dll");
|
||||||
|
#if defined __WIN32__
|
||||||
|
hlib=LoadLibraryA(libname);
|
||||||
|
#else
|
||||||
|
hlib=LoadLibrary(libname);
|
||||||
|
if (hlib<=HINSTANCE_ERROR)
|
||||||
|
hlib=NULL;
|
||||||
|
#endif
|
||||||
|
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
strcat(libname,".so");
|
||||||
|
hlib=dlopen(libname,RTLD_NOW);
|
||||||
|
#endif
|
||||||
|
if (hlib!=NULL) {
|
||||||
|
/* a library that cannot be loaded or that does not have the required
|
||||||
|
* initialization function is simply ignored
|
||||||
|
*/
|
||||||
|
char funcname[sNAMEMAX+9]; /* +1 for '\0', +4 for 'amx_', +4 for 'Init' */
|
||||||
|
strcpy(funcname,"amx_");
|
||||||
|
strcat(funcname,GETENTRYNAME(hdr,lib));
|
||||||
|
strcat(funcname,"Init");
|
||||||
|
#if defined _Windows
|
||||||
|
libinit=(AMX_ENTRY)GetProcAddress(hlib,funcname);
|
||||||
|
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||||
|
libinit=(AMX_ENTRY)dlsym(hlib,funcname);
|
||||||
|
#endif
|
||||||
|
if (libinit!=NULL)
|
||||||
|
libinit(amx);
|
||||||
|
} /* if */
|
||||||
|
lib->address=(ucell)hlib;
|
||||||
|
} /* for */
|
||||||
|
#endif
|
||||||
|
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined JIT
|
#if defined JIT
|
||||||
|
|
||||||
#define CODESIZE_JIT 65536 /* approximate size of the code for the JIT */
|
#define CODESIZE_JIT 8192 /* approximate size of the code for the JIT */
|
||||||
|
|
||||||
#if defined __WIN32__ /* this also applies to Win32 "console" applications */
|
#if defined __WIN32__ /* this also applies to Win32 "console" applications */
|
||||||
|
|
||||||
@ -975,9 +1081,7 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
|
|||||||
|
|
||||||
/* JIT rulz! (TM) */
|
/* JIT rulz! (TM) */
|
||||||
/* MP: added check for correct compilation */
|
/* MP: added check for correct compilation */
|
||||||
//Fixed bug (thanks T(+)rget)
|
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) != 0) {
|
||||||
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0)
|
|
||||||
{
|
|
||||||
/* update the required memory size (the previous value was a
|
/* update the required memory size (the previous value was a
|
||||||
* conservative estimate, now we know the exact size)
|
* conservative estimate, now we know the exact size)
|
||||||
*/
|
*/
|
||||||
@ -990,7 +1094,6 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
|
|||||||
amx->cip = hdr->cip;
|
amx->cip = hdr->cip;
|
||||||
amx->hea = hdr->hea;
|
amx->hea = hdr->hea;
|
||||||
amx->stp = hdr->stp - sizeof(cell);
|
amx->stp = hdr->stp - sizeof(cell);
|
||||||
amx->hlw = hdr->hea;
|
|
||||||
/* also put a sentinel for strings at the top the stack */
|
/* also put a sentinel for strings at the top the stack */
|
||||||
*(cell *)((char*)native_code + hdr->dat + hdr->stp - sizeof(cell)) = 0;
|
*(cell *)((char*)native_code + hdr->dat + hdr->stp - sizeof(cell)) = 0;
|
||||||
amx->stk = amx->stp;
|
amx->stk = amx->stp;
|
||||||
@ -1177,22 +1280,27 @@ int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
|
|||||||
|
|
||||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
|
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
|
||||||
{
|
{
|
||||||
int first,last,mid;
|
int first,last,mid,result;
|
||||||
char pname[sNAMEMAX+1];
|
char pname[sNAMEMAX+1];
|
||||||
|
|
||||||
amx_NumNatives(amx, &last);
|
amx_NumNatives(amx, &last);
|
||||||
last--; /* last valid index is 1 less than the number of functions */
|
last--; /* last valid index is 1 less than the number of functions */
|
||||||
first=0;
|
first=0;
|
||||||
/* normal search */
|
/* binary search */
|
||||||
for (mid=0; mid<=last; mid++)
|
while (first<=last) {
|
||||||
{
|
mid=(first+last)/2;
|
||||||
amx_GetNative(amx, mid, pname);
|
amx_GetNative(amx, mid, pname);
|
||||||
if (strcmp(pname, name)==0)
|
result=strcmp(pname,name);
|
||||||
{
|
if (result>0) {
|
||||||
*index = mid;
|
last=mid-1;
|
||||||
|
} else if (result<0) {
|
||||||
|
first=mid+1;
|
||||||
|
} else {
|
||||||
|
*index=mid;
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* for */
|
} /* while */
|
||||||
|
/* not found, set to an invalid index, so amx_Exec() will fail */
|
||||||
*index=INT_MAX;
|
*index=INT_MAX;
|
||||||
return AMX_ERR_NOTFOUND;
|
return AMX_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
@ -1405,11 +1513,37 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
|
|||||||
#if defined AMX_XXXUSERDATA
|
#if defined AMX_XXXUSERDATA
|
||||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
|
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
|
||||||
{
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
assert(amx!=NULL);
|
||||||
|
assert(tag!=0);
|
||||||
|
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
||||||
|
/* nothing */;
|
||||||
|
if (index>=AMX_USERNUM)
|
||||||
|
return AMX_ERR_USERDATA;
|
||||||
|
*ptr=amx->userdata[index];
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
|
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
|
||||||
{
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
assert(amx!=NULL);
|
||||||
|
assert(tag!=0);
|
||||||
|
/* try to find existing tag */
|
||||||
|
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
||||||
|
/* nothing */;
|
||||||
|
/* if not found, try to find empty tag */
|
||||||
|
if (index>=AMX_USERNUM)
|
||||||
|
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=0; index++)
|
||||||
|
/* nothing */;
|
||||||
|
/* if still not found, quit with error */
|
||||||
|
if (index>=AMX_USERNUM)
|
||||||
|
return AMX_ERR_INDEX;
|
||||||
|
/* set the tag and the value */
|
||||||
|
amx->usertags[index]=tag;
|
||||||
|
amx->userdata[index]=ptr;
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
#endif /* AMX_XXXUSERDATA */
|
#endif /* AMX_XXXUSERDATA */
|
||||||
@ -1427,91 +1561,6 @@ static AMX_NATIVE findfunction(const char *name, const AMX_NATIVE_INFO *list, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *no_function;
|
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_Reregister(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
|
||||||
{
|
|
||||||
AMX_FUNCSTUB *func;
|
|
||||||
AMX_HEADER *hdr;
|
|
||||||
int i,numnatives,count=0;
|
|
||||||
AMX_NATIVE funcptr;
|
|
||||||
|
|
||||||
hdr=(AMX_HEADER *)amx->base;
|
|
||||||
assert(hdr!=NULL);
|
|
||||||
assert(hdr->magic==AMX_MAGIC);
|
|
||||||
assert(hdr->natives<=hdr->libraries);
|
|
||||||
numnatives=NUMENTRIES(hdr,natives,libraries);
|
|
||||||
|
|
||||||
count=0;
|
|
||||||
func=GETENTRY(hdr,natives,0);
|
|
||||||
for (i=0; i<numnatives; i++) {
|
|
||||||
if (func->address!=0) {
|
|
||||||
/* this function is located */
|
|
||||||
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
|
|
||||||
if (funcptr!=NULL)
|
|
||||||
{
|
|
||||||
func->address=(ucell)funcptr;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
} /* if */
|
|
||||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
|
||||||
} /* for */
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
||||||
{
|
{
|
||||||
AMX_FUNCSTUB *func;
|
AMX_FUNCSTUB *func;
|
||||||
@ -1532,12 +1581,12 @@ int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
|||||||
/* this function is not yet located */
|
/* this function is not yet located */
|
||||||
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
|
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
|
||||||
if (funcptr!=NULL)
|
if (funcptr!=NULL)
|
||||||
{
|
{
|
||||||
func->address=(ucell)funcptr;
|
func->address=(ucell)funcptr;
|
||||||
} else {
|
} else {
|
||||||
no_function = GETENTRYNAME(hdr,func);
|
no_function = GETENTRYNAME(hdr,func);
|
||||||
err=AMX_ERR_NOTFOUND;
|
err=AMX_ERR_NOTFOUND;
|
||||||
}
|
}
|
||||||
} /* if */
|
} /* if */
|
||||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
||||||
} /* for */
|
} /* for */
|
||||||
@ -1625,13 +1674,7 @@ int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char
|
|||||||
#define SKIPPARAM(n) ( cip=(cell *)cip+(n) )
|
#define SKIPPARAM(n) ( cip=(cell *)cip+(n) )
|
||||||
#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||||
#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
||||||
#define ABORT(amx,v) { (amx)->stk=reset_stk; \
|
#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; }
|
||||||
(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 CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR
|
||||||
#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW
|
#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW
|
||||||
@ -1681,16 +1724,13 @@ static const void * const amx_opcodelist[] = {
|
|||||||
&&op_file, &&op_line, &&op_symbol, &&op_srange,
|
&&op_file, &&op_line, &&op_symbol, &&op_srange,
|
||||||
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
|
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
|
||||||
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
|
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
|
||||||
&&op_symtag, &&op_break, &&op_float_mul, &&op_float_div,
|
&&op_symtag, &&op_break };
|
||||||
&&op_float_add, &&op_float_sub, &&op_float_to, &&op_float_round,
|
|
||||||
&&op_float_cmp};
|
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
AMX_FUNCSTUB *func;
|
AMX_FUNCSTUB *func;
|
||||||
unsigned char *code, *data;
|
unsigned char *code, *data;
|
||||||
cell pri,alt,stk,frm,hea;
|
cell pri,alt,stk,frm,hea;
|
||||||
cell reset_stk, reset_hea, *cip;
|
cell reset_stk, reset_hea, *cip;
|
||||||
cell offs, offs2;
|
cell offs;
|
||||||
REAL fnum, fnum2;
|
|
||||||
ucell codesize;
|
ucell codesize;
|
||||||
int num,i;
|
int num,i;
|
||||||
|
|
||||||
@ -2429,8 +2469,6 @@ static const void * const amx_opcodelist[] = {
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
if (num==AMX_ERR_SLEEP) {
|
if (num==AMX_ERR_SLEEP) {
|
||||||
@ -2450,8 +2488,6 @@ static const void * const amx_opcodelist[] = {
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
if (num==AMX_ERR_SLEEP) {
|
if (num==AMX_ERR_SLEEP) {
|
||||||
@ -2471,8 +2507,6 @@ static const void * const amx_opcodelist[] = {
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
||||||
if (amx->error!=AMX_ERR_NONE) {
|
if (amx->error!=AMX_ERR_NONE) {
|
||||||
if (amx->error==AMX_ERR_SLEEP) {
|
if (amx->error==AMX_ERR_SLEEP) {
|
||||||
@ -2536,67 +2570,12 @@ static const void * const amx_opcodelist[] = {
|
|||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_nop:
|
op_nop:
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_float_mul:
|
op_break:
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) * amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_add:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) + amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_sub:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) - amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_div:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) / amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_to:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
fnum = (REAL)offs;
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_round:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs);
|
|
||||||
if (!offs2)
|
|
||||||
fnum = floor(fnum + 0.5);
|
|
||||||
else if (offs2 == 1)
|
|
||||||
fnum = floor(fnum);
|
|
||||||
else
|
|
||||||
fnum = ceil(fnum);
|
|
||||||
pri = (cell)fnum;
|
|
||||||
NEXT(cip);
|
|
||||||
op_float_cmp:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs);
|
|
||||||
fnum2 = amx_ctof(offs2);
|
|
||||||
if (fnum == fnum2)
|
|
||||||
pri = 0;
|
|
||||||
else if (fnum > fnum2)
|
|
||||||
pri = 1;
|
|
||||||
else
|
|
||||||
pri = -1;
|
|
||||||
NEXT(cip);
|
|
||||||
op_break:
|
|
||||||
if (amx->debug!=NULL) {
|
if (amx->debug!=NULL) {
|
||||||
/* store status */
|
/* store status */
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
amx->cip=(cell)((unsigned char*)cip-code);
|
amx->cip=(cell)((unsigned char*)cip-code);
|
||||||
num=amx->debug(amx);
|
num=amx->debug(amx);
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
@ -2673,8 +2652,7 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
cell parms[9]; /* registers and parameters for assembler AMX */
|
cell parms[9]; /* registers and parameters for assembler AMX */
|
||||||
#else
|
#else
|
||||||
OPCODE op;
|
OPCODE op;
|
||||||
cell offs, offs2;
|
cell offs;
|
||||||
REAL fnum, fnum2;
|
|
||||||
int num;
|
int num;
|
||||||
#endif
|
#endif
|
||||||
assert(amx!=NULL);
|
assert(amx!=NULL);
|
||||||
@ -3465,8 +3443,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
if (num==AMX_ERR_SLEEP) {
|
if (num==AMX_ERR_SLEEP) {
|
||||||
@ -3486,8 +3462,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
if (num==AMX_ERR_SLEEP) {
|
if (num==AMX_ERR_SLEEP) {
|
||||||
@ -3507,8 +3481,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
|
||||||
if (amx->error!=AMX_ERR_NONE) {
|
if (amx->error!=AMX_ERR_NONE) {
|
||||||
if (amx->error==AMX_ERR_SLEEP) {
|
if (amx->error==AMX_ERR_SLEEP) {
|
||||||
@ -3565,59 +3537,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
break;
|
break;
|
||||||
case OP_NOP:
|
case OP_NOP:
|
||||||
break;
|
break;
|
||||||
case OP_FLOAT_MUL:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) * amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_ADD:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) + amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_SUB:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) - amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_DIV:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs) / amx_ctof(offs2);
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_TO:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
fnum = (float)offs;
|
|
||||||
pri = amx_ftoc(fnum);
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_ROUND:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs);
|
|
||||||
if (!offs2)
|
|
||||||
fnum = (REAL)floor(fnum + 0.5);
|
|
||||||
else if (offs2 == 1)
|
|
||||||
fnum = floor(fnum);
|
|
||||||
else
|
|
||||||
fnum = ceil(fnum);
|
|
||||||
pri = (cell)fnum;
|
|
||||||
break;
|
|
||||||
case OP_FLOAT_CMP:
|
|
||||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
|
||||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
|
||||||
fnum = amx_ctof(offs);
|
|
||||||
fnum2 = amx_ctof(offs2);
|
|
||||||
if (fnum == fnum2)
|
|
||||||
pri = 0;
|
|
||||||
else if (fnum > fnum2)
|
|
||||||
pri = 1;
|
|
||||||
else
|
|
||||||
pri = -1;
|
|
||||||
break;
|
|
||||||
case OP_BREAK:
|
case OP_BREAK:
|
||||||
assert((amx->flags & AMX_FLAG_BROWSE)==0);
|
assert((amx->flags & AMX_FLAG_BROWSE)==0);
|
||||||
if (amx->debug!=NULL) {
|
if (amx->debug!=NULL) {
|
||||||
@ -3625,8 +3544,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
|||||||
amx->frm=frm;
|
amx->frm=frm;
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
amx->hea=hea;
|
amx->hea=hea;
|
||||||
amx->pri=pri;
|
|
||||||
amx->alt=alt;
|
|
||||||
amx->cip=(cell)((unsigned char*)cip-code);
|
amx->cip=(cell)((unsigned char*)cip-code);
|
||||||
num=amx->debug(amx);
|
num=amx->debug(amx);
|
||||||
if (num!=AMX_ERR_NONE) {
|
if (num!=AMX_ERR_NONE) {
|
||||||
|
@ -79,6 +79,15 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#endif
|
||||||
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||||
|
#if !defined alloca
|
||||||
|
#define alloca(n) _alloca(n)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined arraysize
|
#if !defined arraysize
|
||||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||||
#endif
|
#endif
|
||||||
@ -157,7 +166,6 @@ typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
|||||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||||
cell *result, cell *params);
|
cell *result, cell *params);
|
||||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||||
typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
|
||||||
#if !defined _FAR
|
#if !defined _FAR
|
||||||
#define _FAR
|
#define _FAR
|
||||||
#endif
|
#endif
|
||||||
@ -166,14 +174,6 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
|||||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||||
* about pragma pack in a header file */
|
* about pragma pack in a header file */
|
||||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
|
|
||||||
#define stricmp _stricmp
|
|
||||||
|
|
||||||
// Need this because of some stupid bug
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||||
@ -214,7 +214,7 @@ typedef struct tagAMX_NATIVE_INFO {
|
|||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
ucell address PACKED;
|
ucell address PACKED;
|
||||||
char name[sEXPMAX+1];
|
char name[sEXPMAX+1] PACKED;
|
||||||
} PACKED AMX_FUNCSTUB;
|
} PACKED AMX_FUNCSTUB;
|
||||||
|
|
||||||
typedef struct tagFUNCSTUBNT {
|
typedef struct tagFUNCSTUBNT {
|
||||||
@ -239,10 +239,9 @@ typedef struct tagAMX {
|
|||||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||||
int flags PACKED; /* current status, see amx_Flags() */
|
int flags PACKED; /* current status, see amx_Flags() */
|
||||||
/* user data */
|
/* user data */
|
||||||
void _FAR *usertags[AMX_USERNUM] PACKED;
|
long usertags[AMX_USERNUM] PACKED;
|
||||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||||
//we're also gonna set userdata[2] to a special debug structure
|
//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;
|
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||||
/* native functions can raise an error */
|
/* native functions can raise an error */
|
||||||
int error PACKED;
|
int error PACKED;
|
||||||
@ -265,8 +264,8 @@ typedef struct tagAMX {
|
|||||||
typedef struct tagAMX_HEADER {
|
typedef struct tagAMX_HEADER {
|
||||||
int32_t size PACKED; /* size of the "file" */
|
int32_t size PACKED; /* size of the "file" */
|
||||||
uint16_t magic PACKED; /* signature */
|
uint16_t magic PACKED; /* signature */
|
||||||
char file_version; /* file format version */
|
char file_version PACKED; /* file format version */
|
||||||
char amx_version; /* required version of the AMX */
|
char amx_version PACKED; /* required version of the AMX */
|
||||||
int16_t flags PACKED;
|
int16_t flags PACKED;
|
||||||
int16_t defsize PACKED; /* size of a definition record */
|
int16_t defsize PACKED; /* size of a definition record */
|
||||||
int32_t cod PACKED; /* initial value of COD - code block */
|
int32_t cod PACKED; /* initial value of COD - code block */
|
||||||
@ -301,7 +300,6 @@ enum {
|
|||||||
AMX_ERR_DIVIDE, /* divide by zero */
|
AMX_ERR_DIVIDE, /* divide by zero */
|
||||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||||
AMX_ERR_INVNATIVE, /* invalid native was used */
|
|
||||||
|
|
||||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||||
AMX_ERR_FORMAT, /* invalid file format */
|
AMX_ERR_FORMAT, /* invalid file format */
|
||||||
@ -322,7 +320,6 @@ enum {
|
|||||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||||
#define AMX_FLAG_OLDFILE 0x20 /* Old AMX Mod plugin */
|
|
||||||
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
|
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
|
||||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||||
@ -338,16 +335,23 @@ enum {
|
|||||||
#define AMX_COMPACTMARGIN 64
|
#define AMX_COMPACTMARGIN 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UD_FINDPLUGIN 3
|
struct amx_trace
|
||||||
#define UD_DEBUGGER 2
|
{
|
||||||
#define UD_OPCODELIST 1
|
cell frm;
|
||||||
#define UD_HANDLER 0
|
amx_trace *prev;
|
||||||
#define UT_NATIVE 3
|
amx_trace *next;
|
||||||
#define UT_OPTIMIZER 2
|
bool used;
|
||||||
#define UT_BROWSEHOOK 1
|
};
|
||||||
#define UT_BINLOGS 0
|
|
||||||
|
|
||||||
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
/* for native functions that use floating point parameters, the following
|
/* for native functions that use floating point parameters, the following
|
||||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||||
@ -381,7 +385,6 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
|||||||
#endif
|
#endif
|
||||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
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_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_Cleanup(AMX *amx);
|
||||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||||
@ -411,8 +414,6 @@ 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_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_RaiseError(AMX *amx, int error);
|
||||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||||
int AMXAPI amx_Reregister(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_Release(AMX *amx, cell amx_addr);
|
||||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||||
@ -451,15 +452,6 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
typedef struct tagBINLOG
|
|
||||||
{
|
|
||||||
void (*pfnLogNative)(AMX *amx, int native, int params);
|
|
||||||
void (*pfnLogReturn)(AMX *amx, cell retval);
|
|
||||||
void (*pfnLogParams)(AMX *amx, cell *params);
|
|
||||||
} binlogfuncs_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,8 +65,8 @@ extern "C" {
|
|||||||
typedef struct tagAMX_DBG_HDR {
|
typedef struct tagAMX_DBG_HDR {
|
||||||
int32_t size PACKED; /* size of the debug information chunk */
|
int32_t size PACKED; /* size of the debug information chunk */
|
||||||
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
||||||
char file_version; /* file format version */
|
char file_version PACKED; /* file format version */
|
||||||
char amx_version; /* required version of the AMX */
|
char amx_version PACKED; /* required version of the AMX */
|
||||||
int16_t flags PACKED; /* currently unused */
|
int16_t flags PACKED; /* currently unused */
|
||||||
int16_t files PACKED; /* number of entries in the "file" table */
|
int16_t files PACKED; /* number of entries in the "file" table */
|
||||||
int16_t lines PACKED; /* number of entries in the "line" table */
|
int16_t lines PACKED; /* number of entries in the "line" table */
|
||||||
@ -74,51 +74,51 @@ typedef struct tagAMX_DBG_HDR {
|
|||||||
int16_t tags PACKED; /* number of entries in the "tag" table */
|
int16_t tags PACKED; /* number of entries in the "tag" table */
|
||||||
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
||||||
int16_t states PACKED; /* number of entries in the "state" table */
|
int16_t states PACKED; /* number of entries in the "state" table */
|
||||||
} PACKED AMX_DBG_HDR;
|
} AMX_DBG_HDR PACKED;
|
||||||
#define AMX_DBG_MAGIC 0xf1ef
|
#define AMX_DBG_MAGIC 0xf1ef
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_FILE {
|
typedef struct tagAMX_DBG_FILE {
|
||||||
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
} PACKED AMX_DBG_FILE;
|
} AMX_DBG_FILE PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_LINE {
|
typedef struct tagAMX_DBG_LINE {
|
||||||
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
||||||
int32_t line PACKED; /* line number */
|
int32_t line PACKED; /* line number */
|
||||||
} PACKED AMX_DBG_LINE;
|
} AMX_DBG_LINE PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMBOL {
|
typedef struct tagAMX_DBG_SYMBOL {
|
||||||
ucell address PACKED; /* address in the data segment or relative to the frame */
|
ucell address PACKED; /* address in the data segment or relative to the frame */
|
||||||
int16_t tag PACKED; /* tag for the symbol */
|
int16_t tag PACKED; /* tag for the symbol */
|
||||||
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
||||||
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
||||||
char ident; /* kind of symbol (function/variable) */
|
char ident PACKED; /* kind of symbol (function/variable) */
|
||||||
char vclass; /* class of symbol (global/local) */
|
char vclass PACKED; /* class of symbol (global/local) */
|
||||||
int16_t dim PACKED; /* number of dimensions */
|
int16_t dim PACKED; /* number of dimensions */
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
} PACKED AMX_DBG_SYMBOL;
|
} AMX_DBG_SYMBOL PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMDIM {
|
typedef struct tagAMX_DBG_SYMDIM {
|
||||||
int16_t tag PACKED; /* tag for the array dimension */
|
int16_t tag PACKED; /* tag for the array dimension */
|
||||||
ucell size PACKED; /* size of the array dimension */
|
ucell size PACKED; /* size of the array dimension */
|
||||||
} PACKED AMX_DBG_SYMDIM;
|
} AMX_DBG_SYMDIM PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_TAG {
|
typedef struct tagAMX_DBG_TAG {
|
||||||
int16_t tag PACKED; /* tag id */
|
int16_t tag PACKED; /* tag id */
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
} PACKED AMX_DBG_TAG;
|
} AMX_DBG_TAG PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_MACHINE {
|
typedef struct tagAMX_DBG_MACHINE {
|
||||||
int16_t automaton PACKED; /* automaton id */
|
int16_t automaton PACKED; /* automaton id */
|
||||||
ucell address PACKED; /* address of state variable */
|
ucell address PACKED; /* address of state variable */
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
} PACKED AMX_DBG_MACHINE;
|
} AMX_DBG_MACHINE PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_STATE {
|
typedef struct tagAMX_DBG_STATE {
|
||||||
int16_t state PACKED; /* state id */
|
int16_t state PACKED; /* state id */
|
||||||
int16_t automaton PACKED; /* automaton id */
|
int16_t automaton PACKED; /* automaton id */
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||||
} PACKED AMX_DBG_STATE;
|
} AMX_DBG_STATE PACKED;
|
||||||
|
|
||||||
typedef struct tagAMX_DBG {
|
typedef struct tagAMX_DBG {
|
||||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
||||||
@ -128,7 +128,7 @@ typedef struct tagAMX_DBG {
|
|||||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
||||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
||||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
AMX_DBG_STATE _FAR **statetbl PACKED;
|
||||||
} PACKED AMX_DBG;
|
} AMX_DBG PACKED;
|
||||||
|
|
||||||
#if !defined iVARIABLE
|
#if !defined iVARIABLE
|
||||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||||
|
@ -56,8 +56,6 @@
|
|||||||
;
|
;
|
||||||
;History (list of changes)
|
;History (list of changes)
|
||||||
;-------------------------
|
;-------------------------
|
||||||
; 10 february 2006 by David Anderson
|
|
||||||
; Addition of float opcodes
|
|
||||||
; 17 february 2005 by Thiadmer Riemersms
|
; 17 february 2005 by Thiadmer Riemersms
|
||||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
||||||
; 6 march 2004 by Thiadmer Riemersma
|
; 6 march 2004 by Thiadmer Riemersma
|
||||||
@ -131,28 +129,6 @@
|
|||||||
jg near err_stack
|
jg near err_stack
|
||||||
%endmacro
|
%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
|
%macro _CHKHEAP 0
|
||||||
mov ebp,amx
|
mov ebp,amx
|
||||||
mov ebp,[ebp+_hlw]
|
mov ebp,[ebp+_hlw]
|
||||||
@ -1220,7 +1196,8 @@ OP_HALT:
|
|||||||
mov eax,esi ; EAX=CIP
|
mov eax,esi ; EAX=CIP
|
||||||
sub eax,code
|
sub eax,code
|
||||||
mov [ebp+_cip],eax
|
mov [ebp+_cip],eax
|
||||||
_ABORT ebx
|
mov eax,ebx ; return the parameter of the HALT opcode
|
||||||
|
jmp _return
|
||||||
|
|
||||||
|
|
||||||
OP_BOUNDS:
|
OP_BOUNDS:
|
||||||
@ -1244,7 +1221,6 @@ OP_SYSREQ_PRI:
|
|||||||
mov alt,edx ; save ALT
|
mov alt,edx ; save ALT
|
||||||
|
|
||||||
mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM)
|
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 ecx,hea
|
||||||
mov ebx,frm
|
mov ebx,frm
|
||||||
mov [ebp+_hea],ecx
|
mov [ebp+_hea],ecx
|
||||||
@ -1275,7 +1251,8 @@ OP_SYSREQ_PRI:
|
|||||||
pop edi ; restore saved registers
|
pop edi ; restore saved registers
|
||||||
pop esi
|
pop esi
|
||||||
pop ebp
|
pop ebp
|
||||||
_CHKABORT eax ; if result was invalid, leave
|
cmp eax,AMX_ERR_NONE
|
||||||
|
jne near _return ; return error code, if any
|
||||||
|
|
||||||
mov eax,pri ; get retval into eax (PRI)
|
mov eax,pri ; get retval into eax (PRI)
|
||||||
mov edx,alt ; restore ALT
|
mov edx,alt ; restore ALT
|
||||||
@ -1316,8 +1293,8 @@ OP_SYSREQ_D: ; (TR)
|
|||||||
pop edi ; restore saved registers
|
pop edi ; restore saved registers
|
||||||
pop esi
|
pop esi
|
||||||
pop ebp
|
pop ebp
|
||||||
mov eax,[ebp+_error]
|
cmp DWORD [ebp+_error],AMX_ERR_NONE
|
||||||
_CHKABORT eax
|
jne near _return ; return error code, if any
|
||||||
|
|
||||||
; function result is in eax (PRI)
|
; function result is in eax (PRI)
|
||||||
mov edx,alt ; restore ALT
|
mov edx,alt ; restore ALT
|
||||||
@ -1407,110 +1384,8 @@ OP_PUSHADDR:
|
|||||||
OP_NOP:
|
OP_NOP:
|
||||||
add esi,4
|
add esi,4
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_FLOAT_MUL:
|
|
||||||
add esi,4
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
fmul dword [edi+ecx+8]
|
|
||||||
sub esp,4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_DIV:
|
|
||||||
add esi,4
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
fdiv dword [edi+ecx+8]
|
|
||||||
sub esp,4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_ADD:
|
|
||||||
add esi,4
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
fadd dword [edi+ecx+8]
|
|
||||||
sub esp,4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_SUB:
|
|
||||||
add esi,4
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
fsub dword [edi+ecx+8]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_TO:
|
|
||||||
add esi,4
|
|
||||||
fild dword [edi+ecx+4]
|
|
||||||
sub esp,4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_ROUND:
|
|
||||||
add esi,4
|
|
||||||
;get the float control word
|
|
||||||
push 0
|
|
||||||
mov ebp,esp
|
|
||||||
fstcw [ebp]
|
|
||||||
mov eax,[ebp]
|
|
||||||
push eax
|
|
||||||
;clear the top bits
|
|
||||||
xor ah,ah
|
|
||||||
;get the control method
|
|
||||||
push edx
|
|
||||||
mov edx,[edi+ecx+8]
|
|
||||||
and edx,3 ;sanity check
|
|
||||||
shl edx,2 ;shift it to right position
|
|
||||||
;set the bits
|
|
||||||
or ah,dl ;set bits 15,14 of FCW to rounding method
|
|
||||||
or ah,3 ;set precision to 64bit
|
|
||||||
mov [ebp], eax
|
|
||||||
fldcw [ebp]
|
|
||||||
;calculate
|
|
||||||
sub esp,4
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
test edx,edx
|
|
||||||
jz .correct
|
|
||||||
jmp .skip_correct
|
|
||||||
.correct:
|
|
||||||
fadd st0
|
|
||||||
fadd dword [g_round_nearest]
|
|
||||||
fistp dword [esp]
|
|
||||||
pop eax
|
|
||||||
sar eax,1
|
|
||||||
jmp .done
|
|
||||||
.skip_correct:
|
|
||||||
frndint
|
|
||||||
fistp dword [esp]
|
|
||||||
pop eax
|
|
||||||
.done:
|
|
||||||
pop edx
|
|
||||||
;restore bits
|
|
||||||
pop ebp
|
|
||||||
mov [esp], ebp
|
|
||||||
fldcw [esp]
|
|
||||||
pop ebp
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_FLOAT_CMP:
|
|
||||||
add esi, 4
|
|
||||||
fld dword [edi+ecx+8]
|
|
||||||
fld dword [edi+ecx+4]
|
|
||||||
fucompp
|
|
||||||
fnstsw ax
|
|
||||||
fwait
|
|
||||||
sahf
|
|
||||||
cmovz eax, [g_flags+4]
|
|
||||||
cmova eax, [g_flags+8]
|
|
||||||
cmovb eax, [g_flags+0]
|
|
||||||
GO_ON
|
|
||||||
|
|
||||||
OP_BREAK:
|
OP_BREAK:
|
||||||
mov ebp,amx ; get amx into ebp
|
mov ebp,amx ; get amx into ebp
|
||||||
add esi,4
|
add esi,4
|
||||||
@ -1541,7 +1416,7 @@ OP_BREAK:
|
|||||||
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
||||||
_RESTOREREGS ; abort run, but restore stack first
|
_RESTOREREGS ; abort run, but restore stack first
|
||||||
mov eax,[ebp+_error] ; get error code in EAX back again
|
mov eax,[ebp+_error] ; get error code in EAX back again
|
||||||
_FASTABORT
|
jmp _return ; return error code
|
||||||
break_noabort:
|
break_noabort:
|
||||||
_RESTOREREGS
|
_RESTOREREGS
|
||||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||||
@ -1550,34 +1425,43 @@ OP_BREAK:
|
|||||||
|
|
||||||
|
|
||||||
OP_INVALID:
|
OP_INVALID:
|
||||||
_ABORT AMX_ERR_INVINSTR
|
mov eax,AMX_ERR_INVINSTR
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_call:
|
err_call:
|
||||||
_ABORT AMX_ERR_CALLBACK
|
mov eax,AMX_ERR_CALLBACK
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_stack:
|
err_stack:
|
||||||
_ABORT AMX_ERR_STACKERR
|
mov eax,AMX_ERR_STACKERR
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_stacklow:
|
err_stacklow:
|
||||||
_ABORT AMX_ERR_STACKLOW
|
mov eax,AMX_ERR_STACKLOW
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_memaccess:
|
err_memaccess:
|
||||||
_ABORT AMX_ERR_MEMACCESS
|
mov eax,AMX_ERR_MEMACCESS
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_bounds:
|
err_bounds:
|
||||||
_ABORT AMX_ERR_BOUNDS
|
mov eax,AMX_ERR_BOUNDS
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_heaplow:
|
err_heaplow:
|
||||||
_ABORT AMX_ERR_HEAPLOW
|
mov eax,AMX_ERR_HEAPLOW
|
||||||
|
jmp _return
|
||||||
|
|
||||||
err_divide:
|
err_divide:
|
||||||
_ABORT AMX_ERR_DIVIDE
|
mov eax,AMX_ERR_DIVIDE
|
||||||
|
jmp _return
|
||||||
|
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
; save a few parameters, mostly for the "sleep"function
|
; save a few parameters, mostly for the "sleep"function
|
||||||
mov ebp,amx ; get amx into ebp
|
mov ebp,amx ; get amx into ebp
|
||||||
mov [ebp+_cip],esi ; get corrected cip for amxmodx
|
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
|
||||||
mov eax,[ebp+_error]; get error code
|
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT)
|
||||||
|
|
||||||
pop esi ; remove FRM from stack
|
pop esi ; remove FRM from stack
|
||||||
|
|
||||||
@ -1605,14 +1489,6 @@ Start_DATA
|
|||||||
|
|
||||||
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
|
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
|
||||||
|
|
||||||
g_round_nearest DD 0.5
|
|
||||||
|
|
||||||
GLOBAL g_flags
|
|
||||||
g_flags:
|
|
||||||
DD -1
|
|
||||||
DD 0
|
|
||||||
DD 1
|
|
||||||
|
|
||||||
GLOBAL amx_opcodelist
|
GLOBAL amx_opcodelist
|
||||||
GLOBAL _amx_opcodelist
|
GLOBAL _amx_opcodelist
|
||||||
amx_opcodelist:
|
amx_opcodelist:
|
||||||
@ -1754,10 +1630,4 @@ _amx_opcodelist DD OP_INVALID
|
|||||||
DD OP_SYSREQ_D
|
DD OP_SYSREQ_D
|
||||||
DD OP_SYMTAG
|
DD OP_SYMTAG
|
||||||
DD OP_BREAK
|
DD OP_BREAK
|
||||||
DD OP_FLOAT_MUL
|
|
||||||
DD OP_FLOAT_DIV
|
|
||||||
DD OP_FLOAT_ADD
|
|
||||||
DD OP_FLOAT_SUB
|
|
||||||
DD OP_FLOAT_TO
|
|
||||||
DD OP_FLOAT_ROUND
|
|
||||||
DD OP_FLOAT_CMP
|
|
||||||
|
@ -21,26 +21,17 @@
|
|||||||
; step.
|
; step.
|
||||||
|
|
||||||
; NOTE 3:
|
; NOTE 3:
|
||||||
|
; During execution of the compiled code with amx_exec_jit() the x86 processor's
|
||||||
|
; stack is switched into the data section of the abstract machine. This means
|
||||||
|
; that there should always be enough memory left between HEA and STK to provide
|
||||||
|
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
||||||
|
|
||||||
|
; NOTE 4:
|
||||||
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||||
; instructions, I have to tell that they don't work as expected in a JIT
|
; instructions, I have to tell that they don't work as expected in a JIT
|
||||||
; compiled program, because there is no easy way of transforming AMX code
|
; compiled program, because there is no easy way of transforming AMX code
|
||||||
; addresses and JIT translated ones. This might be fixed in a future version.
|
; addresses and JIT translated ones. This might be fixed in a future version.
|
||||||
|
|
||||||
; NOTE 4:
|
|
||||||
; Stack Pointer issues (by David Anderson)
|
|
||||||
; The JIT was changed recently so it no longer uses ESP as a general purpose
|
|
||||||
; register (GRP), because it can conflict with threading/signal systems which
|
|
||||||
; rely on the stack pointer being in-tact to find thread-ids. My fix for this
|
|
||||||
; was to keep esp safe, but save the stack pointer in 'ecx'. As such, ecx is no
|
|
||||||
; longer the CIP or scratch register, it is the save point for pieces of the AMX
|
|
||||||
; structure on the x86 stack.
|
|
||||||
; This means that the optimization of the JIT has changed, as every amx stack
|
|
||||||
; push call now takes two operations instead of one (same for pop), and pushing
|
|
||||||
; addresses is 4 instructions instead of 1.
|
|
||||||
; As of this moment I don't see a better way around it, but the sacrifice for
|
|
||||||
; having pthread-safe code was deemed to be necessary.
|
|
||||||
|
|
||||||
; NOTE 5:
|
|
||||||
; NX ("No eXecute") and XD (eXecution Denied) bits
|
; NX ("No eXecute") and XD (eXecution Denied) bits
|
||||||
; (by Thiadmer Riemersma)
|
; (by Thiadmer Riemersma)
|
||||||
;
|
;
|
||||||
@ -74,8 +65,7 @@
|
|||||||
; segment: the JIT-compiler patches P-code parameters into its own code segment
|
; segment: the JIT-compiler patches P-code parameters into its own code segment
|
||||||
; during compilation. This is handled in the support code for amx_InitJIT.
|
; during compilation. This is handled in the support code for amx_InitJIT.
|
||||||
;
|
;
|
||||||
|
;
|
||||||
; NOTE 6:
|
|
||||||
; CALLING CONVENTIONS
|
; CALLING CONVENTIONS
|
||||||
; (by Thiadmer Riemersma)
|
; (by Thiadmer Riemersma)
|
||||||
;
|
;
|
||||||
@ -87,16 +77,9 @@
|
|||||||
; a reserved word on the assembler, I had to choose a different name for the
|
; a reserved word on the assembler, I had to choose a different name for the
|
||||||
; macro, hence STDECL.)
|
; macro, hence STDECL.)
|
||||||
|
|
||||||
|
|
||||||
; Revision History
|
; Revision History
|
||||||
; ----------------
|
; ----------------
|
||||||
; 16 august 2005 by David "BAILOPAN" Anderson (DA)
|
; 26 july 2005 by David "BAILOPAN" Anderson
|
||||||
; Changed JIT to not swap stack pointer during execution. This
|
|
||||||
; is playing with fire, especially with pthreads and signals on linux,
|
|
||||||
; where the stack pointer is used to find the current thread id. If
|
|
||||||
; the stack pointer is altered during a thread/signal switch/interrupt
|
|
||||||
; unexpected behaviour can occur (crashes).
|
|
||||||
; 26 july 2005 by David "BAILOPAN" Anderson (DA)
|
|
||||||
; Fixed a bug where zero casetbl entries would crash the JIT.
|
; Fixed a bug where zero casetbl entries would crash the JIT.
|
||||||
; 17 february 2005 by Thiadmer Riemersms
|
; 17 february 2005 by Thiadmer Riemersms
|
||||||
; Addition of the BREAK opcode, removal of the older debugging opcode
|
; Addition of the BREAK opcode, removal of the older debugging opcode
|
||||||
@ -182,6 +165,15 @@
|
|||||||
;
|
;
|
||||||
%define FORCERELOCATABLE
|
%define FORCERELOCATABLE
|
||||||
|
|
||||||
|
;
|
||||||
|
; Determines how much memory should be reserved for occurring interrupts.
|
||||||
|
; (If my memory serves me right, DOS4/G(W) provides a stack of 512 bytes
|
||||||
|
; for interrupts that occur in real mode and are promoted to protected mode.)
|
||||||
|
; This value _MUST_ be greater than 64 (for AMX needs) and should be at least
|
||||||
|
; 128 (to serve interrupts).
|
||||||
|
;
|
||||||
|
%define STACKRESERVE 256
|
||||||
|
|
||||||
;
|
;
|
||||||
; This variable controls the generation of memory range checks at run-time.
|
; This variable controls the generation of memory range checks at run-time.
|
||||||
; You should set this to 0, only when you are sure that there are no range
|
; You should set this to 0, only when you are sure that there are no range
|
||||||
@ -194,49 +186,32 @@
|
|||||||
%define JIT 1
|
%define JIT 1
|
||||||
%include "amxdefn.asm"
|
%include "amxdefn.asm"
|
||||||
|
|
||||||
;Registers used for JIT during execution:
|
; GWMV:
|
||||||
; eax - pri
|
; Nasm can't do the next as equivalence statements, since the value of
|
||||||
; ebx - reloc frame
|
; esi is not determined at compile time
|
||||||
; ecx - info params
|
%define stk [esi+32] ; define some aliases to registers that will
|
||||||
; edx - alt
|
%define alt [esi+28] ; be stored on the stack when the code is
|
||||||
; esi - AMX stack
|
%define pri [esi+24] ; actually beeing executed
|
||||||
; edi - DAT
|
%define code [esi+20]
|
||||||
; ebp - scratch
|
%define amx [esi+16]
|
||||||
|
%define retval [esi+12]
|
||||||
;DA:
|
%define stp [esi+8]
|
||||||
; These are still stored in the stack, but the stack pointer
|
%define hea [esi+4]
|
||||||
; holding them is now kept in ecx.
|
%define frm [esi] ; FRM is NOT stored in ebp, FRM+DAT is being held
|
||||||
%define stk [ecx+32] ; define some aliases to registers that will
|
|
||||||
%define alt [ecx+28] ; be stored on the stack when the code is
|
|
||||||
%define pri [ecx+24] ; actually beeing executed
|
|
||||||
%define code [ecx+20]
|
|
||||||
%define amx [ecx+16]
|
|
||||||
%define retval [ecx+12]
|
|
||||||
%define stp [ecx+8]
|
|
||||||
%define hea [ecx+4]
|
|
||||||
%define frm [ecx] ; FRM is NOT stored in ebp, FRM+DAT is being held
|
|
||||||
; in ebx instead.
|
; in ebx instead.
|
||||||
|
|
||||||
;
|
;
|
||||||
; #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
; #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||||
;
|
;
|
||||||
%macro _PUSH 1
|
%macro _PUSH 1
|
||||||
lea esi,[esi-4]
|
push dword %1
|
||||||
mov dword [esi], %1
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro _PUSHMEM 1
|
|
||||||
lea esi,[esi-4]
|
|
||||||
mov ebp, dword %1
|
|
||||||
mov dword [esi], ebp
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
;
|
;
|
||||||
; #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
; #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
||||||
;
|
;
|
||||||
%macro _POP 1
|
%macro _POP 1
|
||||||
mov %1, dword [esi]
|
pop dword %1
|
||||||
lea esi,[esi+4]
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
|
||||||
@ -304,11 +279,7 @@
|
|||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
|
||||||
%ifdef WIN32
|
|
||||||
section .data exec
|
|
||||||
%else
|
|
||||||
section .text
|
section .text
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
global asm_runJIT, _asm_runJIT
|
global asm_runJIT, _asm_runJIT
|
||||||
@ -441,9 +412,7 @@ reloc_done:
|
|||||||
; in the compiled code. This is fine, but the .text section in an ELF executable
|
; in the compiled code. This is fine, but the .text section in an ELF executable
|
||||||
; is usually marked read-only, that's why this code is in the .data section.
|
; is usually marked read-only, that's why this code is in the .data section.
|
||||||
|
|
||||||
%ifndef WIN32
|
|
||||||
section .data exec
|
section .data exec
|
||||||
%endif
|
|
||||||
|
|
||||||
OP_LOAD_PRI:
|
OP_LOAD_PRI:
|
||||||
;nop;
|
;nop;
|
||||||
@ -821,7 +790,7 @@ OP_LCTRL:
|
|||||||
jne lctrl_5
|
jne lctrl_5
|
||||||
GO_ON j_lctrl_4, lctrl_5, 8
|
GO_ON j_lctrl_4, lctrl_5, 8
|
||||||
j_lctrl_4:
|
j_lctrl_4:
|
||||||
mov eax,esi ; 4=STK
|
mov eax,esp ; 4=STK
|
||||||
sub eax,edi
|
sub eax,edi
|
||||||
CHECKCODESIZE j_lctrl_4
|
CHECKCODESIZE j_lctrl_4
|
||||||
lctrl_5:
|
lctrl_5:
|
||||||
@ -855,7 +824,7 @@ OP_SCTRL:
|
|||||||
j_sctrl_4:
|
j_sctrl_4:
|
||||||
;mov esp,eax ; 4=STK
|
;mov esp,eax ; 4=STK
|
||||||
;add esp,edi ; relocate stack
|
;add esp,edi ; relocate stack
|
||||||
lea esi,[eax+edi]
|
lea esp,[eax+edi]
|
||||||
CHECKCODESIZE j_sctrl_4
|
CHECKCODESIZE j_sctrl_4
|
||||||
sctrl_5:
|
sctrl_5:
|
||||||
cmp eax,5
|
cmp eax,5
|
||||||
@ -916,16 +885,14 @@ OP_PUSH_ALT:
|
|||||||
|
|
||||||
OP_PUSH_R_PRI:
|
OP_PUSH_R_PRI:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_r_pri+2
|
putval j_push_r_pri+1
|
||||||
GO_ON j_push_r_pri, OP_PUSH_C, 8
|
GO_ON j_push_r_pri, OP_PUSH_C, 8
|
||||||
|
|
||||||
j_push_r_pri:
|
j_push_r_pri:
|
||||||
push ecx
|
|
||||||
mov ecx,12345678h
|
mov ecx,12345678h
|
||||||
j_push_loop:
|
j_push_loop:
|
||||||
_PUSH eax
|
_PUSH eax
|
||||||
loop j_push_loop
|
loop j_push_loop
|
||||||
pop ecx
|
|
||||||
;dec ecx
|
;dec ecx
|
||||||
;jnz j_push_loop
|
;jnz j_push_loop
|
||||||
CHECKCODESIZE j_push_r_pri
|
CHECKCODESIZE j_push_r_pri
|
||||||
@ -933,33 +900,30 @@ OP_PUSH_R_PRI:
|
|||||||
;good
|
;good
|
||||||
OP_PUSH_C:
|
OP_PUSH_C:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_c_end-4
|
putval j_push_c+1
|
||||||
GO_ON j_push_c, OP_PUSH, 8
|
GO_ON j_push_c, OP_PUSH, 8
|
||||||
|
|
||||||
j_push_c:
|
j_push_c:
|
||||||
_PUSH 12345678h
|
_PUSH 12345678h
|
||||||
j_push_c_end:
|
|
||||||
CHECKCODESIZE j_push_c
|
CHECKCODESIZE j_push_c
|
||||||
|
|
||||||
OP_PUSH:
|
OP_PUSH:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_end-6
|
putval j_push+2
|
||||||
GO_ON j_push, OP_PUSH_S, 8
|
GO_ON j_push, OP_PUSH_S, 8
|
||||||
|
|
||||||
j_push:
|
j_push:
|
||||||
_PUSHMEM [edi+12345678h]
|
_PUSH [edi+12345678h]
|
||||||
j_push_end:
|
|
||||||
CHECKCODESIZE j_push
|
CHECKCODESIZE j_push
|
||||||
|
|
||||||
;good
|
;good
|
||||||
OP_PUSH_S:
|
OP_PUSH_S:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_s_end-6
|
putval j_push_s+2
|
||||||
GO_ON j_push_s, OP_POP_PRI, 8
|
GO_ON j_push_s, OP_POP_PRI, 8
|
||||||
|
|
||||||
j_push_s:
|
j_push_s:
|
||||||
_PUSHMEM [ebx+12345678h]
|
_PUSH [ebx+12345678h]
|
||||||
j_push_s_end:
|
|
||||||
CHECKCODESIZE j_push_s
|
CHECKCODESIZE j_push_s
|
||||||
|
|
||||||
OP_POP_PRI:
|
OP_POP_PRI:
|
||||||
@ -986,8 +950,8 @@ OP_STACK:
|
|||||||
GO_ON j_stack, OP_HEAP, 8
|
GO_ON j_stack, OP_HEAP, 8
|
||||||
|
|
||||||
j_stack:
|
j_stack:
|
||||||
mov edx,esi
|
mov edx,esp
|
||||||
add esi,12345678h
|
add esp,12345678h
|
||||||
sub edx,edi
|
sub edx,edi
|
||||||
%ifdef DORUNTIMECHECKS
|
%ifdef DORUNTIMECHECKS
|
||||||
call [chk_marginstack]
|
call [chk_marginstack]
|
||||||
@ -1015,9 +979,9 @@ OP_PROC:
|
|||||||
GO_ON j_proc, OP_RET
|
GO_ON j_proc, OP_RET
|
||||||
|
|
||||||
j_proc: ;[STK] = FRM, STK = STK - cell size, FRM = STK
|
j_proc: ;[STK] = FRM, STK = STK - cell size, FRM = STK
|
||||||
_PUSHMEM frm ; push old frame (for RET/RETN)
|
_PUSH frm ; push old frame (for RET/RETN)
|
||||||
mov frm,esi ; get new frame
|
mov frm,esp ; get new frame
|
||||||
mov ebx,esi ; already relocated
|
mov ebx,esp ; already relocated
|
||||||
sub frm,edi ; relocate frame
|
sub frm,edi ; relocate frame
|
||||||
CHECKCODESIZE j_proc
|
CHECKCODESIZE j_proc
|
||||||
|
|
||||||
@ -1027,7 +991,6 @@ OP_RET:
|
|||||||
|
|
||||||
j_ret:
|
j_ret:
|
||||||
_POP ebx ; pop frame
|
_POP ebx ; pop frame
|
||||||
lea esi,[esi+4]
|
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
add ebx,edi
|
add ebx,edi
|
||||||
ret
|
ret
|
||||||
@ -1046,13 +1009,11 @@ OP_RETN:
|
|||||||
;good
|
;good
|
||||||
OP_CALL:
|
OP_CALL:
|
||||||
;nop;
|
;nop;
|
||||||
RELOC j_call_e8-j_call+1
|
RELOC 1
|
||||||
GO_ON j_call, OP_CALL_I, 8
|
GO_ON j_call, OP_CALL_I, 8
|
||||||
|
|
||||||
j_call:
|
j_call:
|
||||||
;call 12345678h ; tasm chokes on this out of a sudden
|
;call 12345678h ; tasm chokes on this out of a sudden
|
||||||
_PUSH 0
|
|
||||||
j_call_e8
|
|
||||||
db 0e8h, 0, 0, 0, 0
|
db 0e8h, 0, 0, 0, 0
|
||||||
CHECKCODESIZE j_call
|
CHECKCODESIZE j_call
|
||||||
|
|
||||||
@ -1061,7 +1022,6 @@ OP_CALL_I:
|
|||||||
GO_ON j_call_i, OP_JUMP
|
GO_ON j_call_i, OP_JUMP
|
||||||
|
|
||||||
j_call_i:
|
j_call_i:
|
||||||
_PUSH 0
|
|
||||||
call eax
|
call eax
|
||||||
CHECKCODESIZE j_call_i
|
CHECKCODESIZE j_call_i
|
||||||
|
|
||||||
@ -1212,30 +1172,24 @@ OP_SHL:
|
|||||||
;nop;
|
;nop;
|
||||||
GO_ON j_shl, OP_SHR
|
GO_ON j_shl, OP_SHR
|
||||||
j_shl:
|
j_shl:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
shl eax,cl
|
shl eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_shl
|
CHECKCODESIZE j_shl
|
||||||
|
|
||||||
OP_SHR:
|
OP_SHR:
|
||||||
;nop;
|
;nop;
|
||||||
GO_ON j_shr, OP_SSHR
|
GO_ON j_shr, OP_SSHR
|
||||||
j_shr:
|
j_shr:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
shr eax,cl
|
shr eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_shr
|
CHECKCODESIZE j_shr
|
||||||
|
|
||||||
OP_SSHR:
|
OP_SSHR:
|
||||||
;nop;
|
;nop;
|
||||||
GO_ON j_sshr, OP_SHL_C_PRI
|
GO_ON j_sshr, OP_SHL_C_PRI
|
||||||
j_sshr:
|
j_sshr:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
sar eax,cl
|
sar eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_sshr
|
CHECKCODESIZE j_sshr
|
||||||
|
|
||||||
OP_SHL_C_PRI:
|
OP_SHL_C_PRI:
|
||||||
@ -1654,35 +1608,29 @@ OP_DEC_I:
|
|||||||
|
|
||||||
OP_MOVS:
|
OP_MOVS:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_movs+2
|
putval j_movs+1
|
||||||
GO_ON j_movs, OP_CMPS, 8
|
GO_ON j_movs, OP_CMPS, 8
|
||||||
j_movs:
|
j_movs:
|
||||||
push ecx
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
mov ecx,12345678h
|
|
||||||
call [jit_movs]
|
call [jit_movs]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_movs
|
CHECKCODESIZE j_movs
|
||||||
|
|
||||||
OP_CMPS:
|
OP_CMPS:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_cmps+2
|
putval j_cmps+1
|
||||||
GO_ON j_cmps, OP_FILL, 8
|
GO_ON j_cmps, OP_FILL, 8
|
||||||
j_cmps:
|
j_cmps:
|
||||||
push ecx
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
mov ecx,12345678h
|
|
||||||
call [jit_cmps]
|
call [jit_cmps]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_cmps
|
CHECKCODESIZE j_cmps
|
||||||
|
|
||||||
OP_FILL:
|
OP_FILL:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_fill+2
|
putval j_fill+1
|
||||||
GO_ON j_fill, OP_HALT, 8
|
GO_ON j_fill, OP_HALT, 8
|
||||||
j_fill:
|
j_fill:
|
||||||
push ecx
|
|
||||||
mov ecx,12345678h ;TODO: save ECX if used as special register
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
call [jit_fill]
|
call [jit_fill]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_fill
|
CHECKCODESIZE j_fill
|
||||||
|
|
||||||
;good
|
;good
|
||||||
@ -1882,7 +1830,7 @@ OP_BREAK:
|
|||||||
jae code_gen_done
|
jae code_gen_done
|
||||||
jmp DWORD [ebx] ; go on with the next opcode
|
jmp DWORD [ebx] ; go on with the next opcode
|
||||||
%else
|
%else
|
||||||
GO_ON j_break, OP_FLOAT_MUL
|
GO_ON j_break, OP_INVALID
|
||||||
j_break:
|
j_break:
|
||||||
mov ebp,amx
|
mov ebp,amx
|
||||||
cmp DWORD [ebp+_debug], 0
|
cmp DWORD [ebp+_debug], 0
|
||||||
@ -1891,116 +1839,6 @@ OP_BREAK:
|
|||||||
CHECKCODESIZE j_break
|
CHECKCODESIZE j_break
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
OP_FLOAT_MUL:
|
|
||||||
GO_ON j_float_mul, OP_FLOAT_DIV
|
|
||||||
j_float_mul:
|
|
||||||
fld dword [esi+4]
|
|
||||||
fmul dword [esi+8]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
CHECKCODESIZE j_float_mul
|
|
||||||
|
|
||||||
OP_FLOAT_DIV:
|
|
||||||
GO_ON j_float_div, OP_FLOAT_ADD
|
|
||||||
j_float_div:
|
|
||||||
fld dword [esi+4]
|
|
||||||
fdiv dword [esi+8]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
CHECKCODESIZE j_float_div
|
|
||||||
|
|
||||||
OP_FLOAT_ADD:
|
|
||||||
GO_ON j_float_add, OP_FLOAT_SUB
|
|
||||||
j_float_add:
|
|
||||||
fld dword [esi+4]
|
|
||||||
fadd dword [esi+8]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
CHECKCODESIZE j_float_add
|
|
||||||
|
|
||||||
OP_FLOAT_SUB:
|
|
||||||
GO_ON j_float_sub, OP_FLOAT_TO
|
|
||||||
j_float_sub:
|
|
||||||
fld dword [esi+4]
|
|
||||||
fsub dword [esi+8]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
CHECKCODESIZE j_float_sub
|
|
||||||
|
|
||||||
OP_FLOAT_TO:
|
|
||||||
GO_ON j_float_to, OP_FLOAT_ROUND
|
|
||||||
j_float_to:
|
|
||||||
fild dword [esi+4]
|
|
||||||
sub esp, 4
|
|
||||||
fstp dword [esp]
|
|
||||||
pop eax
|
|
||||||
CHECKCODESIZE j_float_to
|
|
||||||
|
|
||||||
OP_FLOAT_ROUND:
|
|
||||||
GO_ON j_float_round, OP_FLOAT_CMP
|
|
||||||
j_float_round:
|
|
||||||
;get the float control word
|
|
||||||
push 0
|
|
||||||
mov ebp,esp
|
|
||||||
fstcw [ebp]
|
|
||||||
mov eax,[ebp]
|
|
||||||
push eax
|
|
||||||
;clear the top bits
|
|
||||||
xor ah,ah
|
|
||||||
;get the control method
|
|
||||||
push edx
|
|
||||||
mov edx,[esi+8]
|
|
||||||
and edx,3 ;sanity check
|
|
||||||
shl edx,2 ;shift it to right position
|
|
||||||
;set the bits
|
|
||||||
or ah,dl ;set bits 15,14 of FCW to rounding method
|
|
||||||
or ah,3 ;set precision to 64bit
|
|
||||||
mov [ebp], eax
|
|
||||||
fldcw [ebp]
|
|
||||||
;calculate
|
|
||||||
sub esp,4
|
|
||||||
fld dword [esi+4]
|
|
||||||
test edx,edx
|
|
||||||
jz .correct
|
|
||||||
jmp .skip_correct
|
|
||||||
.correct:
|
|
||||||
fadd st0
|
|
||||||
fadd dword [g_round_nearest]
|
|
||||||
fistp dword [esp]
|
|
||||||
pop eax
|
|
||||||
sar eax,1
|
|
||||||
jmp .done
|
|
||||||
.skip_correct:
|
|
||||||
frndint
|
|
||||||
fistp dword [esp]
|
|
||||||
pop eax
|
|
||||||
.done:
|
|
||||||
pop edx
|
|
||||||
;restore bits
|
|
||||||
pop ebp
|
|
||||||
mov [esp], ebp
|
|
||||||
fldcw [esp]
|
|
||||||
pop ebp
|
|
||||||
CHECKCODESIZE j_float_round
|
|
||||||
|
|
||||||
OP_FLOAT_CMP:
|
|
||||||
GO_ON j_float_cmp, OP_INVALID
|
|
||||||
j_float_cmp:
|
|
||||||
fld dword [esi+8]
|
|
||||||
fld dword [esi+4]
|
|
||||||
fucompp
|
|
||||||
fnstsw ax
|
|
||||||
fwait
|
|
||||||
sahf
|
|
||||||
cmovz eax, [g_flagsjit+4]
|
|
||||||
cmova eax, [g_flagsjit+8]
|
|
||||||
cmovb eax, [g_flagsjit+0]
|
|
||||||
CHECKCODESIZE j_float_cmp
|
|
||||||
|
|
||||||
OP_INVALID: ; break from the compiler with an error code
|
OP_INVALID: ; break from the compiler with an error code
|
||||||
mov eax,AMX_ERR_INVINSTR
|
mov eax,AMX_ERR_INVINSTR
|
||||||
pop esi
|
pop esi
|
||||||
@ -2041,7 +1879,7 @@ _amx_exec_jit:
|
|||||||
push dword [eax+20]; store FRM
|
push dword [eax+20]; store FRM
|
||||||
|
|
||||||
mov edx,[eax+4] ; get ALT
|
mov edx,[eax+4] ; get ALT
|
||||||
mov ebp,[eax+8] ; get CIP
|
mov ecx,[eax+8] ; get CIP
|
||||||
mov edi,[eax+12] ; get pointer to data segment
|
mov edi,[eax+12] ; get pointer to data segment
|
||||||
mov esi,[eax+16] ; get STK !!changed, now ECX free as counter!!
|
mov esi,[eax+16] ; get STK !!changed, now ECX free as counter!!
|
||||||
mov ebx,[eax+20] ; get FRM
|
mov ebx,[eax+20] ; get FRM
|
||||||
@ -2049,14 +1887,13 @@ _amx_exec_jit:
|
|||||||
add ebx,edi ; relocate frame
|
add ebx,edi ; relocate frame
|
||||||
|
|
||||||
add esi,edi ; ESP will contain DAT+STK
|
add esi,edi ; ESP will contain DAT+STK
|
||||||
|
xchg esp,esi ; switch to AMX stack
|
||||||
|
|
||||||
add [esp+8],edi ; make STP absolute address for run-time checks
|
add stp,edi ; make STP absolute address for run-time checks
|
||||||
|
|
||||||
mov dword [esi], 0 ; zero this out, but we need to keep it so
|
_POP ebp ; AMX pseudo-return address, ignored
|
||||||
; the stack frame is in tact
|
|
||||||
mov ecx,esp ; copy stack pointer
|
|
||||||
; Call compiled code via CALL NEAR <address>
|
; Call compiled code via CALL NEAR <address>
|
||||||
call ebp
|
call ecx
|
||||||
|
|
||||||
return_to_caller:
|
return_to_caller:
|
||||||
cmp dword retval,0
|
cmp dword retval,0
|
||||||
@ -2069,17 +1906,15 @@ return_to_caller:
|
|||||||
jmp _return
|
jmp _return
|
||||||
|
|
||||||
_return_popstack:
|
_return_popstack:
|
||||||
mov esp,ecx ; get our old stack pointer
|
add esp,4 ; Correct ESP, because we just come from a
|
||||||
|
; runtime error checking routine.
|
||||||
_return:
|
_return:
|
||||||
; store machine state
|
; store machine state
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push ecx
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
mov ecx,esi ; get STK into ECX
|
|
||||||
|
|
||||||
sub ecx,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov [ebp+_stk],ecx ; store values in AMX structure: STK, ...
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK, ...
|
||||||
pop ecx ; get orig value
|
|
||||||
mov ecx,hea ; ... HEA, ...
|
mov ecx,hea ; ... HEA, ...
|
||||||
mov [ebp+_hea],ecx
|
mov [ebp+_hea],ecx
|
||||||
mov ecx,ebx ; ... and FRM
|
mov ecx,ebx ; ... and FRM
|
||||||
@ -2089,8 +1924,8 @@ _return:
|
|||||||
mov [ebp+_alt],edx ; ... and ALT
|
mov [ebp+_alt],edx ; ... and ALT
|
||||||
|
|
||||||
; return
|
; return
|
||||||
pop ecx
|
|
||||||
sub stp,edi ; make STP relative to DAT again
|
sub stp,edi ; make STP relative to DAT again
|
||||||
|
xchg esp,esi ; switch back to caller's stack
|
||||||
|
|
||||||
add esp,4*9 ; remove temporary data
|
add esp,4*9 ; remove temporary data
|
||||||
|
|
||||||
@ -2111,8 +1946,12 @@ err_stacklow:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
_CHKMARGIN_STACK: ; some run-time check routines
|
_CHKMARGIN_STACK: ; some run-time check routines
|
||||||
cmp esi,stp
|
cmp esp,stp
|
||||||
|
lea ebp,[esp-STACKRESERVE]
|
||||||
jg err_stacklow
|
jg err_stacklow
|
||||||
|
sub ebp,edi
|
||||||
|
cmp hea,ebp
|
||||||
|
jg err_stack
|
||||||
ret
|
ret
|
||||||
|
|
||||||
err_heaplow:
|
err_heaplow:
|
||||||
@ -2120,11 +1959,9 @@ err_heaplow:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
_CHKMARGIN_HEAP:
|
_CHKMARGIN_HEAP:
|
||||||
cmp esi,stp
|
cmp esp,stp
|
||||||
jg err_stacklow
|
jg err_stacklow
|
||||||
mov ebp,amx
|
cmp dword hea,0
|
||||||
mov ebp,[ebp+_hlw]
|
|
||||||
cmp dword hea,ebp
|
|
||||||
jl err_heaplow
|
jl err_heaplow
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -2138,7 +1975,7 @@ _VERIFYADDRESS_eax: ; used in load.i, store.i & lidx
|
|||||||
cmp eax,hea
|
cmp eax,hea
|
||||||
jb veax1
|
jb veax1
|
||||||
lea ebp,[eax+edi]
|
lea ebp,[eax+edi]
|
||||||
cmp ebp,esi
|
cmp ebp,esp
|
||||||
jb err_memaccess
|
jb err_memaccess
|
||||||
veax1:
|
veax1:
|
||||||
ret
|
ret
|
||||||
@ -2149,7 +1986,7 @@ _VERIFYADDRESS_edx: ; used in load.i, store.i & lidx
|
|||||||
cmp edx,hea
|
cmp edx,hea
|
||||||
jb vedx1
|
jb vedx1
|
||||||
lea ebp,[edx+edi]
|
lea ebp,[edx+edi]
|
||||||
cmp ebp,esi
|
cmp ebp,esp
|
||||||
jb err_memaccess
|
jb err_memaccess
|
||||||
vedx1:
|
vedx1:
|
||||||
ret
|
ret
|
||||||
@ -2181,15 +2018,15 @@ JIT_OP_SDIV:
|
|||||||
|
|
||||||
JIT_OP_RETN:
|
JIT_OP_RETN:
|
||||||
_POP ebx ; pop frame
|
_POP ebx ; pop frame
|
||||||
add esi,4 ; get rid of the extra parameter from call
|
_POP ecx ; get return address
|
||||||
|
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
_POP ebp
|
_POP ebp
|
||||||
|
|
||||||
add ebx,edi
|
add ebx,edi
|
||||||
add esi,ebp ; remove data from stack
|
add esp,ebp ; remove data from stack
|
||||||
|
|
||||||
ret
|
jmp ecx
|
||||||
|
|
||||||
|
|
||||||
JIT_OP_MOVS: ;length of block to copy is already in ECX
|
JIT_OP_MOVS: ;length of block to copy is already in ECX
|
||||||
@ -2255,33 +2092,34 @@ err_divide:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
JIT_OP_SYSREQ:
|
JIT_OP_SYSREQ:
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push esi
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov alt,edx ; save ALT
|
mov alt,edx ; save ALT
|
||||||
|
|
||||||
mov [ebp+_stk],esi ; store values in AMX structure: STK,
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
|
||||||
mov esi,hea ; HEA,
|
mov ecx,hea ; HEA,
|
||||||
mov ebx,frm ; and FRM
|
mov ebx,frm ; and FRM
|
||||||
mov [ebp+_hea],esi
|
mov [ebp+_hea],ecx
|
||||||
mov [ebp+_frm],ebx
|
mov [ebp+_frm],ebx
|
||||||
|
|
||||||
lea ebx,pri ; 3rd param: addr. of retval
|
lea ebx,pri ; 3rd param: addr. of retval
|
||||||
|
lea ecx,[esp+4] ; 4th param: parameter array
|
||||||
|
|
||||||
;Our original esi is still pushed!
|
xchg esp,esi ; switch to caller stack
|
||||||
|
|
||||||
|
push ecx
|
||||||
push ebx
|
push ebx
|
||||||
push eax ; 2nd param: function number
|
push eax ; 2nd param: function number
|
||||||
push ebp ; 1st param: amx
|
push ebp ; 1st param: amx
|
||||||
call [ebp+_callback]
|
call [ebp+_callback]
|
||||||
_DROPARGS 12 ; remove args from stack
|
_DROPARGS 16 ; remove args from stack
|
||||||
|
|
||||||
pop esi
|
xchg esp,esi ; switch back to AMX stack
|
||||||
pop ecx
|
|
||||||
cmp eax,AMX_ERR_NONE
|
cmp eax,AMX_ERR_NONE
|
||||||
jne _return_popstack
|
jne _return_popstack; return error code, if any
|
||||||
.continue:
|
|
||||||
mov eax,pri ; get retval into eax (PRI)
|
mov eax,pri ; get retval into eax (PRI)
|
||||||
mov edx,alt ; restore ALT
|
mov edx,alt ; restore ALT
|
||||||
mov ebx,frm ; restore FRM
|
mov ebx,frm ; restore FRM
|
||||||
@ -2290,25 +2128,25 @@ JIT_OP_SYSREQ:
|
|||||||
|
|
||||||
|
|
||||||
JIT_OP_SYSREQ_D: ; (TR)
|
JIT_OP_SYSREQ_D: ; (TR)
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push esi
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov alt,edx ; save ALT
|
mov alt,edx ; save ALT
|
||||||
|
|
||||||
mov [ebp+_stk],esi ; store values in AMX structure: STK,
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
|
||||||
mov esi,hea ; HEA,
|
mov ecx,hea ; HEA,
|
||||||
mov eax,frm ; and FRM
|
mov eax,frm ; and FRM
|
||||||
mov [ebp+_hea],esi
|
mov [ebp+_hea],ecx
|
||||||
mov [ebp+_frm],eax ; eax & ecx are invalid by now
|
mov [ebp+_frm],eax ; eax & ecx are invalid by now
|
||||||
|
|
||||||
;esi is still pushed!
|
lea edx,[esp+4] ; 2nd param: parameter array
|
||||||
|
xchg esp,esi ; switch to caller stack
|
||||||
|
push edx
|
||||||
push ebp ; 1st param: amx
|
push ebp ; 1st param: amx
|
||||||
call ebx ; direct call
|
call ebx ; direct call
|
||||||
_DROPARGS 8 ; remove args from stack
|
_DROPARGS 8 ; remove args from stack
|
||||||
|
xchg esp,esi ; switch back to AMX stack
|
||||||
pop ecx
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
cmp dword [ebp+_error],AMX_ERR_NONE
|
cmp dword [ebp+_error],AMX_ERR_NONE
|
||||||
jne _return_popstack; return error code, if any
|
jne _return_popstack; return error code, if any
|
||||||
@ -2322,27 +2160,25 @@ JIT_OP_SYSREQ_D: ; (TR)
|
|||||||
|
|
||||||
JIT_OP_BREAK:
|
JIT_OP_BREAK:
|
||||||
%ifdef DEBUGSUPPORT
|
%ifdef DEBUGSUPPORT
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push esi
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
|
|
||||||
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
||||||
mov [ebp+_alt],edx ; ALT,
|
mov [ebp+_alt],edx ; ALT,
|
||||||
mov [ebp+_stk],esi ; STK,
|
mov [ebp+_stk],ecx ; STK,
|
||||||
mov esi,hea ; HEA,
|
mov ecx,hea ; HEA,
|
||||||
mov ebx,frm ; and FRM
|
mov ebx,frm ; and FRM
|
||||||
mov [ebp+_hea],esi
|
mov [ebp+_hea],ecx
|
||||||
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
|
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
|
||||||
;??? storing CIP is not very useful, because the code changed (during JIT compile)
|
;??? storing CIP is not very useful, because the code changed (during JIT compile)
|
||||||
|
|
||||||
|
xchg esp,esi ; switch to caller stack
|
||||||
push ebp ; 1st param: amx
|
push ebp ; 1st param: amx
|
||||||
call [ebp+_debug]
|
call [ebp+_debug]
|
||||||
_DROPARGS 4 ; remove args from stack
|
_DROPARGS 4 ; remove args from stack
|
||||||
|
xchg esp,esi ; switch back to AMX stack
|
||||||
pop esi
|
|
||||||
pop ecx
|
|
||||||
cmp eax,AMX_ERR_NONE
|
cmp eax,AMX_ERR_NONE
|
||||||
jne _return_popstack; return error code, if any
|
jne _return_popstack; return error code, if any
|
||||||
|
|
||||||
@ -2358,7 +2194,6 @@ JIT_OP_BREAK:
|
|||||||
|
|
||||||
JIT_OP_SWITCH:
|
JIT_OP_SWITCH:
|
||||||
pop ebp ; pop return address = table address
|
pop ebp ; pop return address = table address
|
||||||
push ecx
|
|
||||||
mov ecx,[ebp] ; ECX = number of records
|
mov ecx,[ebp] ; ECX = number of records
|
||||||
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
|
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
|
||||||
;if there are zero cases we should just skip this -- bail
|
;if there are zero cases we should just skip this -- bail
|
||||||
@ -2370,7 +2205,6 @@ JIT_OP_SWITCH:
|
|||||||
sub ebp,8 ; position to preceding case
|
sub ebp,8 ; position to preceding case
|
||||||
loop op_switch_loop ; check next case, or fall through
|
loop op_switch_loop ; check next case, or fall through
|
||||||
op_switch_jump:
|
op_switch_jump:
|
||||||
pop ecx
|
|
||||||
%ifndef FORCERELOCATABLE
|
%ifndef FORCERELOCATABLE
|
||||||
jmp [ebp-4] ; jump to the case instructions
|
jmp [ebp-4] ; jump to the case instructions
|
||||||
%else
|
%else
|
||||||
@ -2431,16 +2265,6 @@ jit_switch DD JIT_OP_SWITCH
|
|||||||
; The table for the browser/relocator function.
|
; The table for the browser/relocator function.
|
||||||
;
|
;
|
||||||
|
|
||||||
global g_flagsjit
|
|
||||||
g_flagsjit:
|
|
||||||
DD -1
|
|
||||||
DD 0
|
|
||||||
DD 1
|
|
||||||
|
|
||||||
global g_round_nearest
|
|
||||||
g_round_nearest:
|
|
||||||
DD 0.5
|
|
||||||
|
|
||||||
global amx_opcodelist_jit, _amx_opcodelist_jit
|
global amx_opcodelist_jit, _amx_opcodelist_jit
|
||||||
|
|
||||||
amx_opcodelist_jit:
|
amx_opcodelist_jit:
|
||||||
@ -2583,12 +2407,5 @@ _amx_opcodelist_jit:
|
|||||||
DD OP_SYSREQ_D ; TR
|
DD OP_SYSREQ_D ; TR
|
||||||
DD OP_SYMTAG ; TR
|
DD OP_SYMTAG ; TR
|
||||||
DD OP_BREAK ; TR
|
DD OP_BREAK ; TR
|
||||||
DD OP_FLOAT_MUL ; DA
|
|
||||||
DD OP_FLOAT_DIV ; DA
|
|
||||||
DD OP_FLOAT_ADD ; DA
|
|
||||||
DD OP_FLOAT_SUB ; DA
|
|
||||||
DD OP_FLOAT_TO ; DA
|
|
||||||
DD OP_FLOAT_ROUND ; DA
|
|
||||||
DD OP_FLOAT_CMP ; DA
|
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include "amxmod_compat.h"
|
|
||||||
#include "format.h"
|
|
||||||
|
|
||||||
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang)
|
|
||||||
{
|
|
||||||
key = (trans & BCOMPAT_TRANSLATE_KEYMASK);
|
|
||||||
dest = (trans >> BCOMPAT_TRANSLATE_DESTRSH) & BCOMPAT_TRANSLATE_DESTMASK;
|
|
||||||
lang = (trans >> BCOMPAT_TRANSLATE_LANGRSH) & BCOMPAT_TRANSLATE_LANGMASK;
|
|
||||||
|
|
||||||
if (dest == 0x3F)
|
|
||||||
{
|
|
||||||
dest = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lang == 0x1F)
|
|
||||||
{
|
|
||||||
lang = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def)
|
|
||||||
{
|
|
||||||
amxtrans_t trans = static_cast<amxtrans_t>(*source);
|
|
||||||
int key, _dest, lang;
|
|
||||||
if (!GetTranslation(trans, key, _dest, lang))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell amx_addr, *phys_addr;
|
|
||||||
if (amx_Allot(amx, 3, &amx_addr, &phys_addr) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_dest == -1)
|
|
||||||
{
|
|
||||||
*phys_addr = LANG_PLAYER;
|
|
||||||
} else if (_dest == 0) {
|
|
||||||
*phys_addr = LANG_SERVER;
|
|
||||||
} else if (lang >= 0 && lang < g_langMngr.GetLangsNum()) {
|
|
||||||
const char *name = g_langMngr.GetLangName(lang);
|
|
||||||
phys_addr[0] = static_cast<cell>(name[0]);
|
|
||||||
phys_addr[1] = static_cast<cell>(name[1]);
|
|
||||||
phys_addr[2] = static_cast<cell>('\0');
|
|
||||||
} else {
|
|
||||||
*phys_addr = LANG_SERVER;
|
|
||||||
}
|
|
||||||
|
|
||||||
//not optimized but it works, eh
|
|
||||||
//if someone cares they can make a translate() wrapper that takes the key # in directly
|
|
||||||
const char *r_key = g_langMngr.GetKey(key);
|
|
||||||
const char *def = translate(amx, amx_addr, r_key);
|
|
||||||
if (!def)
|
|
||||||
{
|
|
||||||
def = r_key;
|
|
||||||
}
|
|
||||||
amx_Release(amx, amx_addr);
|
|
||||||
|
|
||||||
*_key = g_langMngr.GetKey(key);
|
|
||||||
*_def = def;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_translate(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *key = get_amxstring(amx, params[1], 0, len);
|
|
||||||
|
|
||||||
amxtrans_t trans;
|
|
||||||
|
|
||||||
int suki = g_langMngr.GetKeyEntry(key);
|
|
||||||
//Some AMX Mod plugins do not register everything they need. Prevent a crash.
|
|
||||||
if (suki == -1)
|
|
||||||
{
|
|
||||||
suki = g_langMngr.AddKeyEntry(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (suki > BCOMPAT_TRANSLATE_KEYMASK)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not enough translation space, aborting!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
trans = suki & BCOMPAT_TRANSLATE_KEYMASK;
|
|
||||||
int dest = static_cast<int>(params[2]);
|
|
||||||
int lang = static_cast<int>(params[3]);
|
|
||||||
if (dest == -1)
|
|
||||||
{
|
|
||||||
trans |= (0x3F << BCOMPAT_TRANSLATE_DESTRSH);
|
|
||||||
} else {
|
|
||||||
trans |= (dest & BCOMPAT_TRANSLATE_DESTMASK) << BCOMPAT_TRANSLATE_DESTRSH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lang == -1)
|
|
||||||
{
|
|
||||||
trans |= (0x1F << BCOMPAT_TRANSLATE_LANGRSH);
|
|
||||||
} else {
|
|
||||||
trans |= (lang & BCOMPAT_TRANSLATE_LANGMASK) << BCOMPAT_TRANSLATE_LANGRSH;
|
|
||||||
}
|
|
||||||
|
|
||||||
trans |= BCOMPAT_TRANSLATE_BITS;
|
|
||||||
|
|
||||||
return static_cast<cell>(trans);
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_BcompatNatives[] =
|
|
||||||
{
|
|
||||||
{"translate", amx_translate},
|
|
||||||
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
#ifndef _INCLUDE_AMXMOD_CORE_COMPAT_H
|
|
||||||
#define _INCLUDE_AMXMOD_CORE_COMPAT_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New format for translation:
|
|
||||||
* Note that we only support:
|
|
||||||
* 4k keys
|
|
||||||
* 32 languages
|
|
||||||
* 0000 0000 0000 0000 0000 0000 0000 0000
|
|
||||||
* | key id |
|
|
||||||
* | | <- dest id
|
|
||||||
* | | <- lang id
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BCOMPAT_TRANSLATE_BITS 0xFF000000
|
|
||||||
#define BCOMPAT_TRANSLATE_KEYMASK 0xFFF
|
|
||||||
#define BCOMPAT_TRANSLATE_DESTMASK 0x3F
|
|
||||||
#define BCOMPAT_TRANSLATE_DESTRSH 12
|
|
||||||
#define BCOMPAT_TRANSLATE_LANGMASK 0x1F
|
|
||||||
#define BCOMPAT_TRANSLATE_LANGRSH 18
|
|
||||||
|
|
||||||
typedef unsigned int amxtrans_t;
|
|
||||||
|
|
||||||
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang);
|
|
||||||
|
|
||||||
extern AMX_NATIVE_INFO g_BcompatNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_AMXMOD_CORE_COMPAT_H
|
|
5133
amxmodx/amxmodx.cpp
5133
amxmodx/amxmodx.cpp
File diff suppressed because it is too large
Load Diff
@ -32,23 +32,20 @@
|
|||||||
#ifndef AMXMODX_H
|
#ifndef AMXMODX_H
|
||||||
#define AMXMODX_H
|
#define AMXMODX_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "sclinux.h"
|
#include "sclinux.h"
|
||||||
#endif
|
#endif
|
||||||
#include <ctype.h> //tolower, etc
|
#include <ctype.h> //tolower, etc
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include <extdll.h>
|
#include <extdll.h>
|
||||||
#include <meta_api.h>
|
#include <meta_api.h>
|
||||||
|
#include "mm_pextensions.h" // metamod-p extensions
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef MEMORY_TEST
|
||||||
// MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated
|
#include "mmgr/mmgr.h"
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#define unlink _unlink
|
|
||||||
#define mkdir _mkdir
|
|
||||||
#define strdup _strdup
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
@ -72,47 +69,32 @@
|
|||||||
#include "amxxlog.h"
|
#include "amxxlog.h"
|
||||||
|
|
||||||
#define AMXXLOG_Log g_log.Log
|
#define AMXXLOG_Log g_log.Log
|
||||||
#define AMXXLOG_Error g_log.LogError
|
#define AMX_VERSION "1.50"
|
||||||
#define AMX_VERSION "1.76d"
|
|
||||||
|
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[];
|
||||||
|
|
||||||
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[];
|
|
||||||
extern AMX_NATIVE_INFO msg_Natives[];
|
|
||||||
extern AMX_NATIVE_INFO vector_Natives[];
|
|
||||||
extern AMX_NATIVE_INFO g_SortNatives[];
|
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
|
#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)
|
#define DLFREE(m) FreeLibrary(m)
|
||||||
#else
|
#else
|
||||||
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW)
|
#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)
|
#define DLFREE(m) dlclose(m)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __GNUC__
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef intptr_t _INT_PTR;
|
|
||||||
#else
|
|
||||||
#if defined AMD64
|
|
||||||
typedef __int64 _INT_PTR;
|
|
||||||
#else
|
|
||||||
typedef __int32 _INT_PTR;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
typedef HINSTANCE DLHANDLE;
|
typedef HINSTANCE DLHANDLE;
|
||||||
#else
|
#else
|
||||||
typedef void* DLHANDLE;
|
typedef void* DLHANDLE;
|
||||||
#define INFINITE 0xFFFFFFFF
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GETPLAYERAUTHID
|
#ifndef GETPLAYERAUTHID
|
||||||
@ -128,37 +110,36 @@ extern AMX_NATIVE_INFO g_SortNatives[];
|
|||||||
|
|
||||||
char* UTIL_SplitHudMessage(register const char *src);
|
char* UTIL_SplitHudMessage(register const char *src);
|
||||||
int UTIL_ReadFlags(const char* c);
|
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_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_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
|
||||||
void UTIL_IntToString(int value, char *output);
|
void UTIL_IntToString(int value, char *output);
|
||||||
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);
|
||||||
void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen);
|
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen );
|
||||||
|
|
||||||
char *UTIL_VarArgs(const char *fmt, ...);
|
char *UTIL_VarArgs(const char *fmt, ...);
|
||||||
|
|
||||||
|
|
||||||
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
|
#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])
|
#define GET_PLAYER_POINTER_I(i) (&g_players[i])
|
||||||
|
|
||||||
struct WeaponsVault
|
struct WeaponsVault {
|
||||||
{
|
String fullName;
|
||||||
String fullName;
|
short int iId;
|
||||||
short int iId;
|
short int ammoSlot;
|
||||||
short int ammoSlot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fakecmd_t
|
struct fakecmd_t {
|
||||||
{
|
char args[256];
|
||||||
char args[256];
|
const char *argv[3];
|
||||||
const char *argv[3];
|
//char argv[3][128];
|
||||||
int argc;
|
int argc;
|
||||||
bool fake;
|
bool fake;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern bool g_IsNewMM;
|
||||||
|
extern pextension_funcs_t *gpMetaPExtFuncs;
|
||||||
extern CLog g_log;
|
extern CLog g_log;
|
||||||
extern CPluginMngr g_plugins;
|
extern CPluginMngr g_plugins;
|
||||||
extern CTaskMngr g_tasksMngr;
|
extern CTaskMngr g_tasksMngr;
|
||||||
@ -169,8 +150,7 @@ extern CList<CCVar> g_cvars;
|
|||||||
extern CList<ForceObject> g_forcemodels;
|
extern CList<ForceObject> g_forcemodels;
|
||||||
extern CList<ForceObject> g_forcesounds;
|
extern CList<ForceObject> g_forcesounds;
|
||||||
extern CList<ForceObject> g_forcegeneric;
|
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 CList<CPlayer*> g_auth;
|
||||||
extern EventsMngr g_events;
|
extern EventsMngr g_events;
|
||||||
extern Grenades g_grenades;
|
extern Grenades g_grenades;
|
||||||
@ -181,7 +161,7 @@ extern String g_log_dir;
|
|||||||
extern String g_mod_name;
|
extern String g_mod_name;
|
||||||
extern TeamIds g_teamsIds;
|
extern TeamIds g_teamsIds;
|
||||||
extern Vault g_vault;
|
extern Vault g_vault;
|
||||||
extern CForwardMngr g_forwards;
|
extern CForwardMngr g_forwards;
|
||||||
extern WeaponsVault g_weaponsData[MAX_WEAPONS];
|
extern WeaponsVault g_weaponsData[MAX_WEAPONS];
|
||||||
extern XVars g_xvars;
|
extern XVars g_xvars;
|
||||||
extern bool g_bmod_cstrike;
|
extern bool g_bmod_cstrike;
|
||||||
@ -196,7 +176,6 @@ extern float g_game_restarting;
|
|||||||
extern float g_game_timeleft;
|
extern float g_game_timeleft;
|
||||||
extern float g_task_time;
|
extern float g_task_time;
|
||||||
extern float g_auth_time;
|
extern float g_auth_time;
|
||||||
extern bool g_NewDLL_Available;
|
|
||||||
extern hudtextparms_t g_hudset;
|
extern hudtextparms_t g_hudset;
|
||||||
//extern int g_edict_point;
|
//extern int g_edict_point;
|
||||||
extern int g_players_num;
|
extern int g_players_num;
|
||||||
@ -245,15 +224,14 @@ void Client_DeathMsg(void*);
|
|||||||
void amx_command();
|
void amx_command();
|
||||||
void plugin_srvcmd();
|
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);
|
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
|
||||||
|
|
||||||
int loadModules(const char* filename, PLUG_LOADTIME now);
|
int loadModules(const char* filename, PLUG_LOADTIME now);
|
||||||
void detachModules();
|
void detachModules();
|
||||||
void detachReloadModules();
|
void detachReloadModules();
|
||||||
|
|
||||||
#ifdef FAKEMETA
|
#ifdef FAKEMETA
|
||||||
void attachModules();
|
void attachModules();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Count modules
|
// Count modules
|
||||||
@ -266,47 +244,41 @@ enum CountModulesMode
|
|||||||
|
|
||||||
int countModules(CountModulesMode mode);
|
int countModules(CountModulesMode mode);
|
||||||
void modules_callPluginsLoaded();
|
void modules_callPluginsLoaded();
|
||||||
void modules_callPluginsUnloaded();
|
|
||||||
void modules_callPluginsUnloading();
|
|
||||||
|
|
||||||
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||||
char* build_pathname(char *fmt, ...);
|
char* build_pathname(char *fmt, ... );
|
||||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||||
char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
|
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
|
||||||
AMX* get_amxscript(int, void**, const char**);
|
AMX* get_amxscript(int, void**,const char**);
|
||||||
const char* get_amxscriptname(AMX* amx);
|
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);
|
||||||
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
|
|
||||||
|
|
||||||
int amxstring_len(cell* cstr);
|
int amxstring_len(cell* cstr);
|
||||||
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
|
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_amxnatives(AMX* amx,char error[64]);
|
||||||
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max);
|
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max);
|
||||||
int unload_amxscript(AMX* amx, void** program);
|
int unload_amxscript(AMX* amx,void** program);
|
||||||
|
void copy_amxmemory(cell* dest,cell* src,int len);
|
||||||
void copy_amxmemory(cell* dest, cell* src, int len);
|
|
||||||
void get_modname(char*);
|
void get_modname(char*);
|
||||||
void print_srvconsole(char *fmt, ...);
|
void print_srvconsole( char *fmt, ... );
|
||||||
void report_error(int code, char* fmt, ...);
|
void report_error( int code, char* fmt, ... );
|
||||||
void* alloc_amxmemory(void**, int size);
|
void* alloc_amxmemory(void**, int size);
|
||||||
void free_amxmemory(void **ptr);
|
void free_amxmemory(void **ptr);
|
||||||
// get_localinfo
|
// 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);
|
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
|
||||||
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...);
|
void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||||
|
|
||||||
enum ModuleCallReason
|
enum ModuleCallReason
|
||||||
{
|
{
|
||||||
ModuleCall_NotCalled = 0, // nothing
|
ModuleCall_NotCalled = 0, // nothing
|
||||||
ModuleCall_Query, // in Query func
|
ModuleCall_Query, // in Query func
|
||||||
ModuleCall_Attach, // in Attach func
|
ModuleCall_Attach, // in Attach func
|
||||||
ModuleCall_Detach, // in Detach func
|
ModuleCall_Detach, // in Detach func
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
||||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||||
|
|
||||||
void Module_CacheFunctions();
|
void Module_CacheFunctions();
|
||||||
void Module_UncacheFunctions();
|
void Module_UncacheFunctions();
|
||||||
|
|
||||||
@ -326,12 +298,11 @@ extern int FF_PluginLog;
|
|||||||
extern int FF_PluginEnd;
|
extern int FF_PluginEnd;
|
||||||
extern int FF_InconsistentFile;
|
extern int FF_InconsistentFile;
|
||||||
extern int FF_ClientAuthorized;
|
extern int FF_ClientAuthorized;
|
||||||
extern int FF_ChangeLevel;
|
|
||||||
extern bool g_coloredmenus;
|
extern bool g_coloredmenus;
|
||||||
|
|
||||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
#ifdef FAKEMETA
|
||||||
|
extern CFakeMeta g_FakeMeta;
|
||||||
#define MM_CVAR2_VERS 13
|
#endif
|
||||||
|
|
||||||
struct func_s
|
struct func_s
|
||||||
{
|
{
|
||||||
@ -339,6 +310,5 @@ struct func_s
|
|||||||
const char *desc;
|
const char *desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enginefuncs_t *g_pEngTable;
|
|
||||||
|
|
||||||
#endif // AMXMODX_H
|
#endif // AMXMODX_H
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
|
|||||||
/* the time() function returns the number of seconds since January 1 1970
|
/* the time() function returns the number of seconds since January 1 1970
|
||||||
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
|
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
|
||||||
*/
|
*/
|
||||||
return (cell)sec1970;
|
return sec1970;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
@ -35,25 +35,24 @@
|
|||||||
/**********************
|
/**********************
|
||||||
****** AMXXFILE ******
|
****** AMXXFILE ******
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKED __attribute__((packed))
|
||||||
#else
|
#else
|
||||||
#define PACKED
|
#define PACKED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __linux__
|
#if defined __linux__
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
#else
|
#else
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
#if defined __TURBOC__
|
#if defined __TURBOC__
|
||||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TableEntry
|
struct TableEntry
|
||||||
{
|
{
|
||||||
mint8_t cellSize;
|
mint8_t cellSize PACKED;
|
||||||
mint32_t origSize PACKED; // contains AMX_HEADER->stp
|
mint32_t origSize PACKED; // contains AMX_HEADER->stp
|
||||||
mint32_t offset PACKED;
|
mint32_t offset PACKED;
|
||||||
};
|
};
|
||||||
@ -74,7 +73,6 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
{
|
{
|
||||||
m_Bh.plugins = NULL;
|
m_Bh.plugins = NULL;
|
||||||
m_AmxxFile = false;
|
m_AmxxFile = false;
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
m_Status = Err_InvalidParam;
|
m_Status = Err_InvalidParam;
|
||||||
@ -83,8 +81,8 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
|
|
||||||
m_Status = Err_None;
|
m_Status = Err_None;
|
||||||
m_CellSize = cellsize;
|
m_CellSize = cellsize;
|
||||||
|
|
||||||
m_pFile = fopen(filename, "rb");
|
m_pFile = fopen(filename, "rb");
|
||||||
|
|
||||||
if (!m_pFile)
|
if (!m_pFile)
|
||||||
{
|
{
|
||||||
m_Status = Err_FileOpen;
|
m_Status = Err_FileOpen;
|
||||||
@ -95,37 +93,28 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
DATAREAD(&magic, sizeof(magic), 1);
|
DATAREAD(&magic, sizeof(magic), 1);
|
||||||
|
|
||||||
m_OldFile = false;
|
m_OldFile = false;
|
||||||
|
if ( magic == 0x524C4542 ) {
|
||||||
if (magic == 0x524C4542)
|
|
||||||
{
|
|
||||||
//we have an invalid, old, RLEB file
|
//we have an invalid, old, RLEB file
|
||||||
m_Status = Err_OldFile;
|
m_Status = Err_OldFile;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
} else if ( magic == MAGIC_HEADER2 ) {
|
||||||
else if (magic == MAGIC_HEADER2)
|
|
||||||
{
|
|
||||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
||||||
|
if (m_Bh.version != MAGIC_VERSION)
|
||||||
if (m_Bh.version > MAGIC_VERSION)
|
|
||||||
{
|
{
|
||||||
m_Status = Err_OldFile;
|
m_Status = Err_OldFile;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_AmxxFile = true;
|
m_AmxxFile = true;
|
||||||
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
||||||
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
||||||
PluginEntry *pe;
|
PluginEntry *pe;
|
||||||
m_SectionHdrOffset = 0;
|
m_SectionHdrOffset = 0;
|
||||||
m_Entry = -1;
|
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]);
|
pe = &(m_Bh.plugins[i]);
|
||||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
||||||
@ -134,32 +123,26 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
||||||
DATAREAD(&pe->offs, 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]);
|
pe = &(m_Bh.plugins[i]);
|
||||||
|
|
||||||
if (pe->cellsize == m_CellSize)
|
if (pe->cellsize == m_CellSize)
|
||||||
{
|
{
|
||||||
m_Entry = i;
|
m_Entry = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Entry == -1)
|
if (m_Entry == -1)
|
||||||
{
|
{
|
||||||
m_Status = Err_SectionNotFound;
|
m_Status = Err_SectionNotFound;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pe = &(m_Bh.plugins[m_Entry]);
|
pe = &(m_Bh.plugins[m_Entry]);
|
||||||
m_SectionLength = pe->disksize;
|
m_SectionLength = pe->disksize;
|
||||||
}
|
} else if (magic == MAGIC_HEADER) {
|
||||||
else if (magic == MAGIC_HEADER)
|
|
||||||
{
|
|
||||||
// try to find the section
|
// try to find the section
|
||||||
mint8_t numOfPlugins;
|
mint8_t numOfPlugins;
|
||||||
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
|
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
|
||||||
@ -168,7 +151,6 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
|
|
||||||
m_SectionHdrOffset = 0;
|
m_SectionHdrOffset = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
|
for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
|
||||||
{
|
{
|
||||||
DATAREAD(&entry, sizeof(entry), 1);
|
DATAREAD(&entry, sizeof(entry), 1);
|
||||||
@ -178,7 +160,6 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_SectionHdrOffset)
|
if (!m_SectionHdrOffset)
|
||||||
{
|
{
|
||||||
m_Status = Err_SectionNotFound;
|
m_Status = Err_SectionNotFound;
|
||||||
@ -188,13 +169,15 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compute section length
|
// compute section length
|
||||||
if ((i + 1) < static_cast<int>(numOfPlugins))
|
if ((i+1) < static_cast<int>(numOfPlugins))
|
||||||
{
|
{
|
||||||
// there is a next section
|
// there is a next section
|
||||||
TableEntry nextEntry;
|
TableEntry nextEntry;
|
||||||
DATAREAD(&nextEntry, sizeof(nextEntry), 1);
|
DATAREAD(&nextEntry, sizeof(nextEntry), 1);
|
||||||
m_SectionLength = nextEntry.offset - entry.offset;
|
m_SectionLength = nextEntry.offset - entry.offset;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fseek(m_pFile, 0, SEEK_END);
|
fseek(m_pFile, 0, SEEK_END);
|
||||||
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
|
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
|
||||||
}
|
}
|
||||||
@ -204,7 +187,6 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
rewind(m_pFile);
|
rewind(m_pFile);
|
||||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||||
amx_Align16(&hdr.magic);
|
amx_Align16(&hdr.magic);
|
||||||
|
|
||||||
if (hdr.magic == AMX_MAGIC)
|
if (hdr.magic == AMX_MAGIC)
|
||||||
{
|
{
|
||||||
if (cellsize != 4)
|
if (cellsize != 4)
|
||||||
@ -212,19 +194,18 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
m_Status = Err_SectionNotFound;
|
m_Status = Err_SectionNotFound;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_OldFile = true;
|
m_OldFile = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// no known file format
|
// no known file format
|
||||||
m_Status = Err_FileInvalid;
|
m_Status = Err_FileInvalid;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,10 +218,9 @@ CAmxxReader::~CAmxxReader()
|
|||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Bh.plugins)
|
if (m_Bh.plugins)
|
||||||
{
|
{
|
||||||
delete [] m_Bh.plugins;
|
delete m_Bh.plugins;
|
||||||
m_Bh.plugins = NULL;
|
m_Bh.plugins = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -276,16 +256,11 @@ size_t CAmxxReader::GetBufferSize()
|
|||||||
AMX_HEADER hdr;
|
AMX_HEADER hdr;
|
||||||
DATAREAD(&hdr, sizeof(hdr), 1);
|
DATAREAD(&hdr, sizeof(hdr), 1);
|
||||||
fseek(m_pFile, save, SEEK_SET);
|
fseek(m_pFile, save, SEEK_SET);
|
||||||
|
|
||||||
return hdr.stp;
|
return hdr.stp;
|
||||||
}
|
} else if (m_AmxxFile) {
|
||||||
else if (m_AmxxFile)
|
|
||||||
{
|
|
||||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||||
|
|
||||||
if (pe->imagesize > pe->memsize)
|
if (pe->imagesize > pe->memsize)
|
||||||
return pe->imagesize + 1;
|
return pe->imagesize + 1;
|
||||||
|
|
||||||
return pe->memsize + 1;
|
return pe->memsize + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,13 +269,12 @@ size_t CAmxxReader::GetBufferSize()
|
|||||||
TableEntry entry;
|
TableEntry entry;
|
||||||
DATAREAD(&entry, sizeof(entry), 1);
|
DATAREAD(&entry, sizeof(entry), 1);
|
||||||
fseek(m_pFile, save, SEEK_SET);
|
fseek(m_pFile, save, SEEK_SET);
|
||||||
|
|
||||||
return entry.origSize + 1; // +1 : safe
|
return entry.origSize + 1; // +1 : safe
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef DATAREAD
|
#undef DATAREAD
|
||||||
#define DATAREAD(addr, itemsize, itemcount) \
|
#define DATAREAD(addr, itemsize, itemcount) \
|
||||||
if (fread(addr, itemsize, itemcount, m_pFile) != static_cast<size_t>(itemcount)) \
|
if (fread(addr, itemsize, itemcount, m_pFile) != itemcount) \
|
||||||
{ \
|
{ \
|
||||||
if (feof(m_pFile)) \
|
if (feof(m_pFile)) \
|
||||||
m_Status = Err_FileInvalid; \
|
m_Status = Err_FileInvalid; \
|
||||||
@ -324,26 +298,22 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
|||||||
rewind(m_pFile);
|
rewind(m_pFile);
|
||||||
DATAREAD(buffer, 1, filesize);
|
DATAREAD(buffer, 1, filesize);
|
||||||
m_Status = Err_None;
|
m_Status = Err_None;
|
||||||
|
|
||||||
return m_Status;
|
return m_Status;
|
||||||
}
|
} else if (m_AmxxFile) {
|
||||||
else if (m_AmxxFile)
|
|
||||||
{
|
|
||||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||||
char *tempBuffer = new char[m_SectionLength + 1];
|
char *tempBuffer = new char[m_SectionLength + 1];
|
||||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
fseek(m_pFile, pe->offs, SEEK_SET);
|
||||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
||||||
uLongf destLen = GetBufferSize();
|
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;
|
delete [] tempBuffer;
|
||||||
|
|
||||||
if (result != Z_OK)
|
if (result != Z_OK)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||||
m_Status = Err_Decompress;
|
m_Status = Err_Decompress;
|
||||||
return Err_Decompress;
|
return Err_Decompress;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err_None;
|
return Err_None;
|
||||||
} else {
|
} else {
|
||||||
// new file type: go to the section table entry
|
// new file type: go to the section table entry
|
||||||
@ -358,17 +328,15 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
|||||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||||
// decompress
|
// decompress
|
||||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
int result = uncompress((Bytef *)buffer, &destLen,
|
||||||
|
(Bytef *)tempBuffer, m_SectionLength);
|
||||||
delete [] tempBuffer;
|
delete [] tempBuffer;
|
||||||
|
|
||||||
if (result != Z_OK)
|
if (result != Z_OK)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||||
m_Status = Err_Decompress;
|
m_Status = Err_Decompress;
|
||||||
|
|
||||||
return Err_Decompress;
|
return Err_Decompress;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err_None;
|
return Err_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public:
|
|||||||
Error GetStatus(); // Get the current status
|
Error GetStatus(); // Get the current status
|
||||||
size_t GetBufferSize(); // Get the size for the buffer
|
size_t GetBufferSize(); // Get the size for the buffer
|
||||||
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
||||||
inline bool IsOldFile() const { return m_OldFile; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __AMXXFILE_H__
|
#endif // __AMXXFILE_H__
|
||||||
|
|
||||||
|
@ -36,20 +36,18 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CLog::CLog()
|
CLog::CLog()
|
||||||
{
|
{
|
||||||
m_LogType = 0;
|
m_LogType = 0;
|
||||||
m_LogFile.clear();
|
m_LogFile.clear();
|
||||||
m_FoundError = false;
|
|
||||||
m_LoggedErrMap = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLog::~CLog()
|
CLog::~CLog()
|
||||||
@ -63,7 +61,6 @@ void CLog::CloseFile()
|
|||||||
if (!m_LogFile.empty())
|
if (!m_LogFile.empty())
|
||||||
{
|
{
|
||||||
FILE *fp = fopen(m_LogFile.c_str(), "r");
|
FILE *fp = fopen(m_LogFile.c_str(), "r");
|
||||||
|
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -80,7 +77,6 @@ void CLog::CloseFile()
|
|||||||
fprintf(fp, "L %s: %s\n", date, "Log file closed.");
|
fprintf(fp, "L %s: %s\n", date, "Log file closed.");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LogFile.clear();
|
m_LogFile.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,36 +84,29 @@ void CLog::CloseFile()
|
|||||||
void CLog::CreateNewFile()
|
void CLog::CreateNewFile()
|
||||||
{
|
{
|
||||||
CloseFile();
|
CloseFile();
|
||||||
|
|
||||||
// build filename
|
// build filename
|
||||||
time_t td;
|
time_t td;
|
||||||
time(&td);
|
time(&td);
|
||||||
tm *curTime = localtime(&td);
|
tm *curTime = localtime(&td);
|
||||||
|
|
||||||
char file[256];
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
|
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||||
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
|
|
||||||
|
|
||||||
if (!pTmpFile)
|
if (!pTmpFile)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fclose(pTmpFile);
|
fclose(pTmpFile);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
m_LogFile.assign(file);
|
|
||||||
|
|
||||||
// Log logfile start
|
// Log logfile start
|
||||||
FILE *fp = fopen(m_LogFile.c_str(), "w");
|
FILE *fp = fopen(m_LogFile.c_str(), "w");
|
||||||
|
|
||||||
if (!fp)
|
if (!fp)
|
||||||
{
|
{
|
||||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
|
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
|
||||||
SET_LOCALINFO("amxx_logging", "0");
|
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);
|
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);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
@ -134,13 +123,12 @@ void CLog::MapChange()
|
|||||||
// create dir if not existing
|
// create dir if not existing
|
||||||
char file[256];
|
char file[256];
|
||||||
#ifdef __linux
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
|
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
|
||||||
|
|
||||||
if (m_LogType < 0 || m_LogType > 3)
|
if (m_LogType < 0 || m_LogType > 3)
|
||||||
{
|
{
|
||||||
SET_LOCALINFO("amxx_logging", "1");
|
SET_LOCALINFO("amxx_logging", "1");
|
||||||
@ -148,23 +136,22 @@ void CLog::MapChange()
|
|||||||
print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1...");
|
print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1...");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LoggedErrMap = false;
|
|
||||||
|
|
||||||
if (m_LogType == 2)
|
if (m_LogType == 2)
|
||||||
{
|
{
|
||||||
// create new logfile
|
// create new logfile
|
||||||
CreateNewFile();
|
CreateNewFile();
|
||||||
} else if (m_LogType == 1) {
|
|
||||||
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (m_LogType == 1)
|
||||||
|
{
|
||||||
|
Log("-------- Mapchange --------");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::Log(const char *fmt, ...)
|
void CLog::Log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
static char file[256];
|
static char file[256];
|
||||||
|
|
||||||
if (m_LogType == 1 || m_LogType == 2)
|
if (m_LogType == 1 || m_LogType == 2)
|
||||||
{
|
{
|
||||||
// get time
|
// get time
|
||||||
@ -191,7 +178,6 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
CreateNewFile();
|
CreateNewFile();
|
||||||
pF = fopen(m_LogFile.c_str(), "a+");
|
pF = fopen(m_LogFile.c_str(), "a+");
|
||||||
|
|
||||||
if (!pF)
|
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());
|
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());
|
||||||
@ -199,16 +185,19 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
return;
|
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);
|
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+");
|
pF = fopen(file, "a+");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pF)
|
if (pF)
|
||||||
{
|
{
|
||||||
fprintf(pF, "L %s: %s\n", date, msg);
|
fprintf(pF, "L %s: %s\n", date, msg);
|
||||||
fclose(pF);
|
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);
|
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;
|
m_LogType = 0;
|
||||||
return;
|
return;
|
||||||
@ -216,7 +205,9 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
|
|
||||||
// print on server console
|
// print on server console
|
||||||
print_srvconsole("L %s: %s\n", date, msg);
|
print_srvconsole("L %s: %s\n", date, msg);
|
||||||
} else if (m_LogType == 3) {
|
}
|
||||||
|
else if (m_LogType == 3)
|
||||||
|
{
|
||||||
// build message
|
// build message
|
||||||
static char msg_[3072];
|
static char msg_[3072];
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
@ -226,53 +217,3 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
ALERT(at_logged, "%s\n", msg_);
|
ALERT(at_logged, "%s\n", msg_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::LogError(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
static char file[256];
|
|
||||||
|
|
||||||
if (m_FoundError)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get time
|
|
||||||
time_t td;
|
|
||||||
time(&td);
|
|
||||||
tm *curTime = localtime(&td);
|
|
||||||
|
|
||||||
char date[32];
|
|
||||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
|
||||||
|
|
||||||
// msg
|
|
||||||
static char msg[3072];
|
|
||||||
|
|
||||||
va_list arglst;
|
|
||||||
va_start(arglst, fmt);
|
|
||||||
vsnprintf(msg, sizeof(msg)-1, fmt, arglst);
|
|
||||||
va_end(arglst);
|
|
||||||
|
|
||||||
FILE *pF = NULL;
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/error_%02d%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_year - 100);
|
|
||||||
pF = fopen(file, "a+");
|
|
||||||
|
|
||||||
if (pF)
|
|
||||||
{
|
|
||||||
if (!m_LoggedErrMap)
|
|
||||||
{
|
|
||||||
fprintf(pF, "L %s: Start of error session.\n", date);
|
|
||||||
fprintf(pF, "L %s: Info (map \"%s\") (logfile \"error_%02d%02d%02d.log\")\n", date, STRING(gpGlobals->mapname), curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_year - 100);
|
|
||||||
m_LoggedErrMap = true;
|
|
||||||
}
|
|
||||||
fprintf(pF, "L %s: %s\n", date, msg);
|
|
||||||
fclose(pF);
|
|
||||||
} else {
|
|
||||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Error Logging disabled for this map.\n", file);
|
|
||||||
m_FoundError = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print on server console
|
|
||||||
print_srvconsole("L %s: %s\n", date, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -36,20 +36,17 @@ class CLog
|
|||||||
private:
|
private:
|
||||||
String m_LogFile;
|
String m_LogFile;
|
||||||
int m_LogType;
|
int m_LogType;
|
||||||
bool m_FoundError;
|
|
||||||
bool m_LoggedErrMap;
|
|
||||||
|
|
||||||
void GetLastFile(int &outMonth, int &outDay, String &outFilename);
|
void GetLastFile(int &outMonth, int &outDay, String &outFilename);
|
||||||
void UseFile(const String &fileName);
|
void UseFile(const String &fileName);
|
||||||
public:
|
public:
|
||||||
CLog();
|
CLog();
|
||||||
~CLog();
|
~CLog();
|
||||||
|
|
||||||
void CreateNewFile();
|
void CreateNewFile();
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
void MapChange();
|
void MapChange();
|
||||||
void Log(const char *fmt, ...);
|
void Log(const char *fmt, ...);
|
||||||
void LogError(const char *fmt, ...);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __AMXXLOG_H__
|
#endif // __AMXXLOG_H__
|
||||||
|
|
||||||
|
@ -1,362 +0,0 @@
|
|||||||
#if defined BINLOG_ENABLED
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "amxmodx.h"
|
|
||||||
#include "binlog.h"
|
|
||||||
#include "debugger.h"
|
|
||||||
|
|
||||||
BinLog g_BinLog;
|
|
||||||
int g_binlog_level = 0;
|
|
||||||
int g_binlog_maxsize = 0;
|
|
||||||
|
|
||||||
// Helper function to get a filename index
|
|
||||||
#define USHR(x) ((unsigned int)(x)>>1)
|
|
||||||
int LookupFile(AMX_DBG *amxdbg, ucell address)
|
|
||||||
{
|
|
||||||
int high, low, mid;
|
|
||||||
|
|
||||||
high = amxdbg->hdr->files;
|
|
||||||
low = -1;
|
|
||||||
|
|
||||||
while (high - low > 1)
|
|
||||||
{
|
|
||||||
mid = USHR(low + high);
|
|
||||||
if (amxdbg->filetbl[mid]->address <= address)
|
|
||||||
{
|
|
||||||
low = mid;
|
|
||||||
} else {
|
|
||||||
high = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (low == -1)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BinLog::Open()
|
|
||||||
{
|
|
||||||
const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
|
|
||||||
char path[255];
|
|
||||||
build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);
|
|
||||||
|
|
||||||
if (!DirExists(path))
|
|
||||||
{
|
|
||||||
mkdir(path
|
|
||||||
#if defined __linux__
|
|
||||||
, 0755
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if (!DirExists(path))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char file[255];
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);
|
|
||||||
|
|
||||||
unsigned int lastcntr = 0;
|
|
||||||
FILE *lastlog = fopen(file, "rb");
|
|
||||||
if (lastlog)
|
|
||||||
{
|
|
||||||
if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
|
|
||||||
lastcntr = 0;
|
|
||||||
fclose(lastlog);
|
|
||||||
}
|
|
||||||
lastlog = fopen(file, "wb");
|
|
||||||
if (lastlog)
|
|
||||||
{
|
|
||||||
lastcntr++;
|
|
||||||
fwrite(&lastcntr, sizeof(int), 1, lastlog);
|
|
||||||
fclose(lastlog);
|
|
||||||
}
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
|
|
||||||
m_logfile.assign(file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* it's now safe to create the binary log
|
|
||||||
*/
|
|
||||||
FILE *fp = fopen(m_logfile.c_str(), "wb");
|
|
||||||
if (!fp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int magic = BINLOG_MAGIC;
|
|
||||||
short vers = BINLOG_VERSION;
|
|
||||||
char c = sizeof(time_t);
|
|
||||||
fwrite(&magic, sizeof(int), 1, fp);
|
|
||||||
fwrite(&vers, sizeof(short), 1, fp);
|
|
||||||
fwrite(&c, sizeof(char), 1, fp);
|
|
||||||
|
|
||||||
WritePluginDB(fp);
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
m_state = true;
|
|
||||||
|
|
||||||
WriteOp(BinLog_Start, -1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinLog::Close()
|
|
||||||
{
|
|
||||||
WriteOp(BinLog_End, -1);
|
|
||||||
m_state = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinLog::WriteOp(BinLogOp op, int plug, ...)
|
|
||||||
{
|
|
||||||
if (!m_state)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FILE *fp = fopen(m_logfile.c_str(), "ab");
|
|
||||||
if (!fp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (g_binlog_maxsize && op != BinLog_End)
|
|
||||||
{
|
|
||||||
fseek(fp, 0, SEEK_END);
|
|
||||||
if (ftell(fp) > (g_binlog_maxsize * (1024 * 1024)))
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
Close();
|
|
||||||
Open();
|
|
||||||
fp = fopen(m_logfile.c_str(), "ab");
|
|
||||||
if (!fp)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char c = static_cast<char>(op);
|
|
||||||
time_t t = time(NULL);
|
|
||||||
float gt = gpGlobals->time;
|
|
||||||
fwrite(&c, sizeof(char), 1, fp);
|
|
||||||
fwrite(&t, sizeof(time_t), 1, fp);
|
|
||||||
fwrite(>, sizeof(float), 1, fp);
|
|
||||||
fwrite(&plug, sizeof(int), 1, fp);
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, plug);
|
|
||||||
|
|
||||||
AMX *amx = NULL;
|
|
||||||
bool debug = false;
|
|
||||||
AMX_DBG *dbg = NULL;
|
|
||||||
CPluginMngr::CPlugin *pl = NULL;
|
|
||||||
|
|
||||||
if (plug != -1)
|
|
||||||
{
|
|
||||||
pl = g_plugins.findPlugin(plug);
|
|
||||||
if ((debug = pl->isDebug()))
|
|
||||||
{
|
|
||||||
amx = pl->getAMX();
|
|
||||||
dbg = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER])->m_pAmxDbg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case BinLog_Registered:
|
|
||||||
{
|
|
||||||
const char *title = va_arg(ap, const char *);
|
|
||||||
const char *vers = va_arg(ap, const char *);
|
|
||||||
c = (char)strlen(title);
|
|
||||||
fwrite(&c, sizeof(char), 1, fp);
|
|
||||||
fwrite(title, sizeof(char), c+1, fp);
|
|
||||||
c = (char)strlen(vers);
|
|
||||||
fwrite(&c, sizeof(char), 1 ,fp);
|
|
||||||
fwrite(vers, sizeof(char), c+1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_NativeCall:
|
|
||||||
{
|
|
||||||
int file;
|
|
||||||
int native = va_arg(ap, int);
|
|
||||||
int params = va_arg(ap, int);
|
|
||||||
fwrite(&native, sizeof(int), 1, fp);
|
|
||||||
fwrite(¶ms, sizeof(int), 1, fp);
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
file = LookupFile(dbg, amx->cip);
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
} else {
|
|
||||||
file = 0;
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_NativeRet:
|
|
||||||
{
|
|
||||||
cell retval = va_arg(ap, cell);
|
|
||||||
fwrite(&retval, sizeof(cell), 1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_NativeError:
|
|
||||||
{
|
|
||||||
int err = va_arg(ap, int);
|
|
||||||
const char *msg = va_arg(ap, const char *);
|
|
||||||
short len = (short)strlen(msg);
|
|
||||||
fwrite(&err, sizeof(int), 1, fp);
|
|
||||||
fwrite(&len, sizeof(short), 1, fp);
|
|
||||||
fwrite(msg, sizeof(char), len+1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_CallPubFunc:
|
|
||||||
{
|
|
||||||
int file;
|
|
||||||
int num = va_arg(ap, int);
|
|
||||||
fwrite(&num, sizeof(int), 1, fp);
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
file = LookupFile(dbg, amx->cip);
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
} else {
|
|
||||||
file = 0;
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_SetLine:
|
|
||||||
{
|
|
||||||
int file;
|
|
||||||
int line = va_arg(ap, int);
|
|
||||||
fwrite(&line, sizeof(int), 1, fp);
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
file = LookupFile(dbg, amx->cip);
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
} else {
|
|
||||||
file = 0;
|
|
||||||
fwrite(&file, sizeof(int), 1, fp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_FormatString:
|
|
||||||
{
|
|
||||||
int param = va_arg(ap, int);
|
|
||||||
int maxlen = va_arg(ap, int);
|
|
||||||
const char *str = va_arg(ap, const char *);
|
|
||||||
short len = (short)strlen(str);
|
|
||||||
fwrite(¶m, sizeof(int), 1, fp);
|
|
||||||
fwrite(&maxlen, sizeof(int), 1, fp);
|
|
||||||
fwrite(&len, sizeof(short), 1, fp);
|
|
||||||
fwrite(str, sizeof(char), len+1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_NativeParams:
|
|
||||||
{
|
|
||||||
cell *params = va_arg(ap, cell *);
|
|
||||||
cell num = params[0] / sizeof(cell);
|
|
||||||
fwrite(&num, sizeof(cell), 1, fp);
|
|
||||||
for (cell i=1; i<=num; i++)
|
|
||||||
fwrite(&(params[i]), sizeof(cell), 1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_GetString:
|
|
||||||
{
|
|
||||||
cell addr = va_arg(ap, cell);
|
|
||||||
const char *str = va_arg(ap, const char *);
|
|
||||||
short len = (short)strlen(str);
|
|
||||||
fwrite(&addr, sizeof(cell), 1, fp);
|
|
||||||
fwrite(&len, sizeof(short), 1, fp);
|
|
||||||
fwrite(str, sizeof(char), len+1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BinLog_SetString:
|
|
||||||
{
|
|
||||||
cell addr = va_arg(ap, cell);
|
|
||||||
int maxlen = va_arg(ap, int);
|
|
||||||
const char *str = va_arg(ap, const char *);
|
|
||||||
short len = (short)strlen(str);
|
|
||||||
fwrite(&addr, sizeof(cell), 1, fp);
|
|
||||||
fwrite(&maxlen, sizeof(int), 1, fp);
|
|
||||||
fwrite(&len, sizeof(short), 1, fp);
|
|
||||||
fwrite(str, sizeof(char), len+1, fp);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinLog::WritePluginDB(FILE *fp)
|
|
||||||
{
|
|
||||||
int num = g_plugins.getPluginsNum();
|
|
||||||
fwrite(&num, sizeof(int), 1, fp);
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin *pl;
|
|
||||||
char c;
|
|
||||||
unsigned char len;
|
|
||||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
|
||||||
{
|
|
||||||
pl = &(*iter);
|
|
||||||
if (pl->isValid())
|
|
||||||
c = 1;
|
|
||||||
else
|
|
||||||
c = 0;
|
|
||||||
if (c && pl->isDebug())
|
|
||||||
c = 2;
|
|
||||||
fwrite(&c, sizeof(char), 1, fp);
|
|
||||||
if (c)
|
|
||||||
{
|
|
||||||
Debugger *pd = NULL;
|
|
||||||
len = (char)strlen(pl->getName());
|
|
||||||
fwrite(&len, sizeof(char), 1, fp);
|
|
||||||
len++;
|
|
||||||
fwrite(pl->getName(), sizeof(char), len, fp);
|
|
||||||
int natives, publics, files;
|
|
||||||
AMX *amx = pl->getAMX();
|
|
||||||
// Write the number of Filenames
|
|
||||||
if (c == 2)
|
|
||||||
{
|
|
||||||
pd = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER]);
|
|
||||||
files = pd->m_pAmxDbg->hdr->files;
|
|
||||||
fwrite(&files, sizeof(int), 1, fp);
|
|
||||||
}
|
|
||||||
amx_NumNatives(amx, &natives);
|
|
||||||
amx_NumPublics(amx, &publics);
|
|
||||||
fwrite(&natives, sizeof(int), 1, fp);
|
|
||||||
fwrite(&publics, sizeof(int), 1, fp);
|
|
||||||
char name[34];
|
|
||||||
// Write the Filenames to the binfile
|
|
||||||
if (c == 2)
|
|
||||||
{
|
|
||||||
AMX_DBG_FILE **ftable = pd->m_pAmxDbg->filetbl;
|
|
||||||
for (int i=0; i<files; i++)
|
|
||||||
{
|
|
||||||
len = (char)strlen(ftable[i]->name);
|
|
||||||
fwrite(&len, sizeof(char), 1, fp);
|
|
||||||
len++;
|
|
||||||
fwrite(ftable[i]->name, sizeof(char), len, fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i=0; i<natives; i++)
|
|
||||||
{
|
|
||||||
amx_GetNative(amx, i, name);
|
|
||||||
len = (char)strlen(name);
|
|
||||||
fwrite(&len, sizeof(char), 1, fp);
|
|
||||||
len++;
|
|
||||||
fwrite(name, sizeof(char), len, fp);
|
|
||||||
}
|
|
||||||
for (int i=0; i<publics; i++)
|
|
||||||
{
|
|
||||||
amx_GetPublic(amx, i, name);
|
|
||||||
len = (char)strlen(name);
|
|
||||||
fwrite(&len, sizeof(char), 1, fp);
|
|
||||||
len++;
|
|
||||||
fwrite(name, sizeof(char), len, fp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char empty[] = " ";
|
|
||||||
len = 1;
|
|
||||||
fwrite(&len, sizeof(char), 1, fp);
|
|
||||||
fwrite(empty, sizeof(char), len, fp);
|
|
||||||
int no = 0;
|
|
||||||
fwrite(&no, sizeof(int), 1, fp);
|
|
||||||
fwrite(&no, sizeof(int), 1, fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //BINLOG_ENABLED
|
|
@ -1,84 +0,0 @@
|
|||||||
#ifndef _INCLUDE_BINLOG_H
|
|
||||||
#define _INCLUDE_BINLOG_H
|
|
||||||
|
|
||||||
#if defined BINLOG_ENABLED
|
|
||||||
|
|
||||||
#include "CString.h"
|
|
||||||
|
|
||||||
#define BINLOG_MAGIC 0x414D424C
|
|
||||||
#define BINLOG_VERSION 0x0300
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format of binlog:
|
|
||||||
* uint32 magic
|
|
||||||
* uint16 version
|
|
||||||
* uint8 sizeof(time_t)
|
|
||||||
* uint32 num plugins
|
|
||||||
* [
|
|
||||||
* uint8 status codes
|
|
||||||
* str[int8] filename
|
|
||||||
* if(status==2)
|
|
||||||
* uint32 num filenames
|
|
||||||
* uint32 num natives
|
|
||||||
* uint32 num publics
|
|
||||||
* if (status==2)
|
|
||||||
* [
|
|
||||||
* str[uint8] file name
|
|
||||||
* ]
|
|
||||||
* [
|
|
||||||
* str[uint8] native name
|
|
||||||
* ]
|
|
||||||
* [
|
|
||||||
* str[uint8] public name
|
|
||||||
* ]
|
|
||||||
* ]
|
|
||||||
* [
|
|
||||||
* uint8 operation code
|
|
||||||
* time_t realtime
|
|
||||||
* float gametime
|
|
||||||
* int32 plugin id
|
|
||||||
* <extra info>
|
|
||||||
* ]
|
|
||||||
* If filename id is 0 skip as plugin was not in debug mode, if -1 there was an error.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum BinLogOp
|
|
||||||
{
|
|
||||||
BinLog_Start=1,
|
|
||||||
BinLog_End,
|
|
||||||
BinLog_NativeCall, //<int32 native id> <int32_t num_params> <int32_t filename id>
|
|
||||||
BinLog_NativeError, //<int32 errornum> <str[int16] string>
|
|
||||||
BinLog_NativeRet, //<cell value>
|
|
||||||
BinLog_CallPubFunc, //<int32 public id> <int32_t filename id>
|
|
||||||
BinLog_SetLine, //<int32 line no#> <int32_t filename id>
|
|
||||||
BinLog_Registered, //<string title> <string version>
|
|
||||||
BinLog_FormatString, //<int32 param#> <int32 maxlen> <str[int16] string>
|
|
||||||
BinLog_NativeParams, //<int32 num> <cell ...>
|
|
||||||
BinLog_GetString, //<cell addr> <string[int16]>
|
|
||||||
BinLog_SetString, //<cell addr> <int maxlen> <string[int16]>
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinLog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BinLog() : m_state(false)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
bool Open();
|
|
||||||
void Close();
|
|
||||||
void WriteOp(BinLogOp op, int plug, ...);
|
|
||||||
private:
|
|
||||||
void WritePluginDB(FILE *fp);
|
|
||||||
private:
|
|
||||||
String m_logfile;
|
|
||||||
bool m_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern BinLog g_BinLog;
|
|
||||||
extern int g_binlog_level;
|
|
||||||
extern int g_binlog_maxsize;
|
|
||||||
|
|
||||||
#endif //BINLOG_ENABLED
|
|
||||||
|
|
||||||
#endif //_INCLUDE_BINLOG_H
|
|
1019
amxmodx/debugger.cpp
1019
amxmodx/debugger.cpp
File diff suppressed because it is too large
Load Diff
@ -1,201 +0,0 @@
|
|||||||
/* 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), next(NULL), prev(NULL), used(false) {};
|
|
||||||
|
|
||||||
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, bool isClass=false);
|
|
||||||
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_
|
|
384
amxmodx/emsg.cpp
384
amxmodx/emsg.cpp
@ -57,235 +57,208 @@ WeaponsVault g_weaponsData[MAX_WEAPONS];
|
|||||||
|
|
||||||
void Client_VGUIMenu(void* mValue)
|
void Client_VGUIMenu(void* mValue)
|
||||||
{
|
{
|
||||||
if (!mPlayer) return;
|
if (!mPlayer) return;
|
||||||
|
switch (mState++){
|
||||||
mPlayer->vgui = true;
|
case 0:
|
||||||
|
mPlayer->menu = -(*(int*)mValue);
|
||||||
switch (mState++)
|
break;
|
||||||
{
|
case 1:
|
||||||
case 0:
|
mPlayer->keys = *(int*)mValue;
|
||||||
mPlayer->menu = -(*(int*)mValue);
|
}
|
||||||
mPlayer->newmenu = -1;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mPlayer->keys = *(int*)mValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_ShowMenu(void* mValue)
|
void Client_ShowMenu(void* mValue)
|
||||||
{
|
{
|
||||||
if (!mPlayer) return;
|
if (!mPlayer) return;
|
||||||
|
switch (mState++){
|
||||||
mPlayer->vgui = true;
|
case 0:
|
||||||
|
mPlayer->keys = *(int*)mValue;
|
||||||
switch (mState++)
|
break;
|
||||||
{
|
case 3:
|
||||||
case 0:
|
mPlayer->menu = g_menucmds.findMenuId( (char*)mValue );
|
||||||
mPlayer->keys = *(int*)mValue;
|
}
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
{
|
|
||||||
mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
|
|
||||||
mPlayer->newmenu = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool g_bmod_tfc;
|
|
||||||
void Client_TeamInfo(void* mValue)
|
void Client_TeamInfo(void* mValue)
|
||||||
{
|
{
|
||||||
if (mPlayer && !g_bmod_tfc) return;
|
if (mPlayer) return;
|
||||||
static int index;
|
static int index;
|
||||||
|
switch (mState++) {
|
||||||
switch (mState++)
|
case 0:
|
||||||
{
|
index = *(int*)mValue;
|
||||||
case 0:
|
break;
|
||||||
index = *(int*)mValue;
|
case 1:
|
||||||
break;
|
if ( index < 1 || index > gpGlobals->maxClients ) break;
|
||||||
case 1:
|
char* msg = (char*)mValue;
|
||||||
if (index < 1 || index > gpGlobals->maxClients) break;
|
g_players[ index ].team.assign( msg );
|
||||||
char* msg = (char*)mValue;
|
g_teamsIds.registerTeam( msg , -1 );
|
||||||
g_players[index].team.assign(msg);
|
}
|
||||||
g_teamsIds.registerTeam(msg, -1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_TextMsg(void* mValue)
|
void Client_TextMsg(void* mValue)
|
||||||
{
|
{
|
||||||
if (mPlayer) return;
|
if ( mPlayer ) return;
|
||||||
|
switch (mState++) {
|
||||||
switch (mState++)
|
case 1:{
|
||||||
{
|
char * msg = (char*)mValue;
|
||||||
case 1:
|
if (!msg) break;
|
||||||
{
|
if ( !strncmp("#Game_C", msg , 7) ) {
|
||||||
char * msg = (char*)mValue;
|
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
|
||||||
if (!msg) break;
|
// g_endround_time = gpGlobals->time;
|
||||||
|
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
|
||||||
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:
|
else if (!strncmp("#Game_w", msg , 7) ) {
|
||||||
{
|
g_game_timeleft = -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:
|
else if ( !strncmp("#game_clan_s", msg , 12) ){
|
||||||
{
|
g_game_timeleft = -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;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:{
|
||||||
|
char * msg = (char*)mValue;
|
||||||
|
if (!msg) break;
|
||||||
|
if (g_game_timeleft == -2 ){
|
||||||
|
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
|
||||||
|
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
|
||||||
|
}
|
||||||
|
else if ( g_game_timeleft == -3 )
|
||||||
|
g_game_restarting = atoi( msg ) * 60;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:{
|
||||||
|
char * msg = (char*)mValue;
|
||||||
|
if (!msg) break;
|
||||||
|
if ( g_game_timeleft != -3 ) break;
|
||||||
|
g_game_restarting += atoi( msg );
|
||||||
|
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_WeaponList(void* mValue)
|
void Client_WeaponList(void* mValue)
|
||||||
{
|
{
|
||||||
static int wpnList = 0;
|
static int wpnList = 0;
|
||||||
//static int wpnList2;
|
//static int wpnList2;
|
||||||
static int iSlot;
|
static int iSlot;
|
||||||
static const char* wpnName;
|
static const char* wpnName;
|
||||||
|
switch (mState++) {
|
||||||
|
case 0:
|
||||||
|
wpnName = (char*)mValue;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
iSlot = *(int*)mValue;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
int iId = *(int*)mValue;
|
||||||
|
/*int* blocker;
|
||||||
|
|
||||||
|
int iwpn = iId;
|
||||||
|
|
||||||
switch (mState++)
|
if (iId > 31) {
|
||||||
{
|
iwpn -= 31;
|
||||||
case 0:
|
blocker = &wpnList2;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
blocker = &wpnList;*/
|
||||||
|
|
||||||
|
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
|
||||||
|
break;
|
||||||
|
wpnList |= (1<<iId);
|
||||||
|
g_weaponsData[iId].iId = iId;
|
||||||
|
g_weaponsData[iId].ammoSlot = iSlot;
|
||||||
|
g_weaponsData[iId].fullName.assign(wpnName);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_CurWeapon(void* mValue)
|
void Client_CurWeapon(void* mValue)
|
||||||
{
|
{
|
||||||
static int iState;
|
static int iState;
|
||||||
static int iId;
|
static int iId;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
case 0:
|
||||||
{
|
iState = *(int*)mValue;
|
||||||
case 0:
|
break;
|
||||||
iState = *(int*)mValue;
|
case 1:
|
||||||
break;
|
if (!iState) break;
|
||||||
case 1:
|
iId = *(int*)mValue;
|
||||||
if (!iState) break;
|
break;
|
||||||
iId = *(int*)mValue;
|
case 2:
|
||||||
break;
|
if (!mPlayer) return;
|
||||||
case 2:
|
if (!iState || (iId < 1 || iId >= MAX_WEAPONS ) ) break;
|
||||||
if (!mPlayer) return;
|
mPlayer->weapons[iId].clip = *(int*)mValue;
|
||||||
if (!iState || (iId < 1 || iId >= MAX_WEAPONS)) break;
|
mPlayer->current = iId;
|
||||||
mPlayer->weapons[iId].clip = *(int*)mValue;
|
mPlayer->lastHit = mPlayer->lastTrace;
|
||||||
mPlayer->current = iId;
|
}
|
||||||
mPlayer->lastHit = mPlayer->lastTrace;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_AmmoX(void* mValue)
|
void Client_AmmoX(void* mValue)
|
||||||
{
|
{
|
||||||
static int iAmmo;
|
|
||||||
|
static int iAmmo;
|
||||||
switch (mState++)
|
switch (mState++){
|
||||||
{
|
case 0:
|
||||||
case 0:
|
iAmmo = *(int*)mValue;
|
||||||
iAmmo = *(int*)mValue;
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 1:
|
if (!mPlayer) return;
|
||||||
if (!mPlayer) return;
|
for(int i=1;i<MAX_WEAPONS;++i)
|
||||||
for (int i = 1; i < MAX_WEAPONS; ++i)
|
if (iAmmo == g_weaponsData[i].ammoSlot)
|
||||||
if (iAmmo == g_weaponsData[i].ammoSlot)
|
mPlayer->weapons[i].ammo = *(int*)mValue;
|
||||||
mPlayer->weapons[i].ammo = *(int*)mValue;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_AmmoPickup(void* mValue)
|
void Client_AmmoPickup(void* mValue)
|
||||||
{
|
{
|
||||||
static int iSlot;
|
static int iSlot;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
case 0:
|
||||||
{
|
iSlot = *(int*)mValue;
|
||||||
case 0:
|
break;
|
||||||
iSlot = *(int*)mValue;
|
case 1:
|
||||||
break;
|
if (!mPlayer) return;
|
||||||
case 1:
|
for(int i=1;i<MAX_WEAPONS;++i)
|
||||||
if (!mPlayer) return;
|
if (g_weaponsData[i].ammoSlot==iSlot)
|
||||||
for (int i = 1; i < MAX_WEAPONS; ++i)
|
mPlayer->weapons[i].ammo += *(int*)mValue;
|
||||||
if (g_weaponsData[i].ammoSlot==iSlot)
|
}
|
||||||
mPlayer->weapons[i].ammo += *(int*)mValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_ScoreInfo(void* mValue)
|
void Client_ScoreInfo(void* mValue)
|
||||||
{
|
{
|
||||||
static int index;
|
static int index;
|
||||||
static int deaths;
|
static int deaths;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
case 0:
|
||||||
{
|
index = *(int*)mValue;
|
||||||
case 0:
|
break;
|
||||||
index = *(int*)mValue;
|
case 2:
|
||||||
break;
|
deaths = *(int*)mValue;
|
||||||
case 2:
|
break;
|
||||||
deaths = *(int*)mValue;
|
case 4:
|
||||||
break;
|
if ( index < 1 || index > gpGlobals->maxClients ) break;
|
||||||
case 4:
|
CPlayer*pPlayer = GET_PLAYER_POINTER_I( index );
|
||||||
if (index < 1 || index > gpGlobals->maxClients) break;
|
pPlayer->deaths = deaths;
|
||||||
CPlayer*pPlayer = GET_PLAYER_POINTER_I(index);
|
pPlayer->teamId = *(int*)mValue;
|
||||||
pPlayer->deaths = deaths;
|
if ( g_teamsIds.isNewTeam() )
|
||||||
pPlayer->teamId = *(int*)mValue;
|
g_teamsIds.registerTeam( pPlayer->team.c_str() , pPlayer->teamId );
|
||||||
if (g_teamsIds.isNewTeam())
|
}
|
||||||
g_teamsIds.registerTeam(pPlayer->team.c_str(), pPlayer->teamId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_DamageEnd(void* mValue)
|
void Client_DamageEnd(void* mValue)
|
||||||
{
|
{
|
||||||
CPlayer* dead = mPlayer;
|
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.parserInit( CS_DEATHMSG , &gpGlobals->time , mPlayer = 0, mPlayerIndex = 0 );
|
||||||
g_events.parseValue(dead->death_killer);
|
g_events.parseValue( dead->death_killer );
|
||||||
g_events.parseValue(dead->index);
|
g_events.parseValue( dead->index );
|
||||||
g_events.parseValue(dead->death_headshot);
|
g_events.parseValue( dead->death_headshot );
|
||||||
g_events.parseValue(dead->death_weapon.c_str());
|
g_events.parseValue( dead->death_weapon.c_str() );
|
||||||
g_events.parseValue(dead->death_tk ? 1 : 0);
|
g_events.parseValue( dead->death_tk ? 1 : 0 );
|
||||||
g_events.executeEvents();
|
g_events.executeEvents();
|
||||||
dead->death_killer = 0;
|
dead->death_killer = 0;
|
||||||
}
|
}
|
||||||
@ -299,25 +272,28 @@ void Client_DeathMsg(void* mValue)
|
|||||||
static int victim_id;
|
static int victim_id;
|
||||||
static int hs;
|
static int hs;
|
||||||
|
|
||||||
switch (mState++)
|
switch (mState++){
|
||||||
{
|
case 0:
|
||||||
case 0:
|
killer_id = *(int*)mValue;
|
||||||
killer_id = *(int*)mValue;
|
killer = (killer_id > 0 && killer_id < 33) ?
|
||||||
killer = (killer_id > 0 && killer_id < 33) ? GET_PLAYER_POINTER_I(killer_id) : 0;
|
GET_PLAYER_POINTER_I(killer_id) : 0;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
victim_id = *(int*)mValue;
|
victim_id = *(int*)mValue;
|
||||||
victim = (victim_id > 0 && victim_id < 33) ? GET_PLAYER_POINTER_I(victim_id) : 0;
|
victim = (victim_id > 0 && victim_id < 33) ?
|
||||||
break;
|
GET_PLAYER_POINTER_I(victim_id) : 0;
|
||||||
case 2:
|
break;
|
||||||
hs = *(int*)mValue;
|
case 2:
|
||||||
break;
|
hs = *(int*)mValue;
|
||||||
case 3:
|
break;
|
||||||
if (!killer || !victim) break;
|
case 3:
|
||||||
victim->death_killer = killer_id;
|
|
||||||
victim->death_weapon.assign((char*)mValue);
|
if ( !killer || !victim ) break;
|
||||||
victim->death_headshot = hs;
|
|
||||||
victim->death_tk = (killer->teamId == victim->teamId);
|
victim->death_killer = killer_id;
|
||||||
|
victim->death_weapon.assign((char*)mValue);
|
||||||
|
victim->death_headshot = hs;
|
||||||
|
victim->death_tk = (killer->teamId == victim->teamId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -347,4 +323,4 @@ void Client_ResetHUD(void* mValue)
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
2910
amxmodx/fakemeta.cpp
2910
amxmodx/fakemeta.cpp
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,205 @@
|
|||||||
#ifndef __FAKEMETA_H__
|
#ifndef __FAKEMETA_H__
|
||||||
#define __FAKEMETA_H__
|
#define __FAKEMETA_H__
|
||||||
|
|
||||||
|
#ifndef FAKEMETA
|
||||||
int UnloadMetamodPlugin(void *handle);
|
int UnloadMetamodPlugin(void *handle);
|
||||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||||
|
#else
|
||||||
|
// Fake metamod api for modules
|
||||||
|
|
||||||
|
#include "CList.h"
|
||||||
|
|
||||||
|
// from mplugin.h (metamod)
|
||||||
|
// Flags to indicate current "load" state of plugin.
|
||||||
|
// NOTE: order is important, as greater/less comparisons are made.
|
||||||
|
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)
|
||||||
|
PL_OPENED, // dlopened and queried
|
||||||
|
PL_FAILED, // opened, but failed to attach or unattach
|
||||||
|
PL_RUNNING, // attached and running
|
||||||
|
PL_PAUSED, // attached but paused
|
||||||
|
} PLUG_STATUS;
|
||||||
|
|
||||||
|
// from h_export.h (metamod)
|
||||||
|
// Our GiveFnptrsToDll, called by engine.
|
||||||
|
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t
|
||||||
|
*pengfuncsFromEngine, globalvars_t *pGlobals);
|
||||||
|
|
||||||
|
|
||||||
|
// *** CFakeMeta
|
||||||
|
class CFakeMeta
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// Core tables
|
||||||
|
/* DLL_FUNCTIONS m_CoreDllFuncTable;
|
||||||
|
enginefuncs_t m_CoreEngineFuncTable;
|
||||||
|
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable;
|
||||||
|
|
||||||
|
DLL_FUNCTIONS m_CoreDllFuncTable_Post;
|
||||||
|
enginefuncs_t m_CoreEngineFuncTable_Post;
|
||||||
|
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable_Post; */
|
||||||
|
|
||||||
|
bool AddCorePlugin(); // Adds the core plugin if needed
|
||||||
|
public:
|
||||||
|
class CFakeMetaPlugin
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// plugin info
|
||||||
|
String m_Path;
|
||||||
|
PLUG_STATUS m_Status;
|
||||||
|
plugin_info_t *m_Info;
|
||||||
|
// Function tables
|
||||||
|
META_FUNCTIONS m_MetaFuncTable;
|
||||||
|
|
||||||
|
DLL_FUNCTIONS m_DllFuncTable;
|
||||||
|
enginefuncs_t m_EngineFuncTable;
|
||||||
|
NEW_DLL_FUNCTIONS m_NewDllFuncTable;
|
||||||
|
|
||||||
|
DLL_FUNCTIONS m_DllFuncTable_Post;
|
||||||
|
enginefuncs_t m_EngineFuncTable_Post;
|
||||||
|
NEW_DLL_FUNCTIONS m_NewDllFuncTable_Post;
|
||||||
|
|
||||||
|
// OS dep handle
|
||||||
|
DLHANDLE m_Handle;
|
||||||
|
public:
|
||||||
|
inline PLUG_STATUS GetStatus() const
|
||||||
|
{ return m_Status; }
|
||||||
|
inline void SetStatus(PLUG_STATUS newStatus)
|
||||||
|
{ m_Status = newStatus; }
|
||||||
|
|
||||||
|
|
||||||
|
inline plugin_info_t * GetInfo()
|
||||||
|
{ return m_Info; }
|
||||||
|
inline const plugin_info_t * GetInfo() const
|
||||||
|
{ return m_Info; }
|
||||||
|
inline void SetInfo(plugin_info_t *newInfo)
|
||||||
|
{ m_Info = newInfo; }
|
||||||
|
|
||||||
|
inline const char * GetPath()
|
||||||
|
{ return m_Path.c_str(); }
|
||||||
|
|
||||||
|
inline const META_FUNCTIONS &GetMetaFunctions() const
|
||||||
|
{ return m_MetaFuncTable; }
|
||||||
|
|
||||||
|
// Get
|
||||||
|
inline DLL_FUNCTIONS &GetDllFuncTable()
|
||||||
|
{ return m_DllFuncTable; }
|
||||||
|
inline enginefuncs_t &GetEngineFuncTable()
|
||||||
|
{ return m_EngineFuncTable; }
|
||||||
|
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
|
||||||
|
{ return m_NewDllFuncTable; }
|
||||||
|
|
||||||
|
// Get const
|
||||||
|
inline const DLL_FUNCTIONS &GetDllFuncTable() const
|
||||||
|
{ return m_DllFuncTable; }
|
||||||
|
inline const enginefuncs_t &GetEngineFuncTable() const
|
||||||
|
{ return m_EngineFuncTable; }
|
||||||
|
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
|
||||||
|
{ return m_NewDllFuncTable; }
|
||||||
|
|
||||||
|
// Get post
|
||||||
|
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
|
||||||
|
{ return m_DllFuncTable_Post; }
|
||||||
|
inline enginefuncs_t &GetEngineFuncTable_Post()
|
||||||
|
{ return m_EngineFuncTable_Post; }
|
||||||
|
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
|
||||||
|
{ return m_NewDllFuncTable_Post; }
|
||||||
|
|
||||||
|
// Get post const
|
||||||
|
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
|
||||||
|
{ return m_DllFuncTable_Post; }
|
||||||
|
inline const enginefuncs_t &GetEngineFuncTable_Post() const
|
||||||
|
{ return m_EngineFuncTable_Post; }
|
||||||
|
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
|
||||||
|
{ return m_NewDllFuncTable_Post; }
|
||||||
|
|
||||||
|
int Query(mutil_funcs_t *pMetaUtilFuncs); // Also calls GiveFnPtrsToDll
|
||||||
|
int Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs);
|
||||||
|
int Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
|
||||||
|
int GetEntityAPI2(int interfaceVersion);
|
||||||
|
int GetEntityAPI2_Post(int interfaceVersion);
|
||||||
|
int GetEngineFunctions(int interfaceVersion);
|
||||||
|
int GetEngineFunctions_Post(int interfaceVersion);
|
||||||
|
int GetNewDLLFunctions(int interfaceVersion);
|
||||||
|
int GetNewDLLFunctions_Post(int interfaceVersion);
|
||||||
|
|
||||||
|
CFakeMetaPlugin(const char *path);
|
||||||
|
~CFakeMetaPlugin();
|
||||||
|
}; // CFakeMetaPlugin
|
||||||
|
|
||||||
|
CFakeMeta();
|
||||||
|
~CFakeMeta();
|
||||||
|
|
||||||
|
bool AddPlugin(const char *path /*path relative to moddir*/);
|
||||||
|
void ReleasePlugins();
|
||||||
|
|
||||||
|
// This is public because i don't want to declare all the functions as friends :)
|
||||||
|
// :NOTE: The core is now a special, first plugin!
|
||||||
|
CList<CFakeMetaPlugin> m_Plugins;
|
||||||
|
|
||||||
|
// ****** Meta functions ******
|
||||||
|
// Query all added plugins
|
||||||
|
void Meta_Query(mutil_funcs_t *pMetaUtilFuncs);
|
||||||
|
// Attach all added plugins
|
||||||
|
void Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs);
|
||||||
|
// Detach all added plugins
|
||||||
|
void Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
// :NOTE: Meta_Init currently not supported
|
||||||
|
int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
|
||||||
|
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
|
||||||
|
int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
|
||||||
|
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
|
||||||
|
int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
|
||||||
|
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
|
||||||
|
int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
|
||||||
|
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
|
||||||
|
int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
|
||||||
|
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
|
||||||
|
int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
|
||||||
|
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
|
||||||
|
|
||||||
|
// Get
|
||||||
|
/*inline DLL_FUNCTIONS &GetDllFuncTable()
|
||||||
|
{ return m_CoreDllFuncTable; }
|
||||||
|
inline enginefuncs_t &GetEngineFuncTable()
|
||||||
|
{ return m_CoreEngineFuncTable; }
|
||||||
|
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
|
||||||
|
{ return m_CoreNewDllFuncTable; }
|
||||||
|
|
||||||
|
// Get const
|
||||||
|
inline const DLL_FUNCTIONS &GetDllFuncTable() const
|
||||||
|
{ return m_CoreDllFuncTable; }
|
||||||
|
inline const enginefuncs_t &GetEngineFuncTable() const
|
||||||
|
{ return m_CoreEngineFuncTable; }
|
||||||
|
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
|
||||||
|
{ return m_CoreNewDllFuncTable; }
|
||||||
|
|
||||||
|
// Get post
|
||||||
|
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
|
||||||
|
{ return m_CoreDllFuncTable_Post; }
|
||||||
|
inline enginefuncs_t &GetEngineFuncTable_Post()
|
||||||
|
{ return m_CoreEngineFuncTable_Post; }
|
||||||
|
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
|
||||||
|
{ return m_CoreNewDllFuncTable_Post; }
|
||||||
|
|
||||||
|
// Get post const
|
||||||
|
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
|
||||||
|
{ return m_CoreDllFuncTable_Post; }
|
||||||
|
inline const enginefuncs_t &GetEngineFuncTable_Post() const
|
||||||
|
{ return m_CoreEngineFuncTable_Post; }
|
||||||
|
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
|
||||||
|
{ return m_CoreNewDllFuncTable_Post; } */
|
||||||
|
}; // CFakeMeta
|
||||||
|
|
||||||
|
// Fake Metamod
|
||||||
|
// defined in meta_api.cpp
|
||||||
|
extern CFakeMeta g_FakeMeta;
|
||||||
|
|
||||||
|
#endif //FAKEMETA
|
||||||
|
|
||||||
#endif // #ifndef __FAKEMETA_H__
|
#endif // #ifndef __FAKEMETA_H__
|
||||||
|
|
||||||
|
1059
amxmodx/file.cpp
1059
amxmodx/file.cpp
File diff suppressed because it is too large
Load Diff
@ -368,6 +368,7 @@ static cell AMX_NATIVE_CALL n_floatatan(AMX *amx, cell *params)
|
|||||||
* params[2] = radix
|
* params[2] = radix
|
||||||
*/
|
*/
|
||||||
REAL fA = amx_ctof(params[1]);
|
REAL fA = amx_ctof(params[1]);
|
||||||
|
fA = ToRadians(fA, params[2]);
|
||||||
fA = atan(fA);
|
fA = atan(fA);
|
||||||
fA = FromRadians(fA, params[2]);
|
fA = FromRadians(fA, params[2]);
|
||||||
return amx_ftoc(fA);
|
return amx_ftoc(fA);
|
||||||
@ -424,54 +425,6 @@ static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
|
|||||||
return amx_ftoc(fC);
|
return amx_ftoc(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
/* Added by DS */
|
|
||||||
static cell AMX_NATIVE_CALL n_floatsinh(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* params[1] = angle
|
|
||||||
* params[2] = radix
|
|
||||||
*/
|
|
||||||
REAL fA = amx_ctof(params[1]);
|
|
||||||
fA = ToRadians(fA, params[2]);
|
|
||||||
fA = sinh(fA);
|
|
||||||
return amx_ftoc(fA);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
/* Added by DS */
|
|
||||||
static cell AMX_NATIVE_CALL n_floatcosh(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* params[1] = angle
|
|
||||||
* params[2] = radix
|
|
||||||
*/
|
|
||||||
REAL fA = amx_ctof(params[1]);
|
|
||||||
fA = ToRadians(fA, params[2]);
|
|
||||||
fA = cosh(fA);
|
|
||||||
return amx_ftoc(fA);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
|
||||||
#pragma argsused
|
|
||||||
#endif
|
|
||||||
/* Added by DS */
|
|
||||||
static cell AMX_NATIVE_CALL n_floattanh(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* params[1] = angle
|
|
||||||
* params[2] = radix
|
|
||||||
*/
|
|
||||||
REAL fA = amx_ctof(params[1]);
|
|
||||||
fA = ToRadians(fA, params[2]);
|
|
||||||
fA = tanh(fA);
|
|
||||||
return amx_ftoc(fA);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
#pragma argsused
|
#pragma argsused
|
||||||
#endif
|
#endif
|
||||||
@ -504,9 +457,6 @@ AMX_NATIVE_INFO float_Natives[] = {
|
|||||||
{ "floatacos", n_floatacos },
|
{ "floatacos", n_floatacos },
|
||||||
{ "floatatan", n_floatatan },
|
{ "floatatan", n_floatatan },
|
||||||
{ "floatatan2", n_floatatan2 },
|
{ "floatatan2", n_floatatan2 },
|
||||||
{ "floatsinh", n_floatsinh },
|
|
||||||
{ "floatcosh", n_floatcosh },
|
|
||||||
{ "floattanh", n_floattanh },
|
|
||||||
{ NULL, NULL } /* terminator */
|
{ NULL, NULL } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,509 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include "format.h"
|
|
||||||
#include "amxmod_compat.h"
|
|
||||||
|
|
||||||
//Adapted from Quake3's vsprintf
|
|
||||||
// thanks to cybermind for linking me to this :)
|
|
||||||
//I made the following changes:
|
|
||||||
// - Fixed spacing to be AMX Mod X standard
|
|
||||||
// - Added 'n' support, no buffer overflows
|
|
||||||
// - Templatized input/output buffers
|
|
||||||
|
|
||||||
#define ALT 0x00000001 /* alternate form */
|
|
||||||
#define HEXPREFIX 0x00000002 /* add 0x or 0X prefix */
|
|
||||||
#define LADJUST 0x00000004 /* left adjustment */
|
|
||||||
#define LONGDBL 0x00000008 /* long double */
|
|
||||||
#define LONGINT 0x00000010 /* long integer */
|
|
||||||
#define QUADINT 0x00000020 /* quad integer */
|
|
||||||
#define SHORTINT 0x00000040 /* short integer */
|
|
||||||
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
|
|
||||||
#define FPT 0x00000100 /* floating point number */
|
|
||||||
#define to_digit(c) ((c) - '0')
|
|
||||||
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
|
|
||||||
#define to_char(n) ((n) + '0')
|
|
||||||
#define CHECK_ARGS(n) \
|
|
||||||
if ((arg+n) > args) { \
|
|
||||||
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", arg, args); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
THash<String, lang_err> BadLang_Table;
|
|
||||||
|
|
||||||
static cvar_t *amx_mldebug = NULL;
|
|
||||||
static cvar_t *amx_cl_langs = NULL;
|
|
||||||
|
|
||||||
const char *translate(AMX *amx, cell amxaddr, const char *key)
|
|
||||||
{
|
|
||||||
const char *pLangName = NULL;
|
|
||||||
const char *def = NULL;
|
|
||||||
int status;
|
|
||||||
cell *addr = get_amxaddr(amx, amxaddr);
|
|
||||||
char name[4];
|
|
||||||
if (addr[0] == LANG_PLAYER)
|
|
||||||
{
|
|
||||||
if (!amx_cl_langs)
|
|
||||||
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
|
|
||||||
if ( (int)amx_cl_langs->value == 0 )
|
|
||||||
{
|
|
||||||
pLangName = g_vault.get("server_language");
|
|
||||||
} else {
|
|
||||||
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang");
|
|
||||||
}
|
|
||||||
} else if (addr[0] == LANG_SERVER) {
|
|
||||||
pLangName = g_vault.get("server_language");
|
|
||||||
} else if (addr[0] >= 1 && addr[0] <= gpGlobals->maxClients) {
|
|
||||||
if (!amx_cl_langs)
|
|
||||||
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
|
|
||||||
if ( (int)amx_cl_langs->value == 0 )
|
|
||||||
{
|
|
||||||
pLangName = g_vault.get("server_language");
|
|
||||||
} else {
|
|
||||||
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(addr[0])->pEdict, "lang");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
get_amxstring_r(amx, amxaddr, name, 3);
|
|
||||||
pLangName = name;
|
|
||||||
}
|
|
||||||
if (!pLangName || !isalpha(pLangName[0]))
|
|
||||||
pLangName = "en";
|
|
||||||
//next parameter!
|
|
||||||
def = g_langMngr.GetDef(pLangName, key, status);
|
|
||||||
|
|
||||||
if (!amx_mldebug)
|
|
||||||
amx_mldebug = CVAR_GET_POINTER("amx_mldebug");
|
|
||||||
|
|
||||||
bool debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0'));
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
int debug_status;
|
|
||||||
bool validlang = true;
|
|
||||||
const char *testlang = amx_mldebug->string;
|
|
||||||
if (!g_langMngr.LangExists(testlang))
|
|
||||||
{
|
|
||||||
AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang);
|
|
||||||
validlang = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_langMngr.GetDef(testlang, key, debug_status);
|
|
||||||
|
|
||||||
if (validlang && debug_status == ERR_BADKEY)
|
|
||||||
AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (def == NULL)
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(pLangName).last + 120.0f < gpGlobals->time))
|
|
||||||
{
|
|
||||||
AMXXLOG_Error("[AMXX] Language \"%s\" not found", pLangName);
|
|
||||||
BadLang_Table.AltFindOrInsert(pLangName).last = gpGlobals->time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr[0] != LANG_SERVER)
|
|
||||||
def = g_langMngr.GetDef(g_vault.get("server_language"), key, status);
|
|
||||||
|
|
||||||
if (!def && (strcmp(pLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0))
|
|
||||||
def = g_langMngr.GetDef("en", key, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
void AddString(U **buf_p, size_t &maxlen, const cell *string, int width, int prec)
|
|
||||||
{
|
|
||||||
int size = 0;
|
|
||||||
U *buf;
|
|
||||||
static cell nlstr[] = {'(','n','u','l','l',')','\0'};
|
|
||||||
|
|
||||||
buf = *buf_p;
|
|
||||||
|
|
||||||
if (string == NULL)
|
|
||||||
{
|
|
||||||
string = nlstr;
|
|
||||||
prec = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prec >= 0)
|
|
||||||
{
|
|
||||||
for (size = 0; size < prec; size++)
|
|
||||||
{
|
|
||||||
if (string[size] == '\0')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (string[size++]) ;
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size > (int)maxlen)
|
|
||||||
size = maxlen;
|
|
||||||
|
|
||||||
maxlen -= size;
|
|
||||||
width -= size;
|
|
||||||
|
|
||||||
while (size--)
|
|
||||||
*buf++ = static_cast<U>(*string++);
|
|
||||||
|
|
||||||
while (width-- > 0 && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = ' ';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf_p = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec)
|
|
||||||
{
|
|
||||||
U text[32];
|
|
||||||
int digits;
|
|
||||||
double signedVal;
|
|
||||||
U *buf;
|
|
||||||
int val;
|
|
||||||
|
|
||||||
// get the sign
|
|
||||||
signedVal = fval;
|
|
||||||
if (fval < 0)
|
|
||||||
fval = -fval;
|
|
||||||
|
|
||||||
// write the float number
|
|
||||||
digits = 0;
|
|
||||||
val = (int)fval;
|
|
||||||
do {
|
|
||||||
text[digits++] = '0' + val % 10;
|
|
||||||
val /= 10;
|
|
||||||
} while (val);
|
|
||||||
|
|
||||||
if (signedVal < 0)
|
|
||||||
text[digits++] = '-';
|
|
||||||
|
|
||||||
buf = *buf_p;
|
|
||||||
|
|
||||||
while (digits < width && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = ' ';
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (digits-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = text[digits];
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf_p = buf;
|
|
||||||
|
|
||||||
if (prec < 0)
|
|
||||||
prec = 6;
|
|
||||||
// write the fraction
|
|
||||||
digits = 0;
|
|
||||||
while (digits < prec)
|
|
||||||
{
|
|
||||||
fval -= (int) fval;
|
|
||||||
fval *= 10.0;
|
|
||||||
val = (int) fval;
|
|
||||||
text[digits++] = '0' + val % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (digits > 0 && maxlen)
|
|
||||||
{
|
|
||||||
buf = *buf_p;
|
|
||||||
*buf++ = '.';
|
|
||||||
maxlen--;
|
|
||||||
for (prec = 0; maxlen && prec < digits; prec++)
|
|
||||||
{
|
|
||||||
*buf++ = text[prec];
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
*buf_p = buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
void AddUInt(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
|
||||||
{
|
|
||||||
U text[32];
|
|
||||||
int digits;
|
|
||||||
U *buf;
|
|
||||||
|
|
||||||
digits = 0;
|
|
||||||
do {
|
|
||||||
text[digits++] = '0' + val % 10;
|
|
||||||
val /= 10;
|
|
||||||
} while (val);
|
|
||||||
|
|
||||||
buf = *buf_p;
|
|
||||||
|
|
||||||
if( !(flags & LADJUST) )
|
|
||||||
{
|
|
||||||
while (digits < width && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (digits-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = text[digits];
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & LADJUST)
|
|
||||||
{
|
|
||||||
while (width-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf_p = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
void AddInt(U **buf_p, size_t &maxlen, int val, int width, int flags)
|
|
||||||
{
|
|
||||||
U text[32];
|
|
||||||
int digits;
|
|
||||||
int signedVal;
|
|
||||||
U *buf;
|
|
||||||
unsigned int unsignedVal;
|
|
||||||
|
|
||||||
digits = 0;
|
|
||||||
signedVal = val;
|
|
||||||
if (val < 0)
|
|
||||||
{
|
|
||||||
/* we want the unsigned version */
|
|
||||||
unsignedVal = abs(val);
|
|
||||||
} else {
|
|
||||||
unsignedVal = val;
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
text[digits++] = '0' + unsignedVal % 10;
|
|
||||||
unsignedVal /= 10;
|
|
||||||
} while (unsignedVal);
|
|
||||||
|
|
||||||
if (signedVal < 0)
|
|
||||||
text[digits++] = '-';
|
|
||||||
|
|
||||||
buf = *buf_p;
|
|
||||||
|
|
||||||
if( !(flags & LADJUST) )
|
|
||||||
{
|
|
||||||
while (digits < width && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (digits-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = text[digits];
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & LADJUST)
|
|
||||||
{
|
|
||||||
while (width-- && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf_p = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename D, typename S>
|
|
||||||
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param)
|
|
||||||
{
|
|
||||||
int arg;
|
|
||||||
int args = params[0] / sizeof(cell);
|
|
||||||
D *buf_p;
|
|
||||||
D ch;
|
|
||||||
int flags;
|
|
||||||
int width;
|
|
||||||
int prec;
|
|
||||||
int n;
|
|
||||||
char sign;
|
|
||||||
const S *fmt;
|
|
||||||
size_t llen = maxlen;
|
|
||||||
|
|
||||||
buf_p = buffer;
|
|
||||||
arg = *param;
|
|
||||||
fmt = format;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// run through the format string until we hit a '%' or '\0'
|
|
||||||
for (ch = static_cast<D>(*fmt);
|
|
||||||
llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%');
|
|
||||||
fmt++)
|
|
||||||
{
|
|
||||||
*buf_p++ = static_cast<D>(ch);
|
|
||||||
llen--;
|
|
||||||
}
|
|
||||||
if (ch == '\0' || llen <= 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
// skip over the '%'
|
|
||||||
fmt++;
|
|
||||||
|
|
||||||
// reset formatting state
|
|
||||||
flags = 0;
|
|
||||||
width = 0;
|
|
||||||
prec = -1;
|
|
||||||
sign = '\0';
|
|
||||||
|
|
||||||
rflag:
|
|
||||||
ch = static_cast<D>(*fmt++);
|
|
||||||
reswitch:
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case '-':
|
|
||||||
flags |= LADJUST;
|
|
||||||
goto rflag;
|
|
||||||
case '.':
|
|
||||||
n = 0;
|
|
||||||
while( is_digit( ( ch = static_cast<D>(*fmt++)) ) )
|
|
||||||
n = 10 * n + ( ch - '0' );
|
|
||||||
prec = n < 0 ? -1 : n;
|
|
||||||
goto reswitch;
|
|
||||||
case '0':
|
|
||||||
flags |= ZEROPAD;
|
|
||||||
goto rflag;
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
n = 0;
|
|
||||||
do {
|
|
||||||
n = 10 * n + ( ch - '0' );
|
|
||||||
ch = static_cast<D>(*fmt++);
|
|
||||||
} while( is_digit( ch ) );
|
|
||||||
width = n;
|
|
||||||
goto reswitch;
|
|
||||||
case 'c':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
*buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg]));
|
|
||||||
llen--;
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
AddUInt(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
if (amx->flags & AMX_FLAG_OLDFILE)
|
|
||||||
{
|
|
||||||
cell *addr = get_amxaddr(amx, params[arg]);
|
|
||||||
if (*addr & BCOMPAT_TRANSLATE_BITS)
|
|
||||||
{
|
|
||||||
const char *key, *def;
|
|
||||||
if (!translate_bcompat(amx, addr, &key, &def))
|
|
||||||
{
|
|
||||||
goto break_to_normal_string;
|
|
||||||
}
|
|
||||||
arg++;
|
|
||||||
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
|
|
||||||
buf_p += written;
|
|
||||||
llen -= written;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break_to_normal_string:
|
|
||||||
AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
{
|
|
||||||
CHECK_ARGS(1);
|
|
||||||
cell addr = params[arg++];
|
|
||||||
int len;
|
|
||||||
const char *key = get_amxstring(amx, params[arg++], 3, len);
|
|
||||||
const char *def = translate(amx, addr, key);
|
|
||||||
if (!def)
|
|
||||||
{
|
|
||||||
static char buf[255];
|
|
||||||
snprintf(buf, sizeof(buf)-1, "ML_NOTFOUND: %s", key);
|
|
||||||
def = buf;
|
|
||||||
}
|
|
||||||
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
|
|
||||||
buf_p += written;
|
|
||||||
llen -= written;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '%':
|
|
||||||
*buf_p++ = static_cast<D>(ch);
|
|
||||||
if (!llen)
|
|
||||||
goto done;
|
|
||||||
llen--;
|
|
||||||
break;
|
|
||||||
case '\0':
|
|
||||||
*buf_p++ = static_cast<D>('%');
|
|
||||||
if (!llen)
|
|
||||||
goto done;
|
|
||||||
llen--;
|
|
||||||
goto done;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*buf_p++ = static_cast<D>(ch);
|
|
||||||
if (!llen)
|
|
||||||
goto done;
|
|
||||||
llen--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
*buf_p = static_cast<D>(0);
|
|
||||||
*param = arg;
|
|
||||||
return maxlen-llen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HACKHACK: The compiler will generate code for each case we need.
|
|
||||||
* Don't remove this, otherwise files that use certain code generations
|
|
||||||
* will have extern problems. For each case you need, add dummy code
|
|
||||||
* here.
|
|
||||||
*/
|
|
||||||
void __WHOA_DONT_CALL_ME_PLZ_K_lol_o_O()
|
|
||||||
{
|
|
||||||
//acsprintf
|
|
||||||
atcprintf((cell *)NULL, 0, (const char *)NULL, NULL, NULL, NULL);
|
|
||||||
//accprintf
|
|
||||||
atcprintf((cell *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
|
|
||||||
//ascprintf
|
|
||||||
atcprintf((char *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
#ifndef _INCLUDE_FORMATTING_H
|
|
||||||
#define _INCLUDE_FORMATTING_H
|
|
||||||
|
|
||||||
//Amx Templatized Cell Printf
|
|
||||||
template <typename D, typename S>
|
|
||||||
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
|
|
||||||
|
|
||||||
const char *translate(AMX *amx, cell amxaddr, const char *key);
|
|
||||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def);
|
|
||||||
|
|
||||||
#endif //_INCLUDE_FORMATTING_H
|
|
@ -1,51 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; (C)2006 by David "BAILOPAN" Anderson ;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;;Licensed under the GNU General Public License, version 2
|
|
||||||
;;This is a portion of AMX Mod X
|
|
||||||
;; and is maintained by the AMX Mod X development team.
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
global amxx_CpuSupport, _amxx_CpuSupport
|
|
||||||
|
|
||||||
amxx_CpuSupport:
|
|
||||||
_amxx_CpuSupport:
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
push ebx
|
|
||||||
|
|
||||||
mov eax, 0
|
|
||||||
cpuid
|
|
||||||
cmp eax, 1
|
|
||||||
jl .fail
|
|
||||||
|
|
||||||
mov eax, 1
|
|
||||||
cpuid
|
|
||||||
;check if family == 5 or 4
|
|
||||||
and eax, 0780h ;family mask
|
|
||||||
shr eax, 7 ;family shift
|
|
||||||
cmp eax, 5
|
|
||||||
je .fail
|
|
||||||
cmp eax, 4
|
|
||||||
je .fail
|
|
||||||
;check if CMOV exists
|
|
||||||
shr edx, 15
|
|
||||||
and edx, 1
|
|
||||||
cmp edx, 0
|
|
||||||
je .fail
|
|
||||||
|
|
||||||
mov eax, 1
|
|
||||||
jmp .end
|
|
||||||
|
|
||||||
.fail:
|
|
||||||
xor eax, eax
|
|
||||||
|
|
||||||
.end
|
|
||||||
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
@ -1,243 +0,0 @@
|
|||||||
#include "libraries.h"
|
|
||||||
#include "sh_list.h"
|
|
||||||
|
|
||||||
List<Library *> g_libraries;
|
|
||||||
|
|
||||||
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent)
|
|
||||||
{
|
|
||||||
if (FindLibrary(name, type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Library *lib = new Library;
|
|
||||||
|
|
||||||
lib->name.assign(name);
|
|
||||||
lib->type = type;
|
|
||||||
lib->src = src;
|
|
||||||
lib->parent = parent;
|
|
||||||
|
|
||||||
g_libraries.push_back(lib);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DecodeLibCmdString(const char *str, LibDecoder *dec)
|
|
||||||
{
|
|
||||||
if (dec->buffer)
|
|
||||||
{
|
|
||||||
free(dec->buffer);
|
|
||||||
dec->buffer = NULL;
|
|
||||||
}
|
|
||||||
if (str[0] != '?')
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
str++;
|
|
||||||
if (*str == 'r')
|
|
||||||
{
|
|
||||||
str++;
|
|
||||||
if (*str == 'c')
|
|
||||||
dec->cmd = LibCmd_ReqClass;
|
|
||||||
else if (*str == 'l')
|
|
||||||
dec->cmd = LibCmd_ReqLib;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
str++;
|
|
||||||
} else if (*str == 'f') {
|
|
||||||
str++;
|
|
||||||
dec->cmd = LibCmd_ForceLib;
|
|
||||||
} else if (*str == 'e') {
|
|
||||||
str++;
|
|
||||||
if (*str == 'c')
|
|
||||||
dec->cmd = LibCmd_ExpectClass;
|
|
||||||
else if (*str == 'l')
|
|
||||||
dec->cmd = LibCmd_ExpectLib;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
str++;
|
|
||||||
} else if (*str == 'd') {
|
|
||||||
str++;
|
|
||||||
dec->cmd = LibCmd_DefaultLib;
|
|
||||||
}
|
|
||||||
if (*str != '_')
|
|
||||||
return false;
|
|
||||||
str++;
|
|
||||||
if (dec->cmd < LibCmd_ExpectLib)
|
|
||||||
{
|
|
||||||
dec->buffer = strdup(str);
|
|
||||||
dec->param1 = dec->buffer;
|
|
||||||
dec->param2 = NULL;
|
|
||||||
} else {
|
|
||||||
dec->buffer = strdup(str);
|
|
||||||
char *p = strchr(dec->buffer, '_');
|
|
||||||
while (p && (*(p+1) == '_'))
|
|
||||||
p = strchr(p+2, '_');
|
|
||||||
if (!p || !*(p+1))
|
|
||||||
return false;
|
|
||||||
*p = '\0';
|
|
||||||
dec->param1 = dec->buffer;
|
|
||||||
dec->param2 = p+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent)
|
|
||||||
{
|
|
||||||
char buffer[255];
|
|
||||||
char *ptr, *p, s;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer)-1, "%s", name);
|
|
||||||
|
|
||||||
ptr = buffer;
|
|
||||||
p = buffer;
|
|
||||||
while (*p)
|
|
||||||
{
|
|
||||||
while (*p && (*p != ','))
|
|
||||||
p++;
|
|
||||||
s = *p;
|
|
||||||
*p = '\0';
|
|
||||||
if (AddLibrary(ptr, type, src, parent))
|
|
||||||
count++;
|
|
||||||
if (!s)
|
|
||||||
break;
|
|
||||||
p++;
|
|
||||||
while (*p && (*p == ','))
|
|
||||||
p++;
|
|
||||||
ptr = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ClearLibraries(LibSource src)
|
|
||||||
{
|
|
||||||
List<Library *>::iterator iter;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
iter = g_libraries.begin();
|
|
||||||
while (iter != g_libraries.end())
|
|
||||||
{
|
|
||||||
if ( (*iter)->src == src )
|
|
||||||
{
|
|
||||||
delete (*iter);
|
|
||||||
iter = g_libraries.erase(iter);
|
|
||||||
count++;
|
|
||||||
} else {
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t RemoveLibraries(void *parent)
|
|
||||||
{
|
|
||||||
List<Library *>::iterator iter;
|
|
||||||
Library *lib;
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
iter = g_libraries.begin();
|
|
||||||
while (iter != g_libraries.end())
|
|
||||||
{
|
|
||||||
lib = (*iter);
|
|
||||||
if (lib->parent == parent)
|
|
||||||
{
|
|
||||||
delete (*iter);
|
|
||||||
iter = g_libraries.erase(iter);
|
|
||||||
count++;
|
|
||||||
} else {
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FindLibrary(const char *name, LibType type)
|
|
||||||
{
|
|
||||||
List<Library *>::iterator iter;
|
|
||||||
Library *lib;
|
|
||||||
|
|
||||||
for (iter = g_libraries.begin(); iter != g_libraries.end(); iter++)
|
|
||||||
{
|
|
||||||
lib = (*iter);
|
|
||||||
if (lib->type != type)
|
|
||||||
continue;
|
|
||||||
if (strcasecmp(lib->name.c_str(), name) == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LibError RunLibCommand(const LibDecoder *enc)
|
|
||||||
{
|
|
||||||
List<Library *>::iterator iter,end;
|
|
||||||
Library *lib;
|
|
||||||
|
|
||||||
iter = g_libraries.begin();
|
|
||||||
end = g_libraries.end();
|
|
||||||
|
|
||||||
if ( (enc->cmd == LibCmd_ReqLib) || (enc->cmd == LibCmd_ReqClass) )
|
|
||||||
{
|
|
||||||
LibType expect = LibType_Library;
|
|
||||||
|
|
||||||
if (enc->cmd == LibCmd_ReqLib)
|
|
||||||
expect = LibType_Library;
|
|
||||||
else if (enc->cmd == LibCmd_ReqClass)
|
|
||||||
expect = LibType_Class;
|
|
||||||
|
|
||||||
/** see if it exists */
|
|
||||||
for (; iter != end; iter++)
|
|
||||||
{
|
|
||||||
lib = (*iter);
|
|
||||||
if (lib->type != expect)
|
|
||||||
continue;
|
|
||||||
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
|
|
||||||
return LibErr_None;
|
|
||||||
}
|
|
||||||
if (expect == LibType_Library)
|
|
||||||
return LibErr_NoLibrary;
|
|
||||||
else if (expect == LibType_Class)
|
|
||||||
return LibErr_NoClass;
|
|
||||||
|
|
||||||
return LibErr_NoLibrary;
|
|
||||||
} else if (enc->cmd == LibCmd_ForceLib) {
|
|
||||||
if (!LoadModule(enc->param1, PT_ANYTIME, true, true))
|
|
||||||
{
|
|
||||||
return LibErr_NoLibrary;
|
|
||||||
}
|
|
||||||
} else if ( (enc->cmd == LibCmd_DefaultLib) ||
|
|
||||||
((enc->cmd == LibCmd_ExpectLib) || (enc->cmd == LibCmd_ExpectClass)) )
|
|
||||||
{
|
|
||||||
LibType expect;
|
|
||||||
|
|
||||||
if (enc->cmd == LibCmd_ExpectLib)
|
|
||||||
expect = LibType_Library;
|
|
||||||
else
|
|
||||||
expect = LibType_Class;
|
|
||||||
|
|
||||||
/** see if it exists */
|
|
||||||
for (; iter != end; iter++)
|
|
||||||
{
|
|
||||||
lib = (*iter);
|
|
||||||
if (lib->type != expect)
|
|
||||||
continue;
|
|
||||||
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
|
|
||||||
return LibErr_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LoadModule(enc->param2, PT_ANYTIME, true, true))
|
|
||||||
{
|
|
||||||
return LibErr_NoLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LibErr_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LibErr_None;
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
#ifndef _INCLUDE_LIBRARIES_H
|
|
||||||
#define _INCLUDE_LIBRARIES_H
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "amxmodx.h"
|
|
||||||
#include "CString.h"
|
|
||||||
|
|
||||||
enum LibSource
|
|
||||||
{
|
|
||||||
LibSource_Plugin,
|
|
||||||
LibSource_Module
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LibType
|
|
||||||
{
|
|
||||||
LibType_Library,
|
|
||||||
LibType_Class
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Library
|
|
||||||
{
|
|
||||||
String name;
|
|
||||||
LibSource src;
|
|
||||||
LibType type;
|
|
||||||
void *parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LibCmd
|
|
||||||
{
|
|
||||||
LibCmd_ReqLib,
|
|
||||||
LibCmd_ReqClass,
|
|
||||||
LibCmd_ForceLib,
|
|
||||||
LibCmd_ExpectLib,
|
|
||||||
LibCmd_ExpectClass,
|
|
||||||
LibCmd_DefaultLib,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LibError
|
|
||||||
{
|
|
||||||
LibErr_None = 0,
|
|
||||||
LibErr_NoLibrary,
|
|
||||||
LibErr_NoClass,
|
|
||||||
};
|
|
||||||
|
|
||||||
class LibDecoder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LibDecoder() : buffer(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~LibDecoder()
|
|
||||||
{
|
|
||||||
free(buffer);
|
|
||||||
buffer = NULL;
|
|
||||||
param1 = NULL;
|
|
||||||
param2 = NULL;
|
|
||||||
}
|
|
||||||
char *buffer;
|
|
||||||
char *param1;
|
|
||||||
char *param2;
|
|
||||||
LibCmd cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent=NULL);
|
|
||||||
bool DecodeLibCmdString(const char *str, LibDecoder *cmd);
|
|
||||||
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent=NULL);
|
|
||||||
size_t ClearLibraries(LibSource src);
|
|
||||||
LibError RunLibCommand(const LibDecoder *enc);
|
|
||||||
size_t RemoveLibraries(void *parent);
|
|
||||||
bool FindLibrary(const char *name, LibType type);
|
|
||||||
|
|
||||||
|
|
||||||
#endif //_INCLUDE_LIBRARIES_H
|
|
@ -111,7 +111,7 @@ void MD5::update(FILE *file){
|
|||||||
unsigned char buffer[1024];
|
unsigned char buffer[1024];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
while ((len=fread(buffer, 1, 1024, file)))
|
while (len=fread(buffer, 1, 1024, file))
|
||||||
update(buffer, len);
|
update(buffer, len);
|
||||||
|
|
||||||
fclose (file);
|
fclose (file);
|
||||||
|
@ -1,805 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include "messages.h"
|
|
||||||
|
|
||||||
Message Msg;
|
|
||||||
CVector<int> msgHooks[256];
|
|
||||||
int msgBlocks[256] = {BLOCK_NOT};
|
|
||||||
int msgDest;
|
|
||||||
int msgType;
|
|
||||||
float *msgOrigin;
|
|
||||||
edict_t *msgpEntity;
|
|
||||||
bool inhook = false;
|
|
||||||
bool inblock = false;
|
|
||||||
enginefuncs_t *g_pEngTable = NULL;
|
|
||||||
|
|
||||||
void ClearMessages()
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<MAX_MESSAGES; i++)
|
|
||||||
{
|
|
||||||
msgHooks[i].clear();
|
|
||||||
msgBlocks[i] = BLOCK_NOT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Message::Message()
|
|
||||||
{
|
|
||||||
m_CurParam = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Message::Ready()
|
|
||||||
{
|
|
||||||
if (!m_Params.size())
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::Init()
|
|
||||||
{
|
|
||||||
if (!Ready())
|
|
||||||
{
|
|
||||||
msgparam *p = new msgparam;
|
|
||||||
m_Params.push_back(p);
|
|
||||||
}
|
|
||||||
m_CurParam = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Message::~Message()
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<m_Params.size(); i++)
|
|
||||||
delete m_Params[i];
|
|
||||||
|
|
||||||
m_Params.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
msgparam *Message::AdvPtr()
|
|
||||||
{
|
|
||||||
msgparam *pParam = NULL;
|
|
||||||
|
|
||||||
if (++m_CurParam >= m_Params.size())
|
|
||||||
{
|
|
||||||
pParam = new msgparam;
|
|
||||||
m_Params.push_back(pParam);
|
|
||||||
} else {
|
|
||||||
pParam = m_Params[m_CurParam];
|
|
||||||
}
|
|
||||||
|
|
||||||
return pParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::AddParam(const char *data, msgtype type)
|
|
||||||
{
|
|
||||||
msgparam *pParam = AdvPtr();
|
|
||||||
|
|
||||||
pParam->szData.assign(data);
|
|
||||||
pParam->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::AddParam(int data, msgtype type)
|
|
||||||
{
|
|
||||||
msgparam *pParam = AdvPtr();
|
|
||||||
|
|
||||||
pParam->v.iData = data;
|
|
||||||
pParam->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::AddParam(float data, msgtype type)
|
|
||||||
{
|
|
||||||
msgparam *pParam = AdvPtr();
|
|
||||||
|
|
||||||
pParam->v.fData = data;
|
|
||||||
pParam->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgtype Message::GetParamType(size_t index)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return static_cast<msgtype>(0);
|
|
||||||
|
|
||||||
return m_Params[index]->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Message::GetParamFloat(size_t index)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return m_Params[index]->v.fData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Message::GetParamString(size_t index)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return m_Params[index]->szData.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Message::GetParamInt(size_t index)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return m_Params[index]->v.iData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::SetParam(size_t index, float data)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_Params[index]->v.fData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::SetParam(size_t index, int data)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_Params[index]->v.iData = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::SetParam(size_t index, const char *data)
|
|
||||||
{
|
|
||||||
if (index < 1 || index > m_CurParam)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_Params[index]->szData.assign(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::Reset()
|
|
||||||
{
|
|
||||||
m_CurParam = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Message::Params()
|
|
||||||
{
|
|
||||||
return m_CurParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Message::Send()
|
|
||||||
{
|
|
||||||
msgparam *pParam = NULL;
|
|
||||||
|
|
||||||
for (size_t i=1; i<=m_CurParam; i++)
|
|
||||||
{
|
|
||||||
pParam = m_Params[i];
|
|
||||||
switch (pParam->type)
|
|
||||||
{
|
|
||||||
case arg_byte:
|
|
||||||
WRITE_BYTE(pParam->v.iData);
|
|
||||||
break;
|
|
||||||
case arg_char:
|
|
||||||
WRITE_CHAR(pParam->v.iData);
|
|
||||||
break;
|
|
||||||
case arg_short:
|
|
||||||
WRITE_SHORT(pParam->v.iData);
|
|
||||||
break;
|
|
||||||
case arg_long:
|
|
||||||
WRITE_LONG(pParam->v.iData);
|
|
||||||
break;
|
|
||||||
case arg_angle:
|
|
||||||
WRITE_ANGLE(pParam->v.fData);
|
|
||||||
break;
|
|
||||||
case arg_coord:
|
|
||||||
WRITE_COORD(pParam->v.fData);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
WRITE_STRING(pParam->szData.c_str());
|
|
||||||
break;
|
|
||||||
case arg_entity:
|
|
||||||
WRITE_ENTITY(pParam->v.iData);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
|
|
||||||
{
|
|
||||||
if (msgBlocks[msg_type])
|
|
||||||
{
|
|
||||||
inblock = true;
|
|
||||||
msgType = msg_type;
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (msgHooks[msg_type].size()) {
|
|
||||||
inhook = true;
|
|
||||||
msgDest = msg_dest;
|
|
||||||
msgType = msg_type;
|
|
||||||
msgOrigin = (float *)pOrigin;
|
|
||||||
msgpEntity = ed;
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteByte(int iValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(iValue, arg_byte);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteChar(int iValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(iValue, arg_char);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteShort(int iValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(iValue, arg_short);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteLong(int iValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(iValue, arg_long);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteAngle(float flValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(flValue, arg_angle);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteCoord(float flValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(flValue, arg_coord);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteString(const char *sz)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(sz, arg_string);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_WriteEntity(int iValue)
|
|
||||||
{
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
Msg.AddParam(iValue, arg_entity);
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void C_MessageEnd(void)
|
|
||||||
{
|
|
||||||
int mres = 0, mresB = 0;
|
|
||||||
unsigned int i = 0;
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
inblock = false;
|
|
||||||
if (msgBlocks[msgType] == BLOCK_ONCE)
|
|
||||||
{
|
|
||||||
msgBlocks[msgType] = BLOCK_NOT;
|
|
||||||
}
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
for (i=0; i<msgHooks[msgType].size(); i++)
|
|
||||||
{
|
|
||||||
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
|
||||||
if (mresB > mres)
|
|
||||||
mres = mresB;
|
|
||||||
}
|
|
||||||
inhook = false;
|
|
||||||
if (mres & 1)
|
|
||||||
{
|
|
||||||
Msg.Reset();
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* send the real message */
|
|
||||||
MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity);
|
|
||||||
Msg.Send();
|
|
||||||
MESSAGE_END();
|
|
||||||
|
|
||||||
/* reset */
|
|
||||||
Msg.Reset();
|
|
||||||
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
|
|
||||||
{
|
|
||||||
int numparam = *params / sizeof(cell);
|
|
||||||
float vecOrigin[3];
|
|
||||||
cell *cpOrigin;
|
|
||||||
|
|
||||||
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
|
|
||||||
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (params[1])
|
|
||||||
{
|
|
||||||
case MSG_BROADCAST:
|
|
||||||
case MSG_ALL:
|
|
||||||
case MSG_SPEC:
|
|
||||||
MESSAGE_BEGIN(params[1], params[2], NULL);
|
|
||||||
break;
|
|
||||||
case MSG_PVS: case MSG_PAS:
|
|
||||||
case MSG_PVS_R: case MSG_PAS_R:
|
|
||||||
if (numparam < 3)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpOrigin = get_amxaddr(amx, params[3]);
|
|
||||||
|
|
||||||
vecOrigin[0] = static_cast<float>(*cpOrigin);
|
|
||||||
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
|
|
||||||
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
|
|
||||||
|
|
||||||
MESSAGE_BEGIN(params[1], params[2], vecOrigin);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case MSG_ONE_UNRELIABLE:
|
|
||||||
case MSG_ONE:
|
|
||||||
if (numparam < 4)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MESSAGE_BEGIN(params[1], params[2], NULL, INDEXENT(params[4]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL message_end(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
MESSAGE_END();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_byte(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_BYTE(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_char(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_CHAR(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_short(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_SHORT(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_long(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_LONG(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_entity(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_ENTITY(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_angle(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_ANGLE(static_cast<float>(params[1]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_coord(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
WRITE_COORD(static_cast<float>(params[1]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
int a;
|
|
||||||
WRITE_STRING(get_amxstring(amx, params[1], 3, a));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *name = get_amxstring(amx, params[2], 0, len);
|
|
||||||
|
|
||||||
if (!Msg.Ready())
|
|
||||||
Msg.Init();
|
|
||||||
|
|
||||||
if (params[1]>0 && params[1] < 256)
|
|
||||||
{
|
|
||||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
if (id != -1)
|
|
||||||
{
|
|
||||||
msgHooks[params[1]].push_back(id);
|
|
||||||
return id;
|
|
||||||
} else {
|
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int msgid = params[1];
|
|
||||||
int block = params[2];
|
|
||||||
|
|
||||||
if (msgid < 1 || msgid > 255)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
msgBlocks[msgid] = block;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_block(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int msgid = params[1];
|
|
||||||
|
|
||||||
if (msgid < 1 || msgid > 255)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return msgBlocks[msgid];
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
return Msg.Params();
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Msg.GetParamType(argn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Msg.GetParamInt(argn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Msg.SetParam(argn, (int)params[3]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
REAL f = (REAL)Msg.GetParamFloat(argn);
|
|
||||||
return amx_ftoc(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
REAL fVal = amx_ctof(params[3]);
|
|
||||||
|
|
||||||
Msg.SetParam(argn, (float)fVal);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *szVal = Msg.GetParamString(argn);
|
|
||||||
|
|
||||||
return set_amxstring(amx, params[2], szVal, params[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
size_t argn = static_cast<size_t>(params[1]);
|
|
||||||
int iLen;
|
|
||||||
|
|
||||||
if (!inhook || argn > Msg.Params())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *szVal = get_amxstring(amx, params[2], 0, iLen);
|
|
||||||
|
|
||||||
Msg.SetParam(argn, szVal);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_msg_origin(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!inhook)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not in a message hook");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell *cAddr = get_amxaddr(amx, params[1]);
|
|
||||||
|
|
||||||
if (msgDest >= MSG_PVS && msgDest <= MSG_PAS_R)
|
|
||||||
{
|
|
||||||
vec3_t vRet = (Vector)msgOrigin;
|
|
||||||
cAddr[0] = FloatToCell(vRet.x);
|
|
||||||
cAddr[1] = FloatToCell(vRet.y);
|
|
||||||
cAddr[2] = FloatToCell(vRet.z);
|
|
||||||
} else {
|
|
||||||
cAddr[0] = 0;
|
|
||||||
cAddr[1] = 0;
|
|
||||||
cAddr[2] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL emessage_begin(AMX *amx, cell *params) /* 4 param */
|
|
||||||
{
|
|
||||||
int numparam = *params / sizeof(cell);
|
|
||||||
float vecOrigin[3];
|
|
||||||
cell *cpOrigin;
|
|
||||||
|
|
||||||
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
|
|
||||||
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (params[1])
|
|
||||||
{
|
|
||||||
case MSG_BROADCAST:
|
|
||||||
case MSG_ALL:
|
|
||||||
case MSG_SPEC:
|
|
||||||
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, NULL);
|
|
||||||
break;
|
|
||||||
case MSG_PVS: case MSG_PAS:
|
|
||||||
case MSG_PVS_R: case MSG_PAS_R:
|
|
||||||
if (numparam < 3)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cpOrigin = get_amxaddr(amx, params[3]);
|
|
||||||
|
|
||||||
vecOrigin[0] = static_cast<float>(*cpOrigin);
|
|
||||||
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
|
|
||||||
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
|
|
||||||
|
|
||||||
g_pEngTable->pfnMessageBegin(params[1], params[2], vecOrigin, NULL);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case MSG_ONE_UNRELIABLE:
|
|
||||||
case MSG_ONE:
|
|
||||||
if (numparam < 4)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, INDEXENT(params[4]));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL emessage_end(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnMessageEnd();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_byte(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteByte(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_char(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteChar(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_short(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteShort(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_long(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteLong(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_entity(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteEntity(params[1]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_angle(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteAngle(static_cast<float>(params[1]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_coord(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
g_pEngTable->pfnWriteCoord(static_cast<float>(params[1]));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL ewrite_string(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
int a;
|
|
||||||
g_pEngTable->pfnWriteString(get_amxstring(amx, params[1], 3, a));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO msg_Natives[] =
|
|
||||||
{
|
|
||||||
{"message_begin", message_begin},
|
|
||||||
{"message_end", message_end},
|
|
||||||
|
|
||||||
{"write_angle", write_angle},
|
|
||||||
{"write_byte", write_byte},
|
|
||||||
{"write_char", write_char},
|
|
||||||
{"write_coord", write_coord},
|
|
||||||
{"write_entity", write_entity},
|
|
||||||
{"write_long", write_long},
|
|
||||||
{"write_short", write_short},
|
|
||||||
{"write_string", write_string},
|
|
||||||
|
|
||||||
{"register_message", register_message},
|
|
||||||
|
|
||||||
{"set_msg_block", set_msg_block},
|
|
||||||
{"get_msg_block", get_msg_block},
|
|
||||||
|
|
||||||
{"get_msg_args", get_msg_args},
|
|
||||||
{"get_msg_argtype", get_msg_argtype},
|
|
||||||
{"get_msg_arg_int", get_msg_arg_int},
|
|
||||||
{"set_msg_arg_int", set_msg_arg_int},
|
|
||||||
{"get_msg_arg_float", get_msg_arg_float},
|
|
||||||
{"set_msg_arg_float", set_msg_arg_float},
|
|
||||||
{"get_msg_arg_string", get_msg_arg_string},
|
|
||||||
{"set_msg_arg_string", set_msg_arg_string},
|
|
||||||
{"get_msg_origin", get_msg_origin},
|
|
||||||
|
|
||||||
{"emessage_begin", emessage_begin},
|
|
||||||
{"emessage_end", emessage_end},
|
|
||||||
|
|
||||||
{"ewrite_angle", ewrite_angle},
|
|
||||||
{"ewrite_byte", ewrite_byte},
|
|
||||||
{"ewrite_char", ewrite_char},
|
|
||||||
{"ewrite_coord", ewrite_coord},
|
|
||||||
{"ewrite_entity", ewrite_entity},
|
|
||||||
{"ewrite_long", ewrite_long},
|
|
||||||
{"ewrite_short", ewrite_short},
|
|
||||||
{"ewrite_string", ewrite_string},
|
|
||||||
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
1919
amxmodx/meta_api.cpp
1919
amxmodx/meta_api.cpp
File diff suppressed because it is too large
Load Diff
116
amxmodx/mm_pextensions.h
Executable file
116
amxmodx/mm_pextensions.h
Executable file
@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004 Jussi Kivilinna
|
||||||
|
*
|
||||||
|
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
|
||||||
|
*
|
||||||
|
* Metamod 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.
|
||||||
|
*
|
||||||
|
* Metamod 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 Metamod; 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 MM_PEXTENSIONS_H
|
||||||
|
#define MM_PEXTENSIONS_H
|
||||||
|
|
||||||
|
#include "plinfo.h" // plid_t
|
||||||
|
#include "meta_api.h" // PLUG_LOADTIME
|
||||||
|
/*
|
||||||
|
|
||||||
|
How to use:
|
||||||
|
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
|
||||||
|
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
|
||||||
|
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
|
||||||
|
and pointer to extension function table.
|
||||||
|
3. Meta_PExtGiveFnptrs should return plugin's interface version.
|
||||||
|
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
|
||||||
|
interface version greater than current. Plugin should disable itself in
|
||||||
|
this kind of situation.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
#include "mm_pextensions.h"
|
||||||
|
|
||||||
|
pextension_funcs_t *gpMetaPExtFuncs;
|
||||||
|
|
||||||
|
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
|
||||||
|
if(interfaceVersion < META_PEXT_VERSION) {
|
||||||
|
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
|
||||||
|
gpMetaPExtFuncs = NULL;
|
||||||
|
|
||||||
|
return(META_PEXT_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpMetaPExtFuncs = pMetaPExtFuncs;
|
||||||
|
|
||||||
|
return(META_PEXT_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
Callback functions:
|
||||||
|
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||||
|
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
|
||||||
|
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
|
||||||
|
plugin at it.
|
||||||
|
Returns zero on success.
|
||||||
|
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||||
|
|
||||||
|
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
|
||||||
|
unloads found plugin.
|
||||||
|
Returns zero on success.
|
||||||
|
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||||
|
|
||||||
|
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
Unloads plugin with 'plugin_handle'.
|
||||||
|
Returns zero on success.
|
||||||
|
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||||
|
|
||||||
|
!NOTE! Plugin cannot unload itself!
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Interface version
|
||||||
|
// 1: first version. Used in p13
|
||||||
|
// 2: Complete remake (p14):
|
||||||
|
// pfnLoadMetaPluginByName
|
||||||
|
// pfnUnloadMetaPluginByName
|
||||||
|
// pfnUnloadMetaPluginByHandle
|
||||||
|
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
|
||||||
|
#define META_PEXT_VERSION 2
|
||||||
|
|
||||||
|
// Meta PExtension Function table type.
|
||||||
|
typedef struct pextension_funcs_s {
|
||||||
|
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||||
|
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||||
|
} pextension_funcs_t;
|
||||||
|
|
||||||
|
// Convenience macros for MetaPExtension functions.
|
||||||
|
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
|
||||||
|
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
|
||||||
|
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
|
||||||
|
|
||||||
|
// Give plugin extension function table.
|
||||||
|
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
|
||||||
|
pextension_funcs_t *pMetaPExtFuncs);
|
||||||
|
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
|
||||||
|
pextension_funcs_t *pMetaPExtFuncs);
|
||||||
|
|
||||||
|
#endif /* MM_PEXTENSIONS_H */
|
1919
amxmodx/modules.cpp
1919
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
#undef DLLEXPORT
|
#undef DLLEXPORT
|
||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define DLLEXPORT __attribute__((visibility("default")))
|
#define DLLEXPORT
|
||||||
#define WINAPI
|
#define WINAPI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef C_DLLEXPORT
|
#undef C_DLLEXPORT
|
||||||
@ -48,44 +48,6 @@
|
|||||||
#define RELOAD_MODULE 0
|
#define RELOAD_MODULE 0
|
||||||
#define STATIC_MODULE 1
|
#define STATIC_MODULE 1
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
Player_Name, //String
|
|
||||||
Player_Ip, //String
|
|
||||||
Player_Team, //String
|
|
||||||
Player_Ingame, //bool
|
|
||||||
Player_Authorized, //bool
|
|
||||||
Player_Vgui, //bool
|
|
||||||
Player_Time, //float
|
|
||||||
Player_Playtime, //float
|
|
||||||
Player_MenuExpire, //float
|
|
||||||
Player_Weapons, //struct{int,int}[32]
|
|
||||||
Player_CurrentWeapon, //int
|
|
||||||
Player_TeamID, //int
|
|
||||||
Player_Deaths, //int
|
|
||||||
Player_Aiming, //int
|
|
||||||
Player_Menu, //int
|
|
||||||
Player_Keys, //int
|
|
||||||
Player_Flags, //int[32]
|
|
||||||
Player_Newmenu, //int
|
|
||||||
Player_NewmenuPage, //int
|
|
||||||
} PlayerProp;
|
|
||||||
|
|
||||||
int CheckModules(AMX *amx, char error[128]);
|
int CheckModules(AMX *amx, char error[128]);
|
||||||
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
|
|
||||||
const char *StrCaseStr(const char *as, const char *bs);
|
|
||||||
|
|
||||||
class Debugger;
|
|
||||||
Debugger *DisableDebugHandler(AMX *amx);
|
|
||||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
|
||||||
|
|
||||||
bool DirExists(const char *dir);
|
|
||||||
const char* GetFileName(AMX *amx);
|
|
||||||
|
|
||||||
inline cell FloatToCell(float input)
|
|
||||||
{
|
|
||||||
REAL output = input;
|
|
||||||
return *(cell *)&output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __MODULES_H__
|
#endif // __MODULES_H__
|
||||||
|
6
amxmodx/msvc/amxmodx_mm.def
Executable file
6
amxmodx/msvc/amxmodx_mm.def
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
LIBRARY amxx_mm
|
||||||
|
EXPORTS
|
||||||
|
GiveFnptrsToDll @1
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
.data READ WRITE
|
@ -5,20 +5,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcpro
|
|||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
|
Debug = Debug
|
||||||
JITDebug = JITDebug
|
JITDebug = JITDebug
|
||||||
JITDebugBinLog = JITDebugBinLog
|
JITMemtestRelease = JITMemtestRelease
|
||||||
JITRelease = JITRelease
|
JITRelease = JITRelease
|
||||||
JITReleaseBinLog = JITReleaseBinLog
|
MaximalSpeed = MaximalSpeed
|
||||||
|
MemtestDebug = MemtestDebug
|
||||||
|
MemtestRelease = MemtestRelease
|
||||||
|
Release = Release
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfiguration) = postSolution
|
GlobalSection(ProjectConfiguration) = postSolution
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|Win32
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
|
||||||
|
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
Version="7.10"
|
Version="7.10"
|
||||||
Name="amxmodx"
|
Name="amxmodx"
|
||||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||||
RootNamespace="amxmodx"
|
|
||||||
SccProjectName=""
|
SccProjectName=""
|
||||||
SccLocalPath="">
|
SccLocalPath="">
|
||||||
<Platforms>
|
<Platforms>
|
||||||
@ -12,6 +11,283 @@
|
|||||||
Name="Win32"/>
|
Name="Win32"/>
|
||||||
</Platforms>
|
</Platforms>
|
||||||
<Configurations>
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory=".\Debug"
|
||||||
|
IntermediateDirectory=".\Debug"
|
||||||
|
ConfigurationType="2"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="5"
|
||||||
|
StructMemberAlignment="3"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\debug/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\debug/"
|
||||||
|
ObjectFile=".\debug/"
|
||||||
|
ProgramDataBaseFileName=".\debug/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="debug/amxmodx_mm.dll"
|
||||||
|
Version="0.1"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\debug/amxx_mm.lib"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
MkTypLibCompatible="TRUE"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
TargetEnvironment="1"
|
||||||
|
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1033"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory=".\Release"
|
||||||
|
IntermediateDirectory=".\Release"
|
||||||
|
ConfigurationType="2"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
GlobalOptimizations="TRUE"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||||
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\release/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\release/"
|
||||||
|
ObjectFile=".\release/"
|
||||||
|
ProgramDataBaseFileName=".\release/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="release/amxmodx_mm.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
ProgramDatabaseFile=".\release/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\release/amxx_mm.lib"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
MkTypLibCompatible="TRUE"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
TargetEnvironment="1"
|
||||||
|
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1033"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MemtestDebug|Win32"
|
||||||
|
OutputDirectory="MemtestDebug"
|
||||||
|
IntermediateDirectory="MemtestDebug"
|
||||||
|
ConfigurationType="2"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="5"
|
||||||
|
StructMemberAlignment="3"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\memtestdebug/"
|
||||||
|
ObjectFile=".\memtestdebug/"
|
||||||
|
ProgramDataBaseFileName=".\memtestdebug/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="memtestdebug/amxmodx_mm.dll"
|
||||||
|
Version="0.1"
|
||||||
|
LinkIncremental="2"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
MkTypLibCompatible="TRUE"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
TargetEnvironment="1"
|
||||||
|
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="_DEBUG"
|
||||||
|
Culture="1033"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="MemtestRelease|Win32"
|
||||||
|
OutputDirectory="MemtestRelease"
|
||||||
|
IntermediateDirectory="MemtestRelease"
|
||||||
|
ConfigurationType="2"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
GlobalOptimizations="TRUE"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||||
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\memtestrelease/"
|
||||||
|
ObjectFile=".\memtestrelease/"
|
||||||
|
ProgramDataBaseFileName=".\memtestrelease/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="memtestrelease/amxmodx_mm.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||||
|
GenerateMapFile="TRUE"
|
||||||
|
MapExports="TRUE"
|
||||||
|
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
MkTypLibCompatible="TRUE"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
TargetEnvironment="1"
|
||||||
|
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
PreprocessorDefinitions="NDEBUG"
|
||||||
|
Culture="1033"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="JITDebug|Win32"
|
Name="JITDebug|Win32"
|
||||||
OutputDirectory="JITDebug"
|
OutputDirectory="JITDebug"
|
||||||
@ -23,7 +299,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories=""
|
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
@ -46,14 +322,14 @@
|
|||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||||
Version="0.1"
|
Version="0.1"
|
||||||
LinkIncremental="2"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
IgnoreDefaultLibraryNames="MSVCRT"
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\jitdebug/amxmodx_mm.pdb"
|
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||||
ImportLibrary=".\jitdebug/amxmodx_mm.lib"/>
|
ImportLibrary=".\jitdebug/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
PreprocessorDefinitions="_DEBUG"
|
PreprocessorDefinitions="_DEBUG"
|
||||||
@ -92,13 +368,9 @@
|
|||||||
CharacterSet="2">
|
CharacterSet="2">
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
|
||||||
GlobalOptimizations="TRUE"
|
GlobalOptimizations="TRUE"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
EnableIntrinsicFunctions="TRUE"
|
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="TRUE"
|
|
||||||
OptimizeForProcessor="0"
|
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||||
IgnoreStandardIncludePath="FALSE"
|
IgnoreStandardIncludePath="FALSE"
|
||||||
@ -113,7 +385,6 @@
|
|||||||
ProgramDataBaseFileName=".\jitrelease/"
|
ProgramDataBaseFileName=".\jitrelease/"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
DebugInformationFormat="3"
|
|
||||||
CompileAs="0"/>
|
CompileAs="0"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
@ -128,9 +399,9 @@
|
|||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
IgnoreDefaultLibraryNames="MSVCRT"
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
|
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
||||||
GenerateMapFile="TRUE"
|
GenerateMapFile="FALSE"
|
||||||
ImportLibrary=".\jitrelease/amxmodx_mm.lib"/>
|
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
PreprocessorDefinitions="NDEBUG"
|
PreprocessorDefinitions="NDEBUG"
|
||||||
@ -160,54 +431,53 @@
|
|||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="JITDebugBinLog|Win32"
|
Name="JITMemtestRelease|Win32"
|
||||||
OutputDirectory="$(ConfigurationName)"
|
OutputDirectory="JITMemtestRelease"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="JITMemtestRelease"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
UseOfMFC="0"
|
UseOfMFC="0"
|
||||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
CharacterSet="2">
|
CharacterSet="2">
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
GlobalOptimizations="TRUE"
|
||||||
AdditionalIncludeDirectories=""
|
InlineFunctionExpansion="1"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED"
|
FavorSizeOrSpeed="1"
|
||||||
BasicRuntimeChecks="3"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
RuntimeLibrary="5"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||||
StructMemberAlignment="3"
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
UsePrecompiledHeader="2"
|
UsePrecompiledHeader="2"
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
|
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
|
||||||
AssemblerListingLocation=".\jitdebugbinlog/"
|
AssemblerListingLocation=".\jitmemtestrelease/"
|
||||||
ObjectFile=".\jitdebugbinlog/"
|
ObjectFile=".\jitmemtestrelease/"
|
||||||
ProgramDataBaseFileName=".\jitdebugbinlog/"
|
ProgramDataBaseFileName=".\jitmemtestrelease/"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
DebugInformationFormat="4"
|
|
||||||
CompileAs="0"/>
|
CompileAs="0"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
|
||||||
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
|
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||||
Version="0.1"
|
LinkIncremental="1"
|
||||||
LinkIncremental="2"
|
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
|
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||||
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"/>
|
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
PreprocessorDefinitions="_DEBUG"
|
PreprocessorDefinitions="NDEBUG"
|
||||||
MkTypLibCompatible="TRUE"
|
MkTypLibCompatible="TRUE"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
TargetEnvironment="1"
|
TargetEnvironment="1"
|
||||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPostBuildEventTool"/>
|
Name="VCPostBuildEventTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
@ -216,7 +486,7 @@
|
|||||||
Name="VCPreLinkEventTool"/>
|
Name="VCPreLinkEventTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCResourceCompilerTool"
|
Name="VCResourceCompilerTool"
|
||||||
PreprocessorDefinitions="_DEBUG"
|
PreprocessorDefinitions="NDEBUG"
|
||||||
Culture="1033"/>
|
Culture="1033"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCWebServiceProxyGeneratorTool"/>
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
@ -230,54 +500,48 @@
|
|||||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="JITReleaseBinLog|Win32"
|
Name="MaximalSpeed|Win32"
|
||||||
OutputDirectory="$(ConfigurationName)"
|
OutputDirectory="MaximalSpeed"
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
IntermediateDirectory="MaximalSpeed"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
UseOfMFC="0"
|
UseOfMFC="0"
|
||||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
CharacterSet="2">
|
CharacterSet="2">
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="2"
|
|
||||||
GlobalOptimizations="TRUE"
|
GlobalOptimizations="TRUE"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
EnableIntrinsicFunctions="TRUE"
|
EnableIntrinsicFunctions="TRUE"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="TRUE"
|
OptimizeForProcessor="2"
|
||||||
OptimizeForProcessor="0"
|
OptimizeForWindowsApplication="TRUE"
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||||
IgnoreStandardIncludePath="FALSE"
|
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
UsePrecompiledHeader="2"
|
UsePrecompiledHeader="2"
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
|
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
|
||||||
AssemblerListingLocation=".\jitreleasebinlog/"
|
AssemblerListingLocation=".\MaximalSpeed/"
|
||||||
ObjectFile=".\jitreleasebinlog/"
|
ObjectFile=".\MaximalSpeed/"
|
||||||
ProgramDataBaseFileName=".\jitreleasebinlog/"
|
ProgramDataBaseFileName=".\MaximalSpeed/"
|
||||||
WarningLevel="3"
|
WarningLevel="3"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
DebugInformationFormat="3"
|
|
||||||
CompileAs="0"/>
|
CompileAs="0"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"/>
|
Name="VCCustomBuildTool"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||||
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
|
OutputFile="MaximalSpeed/amxmodx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
|
||||||
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
|
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||||
GenerateMapFile="TRUE"
|
|
||||||
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"/>
|
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
PreprocessorDefinitions="NDEBUG"
|
PreprocessorDefinitions="NDEBUG"
|
||||||
@ -322,9 +586,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxdbg.cpp">
|
RelativePath="..\amxdbg.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\amxmod_compat.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.cpp">
|
RelativePath="..\amxmodx.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -337,21 +598,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxxlog.cpp">
|
RelativePath="..\amxxlog.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\binlog.cpp">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebug|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CCmd.cpp">
|
RelativePath="..\CCmd.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -388,14 +634,17 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CVault.cpp">
|
RelativePath="..\CVault.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\emsg.cpp">
|
RelativePath="..\emsg.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\fakemeta.cpp">
|
RelativePath="..\fakemeta.cpp">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="MemtestDebug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
GeneratePreprocessedFile="0"/>
|
||||||
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\file.cpp">
|
RelativePath="..\file.cpp">
|
||||||
@ -403,30 +652,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\float.cpp">
|
RelativePath="..\float.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\format.cpp">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="4"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="4"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\libraries.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.cpp">
|
RelativePath="..\md5.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\messages.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\meta_api.cpp">
|
RelativePath="..\meta_api.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -439,35 +667,14 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\newmenus.cpp">
|
RelativePath="..\newmenus.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\nongpl_matches.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\optimizer.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\power.cpp">
|
RelativePath="..\power.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\sorting.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\srvcmd.cpp">
|
RelativePath="..\srvcmd.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\string.cpp">
|
RelativePath="..\string.cpp">
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="2"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="2"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\strptime.cpp">
|
RelativePath="..\strptime.cpp">
|
||||||
@ -478,9 +685,43 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\vault.cpp">
|
RelativePath="..\vault.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<Filter
|
||||||
RelativePath="..\vector.cpp">
|
Name="mmgr"
|
||||||
</File>
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\mmgr\mmgr.cpp">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="JITDebug|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="JITRelease|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="MaximalSpeed|Win32"
|
||||||
|
ExcludedFromBuild="TRUE">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@ -491,9 +732,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxdbg.h">
|
RelativePath="..\amxdbg.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\amxmod_compat.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.h">
|
RelativePath="..\amxmodx.h">
|
||||||
</File>
|
</File>
|
||||||
@ -503,9 +741,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxxlog.h">
|
RelativePath="..\amxxlog.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\binlog.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CCmd.h">
|
RelativePath="..\CCmd.h">
|
||||||
</File>
|
</File>
|
||||||
@ -542,6 +777,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CQueue.h">
|
RelativePath="..\CQueue.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CStack.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CString.h">
|
RelativePath="..\CString.h">
|
||||||
</File>
|
</File>
|
||||||
@ -554,27 +792,15 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CVector.h">
|
RelativePath="..\CVector.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\fakemeta.h">
|
RelativePath="..\fakemeta.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\format.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\libraries.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.h">
|
RelativePath="..\md5.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\menus.h">
|
RelativePath="..\menus.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\messages.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\modules.h">
|
RelativePath="..\modules.h">
|
||||||
</File>
|
</File>
|
||||||
@ -584,30 +810,25 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\newmenus.h">
|
RelativePath="..\newmenus.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\nongpl_matches.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\optimizer.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\resource.h">
|
RelativePath="..\resource.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\sh_list.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sh_stack.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sh_tinyhash.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\zlib\zconf.h">
|
RelativePath="..\zlib\zconf.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\zlib\zlib.h">
|
RelativePath="..\zlib\zlib.h">
|
||||||
</File>
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="mmgr"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\mmgr\mmgr.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mmgr\nommgr.h">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
@ -616,72 +837,6 @@
|
|||||||
RelativePath="..\version.rc">
|
RelativePath="..\version.rc">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Assembly"
|
|
||||||
Filter="">
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxdefn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxexecn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxjitsn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\helpers-x86.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-amd64.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-x86.asm">
|
|
||||||
</File>
|
|
||||||
<Filter
|
|
||||||
Name="Builds"
|
|
||||||
Filter="">
|
|
||||||
<File
|
|
||||||
RelativePath="..\Jit\helpers-x86.obj">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="SDK"
|
|
||||||
Filter="">
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\amxxmodule.cpp">
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebug|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebugBinLog|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32"
|
|
||||||
ExcludedFromBuild="TRUE">
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\amxxmodule.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\moduleconfig.h">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
|
||||||
# Visual Studio 2005
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
JITDebug|Win32 = JITDebug|Win32
|
|
||||||
JITDebugBinLog|Win32 = JITDebugBinLog|Win32
|
|
||||||
JITRelease|Win32 = JITRelease|Win32
|
|
||||||
JITReleaseBinLog|Win32 = JITReleaseBinLog|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.ActiveCfg = JITDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.Build.0 = JITDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.ActiveCfg = JITDebugBinLog|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.Build.0 = JITDebugBinLog|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.ActiveCfg = JITRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.Build.0 = JITRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.ActiveCfg = JITReleaseBinLog|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.Build.0 = JITReleaseBinLog|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@ -1,930 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="8.00"
|
|
||||||
Name="amxmodx_mm"
|
|
||||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
|
||||||
RootNamespace="amxmodx"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="JITDebug|Win32"
|
|
||||||
OutputDirectory="JITDebug"
|
|
||||||
IntermediateDirectory="JITDebug"
|
|
||||||
ConfigurationType="2"
|
|
||||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
|
||||||
UseOfMFC="0"
|
|
||||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
|
||||||
CharacterSet="2"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
MkTypLibCompatible="true"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
TargetEnvironment="1"
|
|
||||||
TypeLibraryName=".\debug/amxmodx.tlb"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="1"
|
|
||||||
StructMemberAlignment="3"
|
|
||||||
TreatWChar_tAsBuiltInType="true"
|
|
||||||
RuntimeTypeInfo="false"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
|
||||||
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
|
|
||||||
AssemblerListingLocation=".\jitdebug/"
|
|
||||||
ObjectFile=".\jitdebug/"
|
|
||||||
ProgramDataBaseFileName=".\jitdebug/"
|
|
||||||
WarningLevel="3"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
CompileAs="0"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
Culture="1033"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalOptions="/MACHINE:I386"
|
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
|
||||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
|
||||||
Version="0.1"
|
|
||||||
LinkIncremental="2"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
|
||||||
ImportLibrary=".\jitdebug/amxmodx_mm.lib"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
OutputDirectory="JITRelease"
|
|
||||||
IntermediateDirectory="JITRelease"
|
|
||||||
ConfigurationType="2"
|
|
||||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
|
||||||
UseOfMFC="0"
|
|
||||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
|
||||||
CharacterSet="2"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
MkTypLibCompatible="true"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
TargetEnvironment="1"
|
|
||||||
TypeLibraryName=".\release/amxmodx.tlb"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
InlineFunctionExpansion="1"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
FavorSizeOrSpeed="1"
|
|
||||||
OmitFramePointers="true"
|
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE"
|
|
||||||
IgnoreStandardIncludePath="false"
|
|
||||||
StringPooling="true"
|
|
||||||
RuntimeLibrary="0"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
TreatWChar_tAsBuiltInType="true"
|
|
||||||
RuntimeTypeInfo="false"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
|
||||||
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
|
|
||||||
AssemblerListingLocation=".\jitrelease/"
|
|
||||||
ObjectFile=".\jitrelease/"
|
|
||||||
ProgramDataBaseFileName=".\jitrelease/"
|
|
||||||
WarningLevel="3"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
CompileAs="0"
|
|
||||||
ShowIncludes="false"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
Culture="1033"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalOptions="/MACHINE:I386"
|
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
|
||||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
|
|
||||||
GenerateMapFile="true"
|
|
||||||
ImportLibrary=".\jitrelease/amxmodx_mm.lib"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="JITDebugBinLog|Win32"
|
|
||||||
OutputDirectory="$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="2"
|
|
||||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
|
||||||
UseOfMFC="0"
|
|
||||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
|
||||||
CharacterSet="2"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
MkTypLibCompatible="true"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
TargetEnvironment="1"
|
|
||||||
TypeLibraryName=".\debug/amxmodx.tlb"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
AdditionalIncludeDirectories=""
|
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="1"
|
|
||||||
StructMemberAlignment="3"
|
|
||||||
TreatWChar_tAsBuiltInType="true"
|
|
||||||
RuntimeTypeInfo="false"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
|
||||||
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
|
|
||||||
AssemblerListingLocation=".\jitdebugbinlog/"
|
|
||||||
ObjectFile=".\jitdebugbinlog/"
|
|
||||||
ProgramDataBaseFileName=".\jitdebugbinlog/"
|
|
||||||
WarningLevel="3"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
CompileAs="0"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
Culture="1033"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalOptions="/MACHINE:I386"
|
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
|
||||||
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
|
|
||||||
Version="0.1"
|
|
||||||
LinkIncremental="2"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
|
|
||||||
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="JITReleaseBinLog|Win32"
|
|
||||||
OutputDirectory="$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="2"
|
|
||||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
|
||||||
UseOfMFC="0"
|
|
||||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
|
||||||
CharacterSet="2"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
MkTypLibCompatible="true"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
TargetEnvironment="1"
|
|
||||||
TypeLibraryName=".\release/amxmodx.tlb"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
InlineFunctionExpansion="1"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
FavorSizeOrSpeed="1"
|
|
||||||
OmitFramePointers="true"
|
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
|
|
||||||
IgnoreStandardIncludePath="false"
|
|
||||||
StringPooling="true"
|
|
||||||
RuntimeLibrary="0"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
TreatWChar_tAsBuiltInType="true"
|
|
||||||
RuntimeTypeInfo="false"
|
|
||||||
UsePrecompiledHeader="0"
|
|
||||||
PrecompiledHeaderThrough="amxmodx.h"
|
|
||||||
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
|
|
||||||
AssemblerListingLocation=".\jitreleasebinlog/"
|
|
||||||
ObjectFile=".\jitreleasebinlog/"
|
|
||||||
ProgramDataBaseFileName=".\jitreleasebinlog/"
|
|
||||||
WarningLevel="3"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
CompileAs="0"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
Culture="1033"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
AdditionalOptions="/MACHINE:I386"
|
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
|
||||||
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
|
|
||||||
LinkIncremental="1"
|
|
||||||
SuppressStartupBanner="true"
|
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
|
||||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
|
|
||||||
GenerateMapFile="true"
|
|
||||||
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebDeploymentTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amx.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxcore.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxdbg.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxmod_compat.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxmodx.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxtime.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxxfile.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxxlog.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\binlog.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebug|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CCmd.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CEvent.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CFile.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CForward.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CLang.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CLogEvent.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CMenu.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CMisc.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CModule.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CPlugin.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CTask.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CVault.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\emsg.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\fakemeta.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\file.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\float.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\format.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="4"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="4"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\libraries.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\md5.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\messages.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\meta_api.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\modules.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\newmenus.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\nongpl_matches.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\optimizer.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\power.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sorting.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\srvcmd.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\string.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="2"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
AssemblerOutput="2"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\strptime.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\util.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\vault.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\vector.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amx.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxdbg.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxmod_compat.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxmodx.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxxfile.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxxlog.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\binlog.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CCmd.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CEvent.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CFile.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CForward.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CLang.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CList.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CLogEvent.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CMenu.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CMisc.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CModule.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CPlugin.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CQueue.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CString.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CTask.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CVault.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\CVector.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\fakemeta.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\format.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\libraries.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\md5.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\messages.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\modules.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\newmenus.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\nongpl_matches.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\optimizer.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\resource.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sh_list.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sh_stack.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sh_tinyhash.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\zlib\zconf.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\zlib\zlib.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\version.rc"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Assembly"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxdefn.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxexecn.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxjitsn.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\helpers-x86.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-amd64.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-x86.asm"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<Filter
|
|
||||||
Name="Builds"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\Jit\helpers-x86.obj"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="SDK"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\amxxmodule.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebug|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITRelease|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITDebugBinLog|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="JITReleaseBinLog|Win32"
|
|
||||||
ExcludedFromBuild="true"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\amxxmodule.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\sdk\moduleconfig.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@ -95,6 +95,4 @@ _amxx_DynaCodesize:
|
|||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
GLOBAL_GATE DD 0
|
GLOBAL_GATE DD 0
|
||||||
|
@ -29,27 +29,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "sh_stack.h"
|
|
||||||
#include "natives.h"
|
|
||||||
#include "debugger.h"
|
|
||||||
#include "libraries.h"
|
|
||||||
#include "format.h"
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "CStack.h"
|
||||||
|
#include "natives.h"
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "sclinux.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Written by David "BAILOPAN" Anderson
|
//Written by David "BAILOPAN" Anderson
|
||||||
//With the exception for param_convert, which was written by
|
//With the exception for param_convert, which was written by
|
||||||
// Julien "dJeyL" Laurent
|
// Julien "dJeyL" Laurent
|
||||||
|
|
||||||
CStack<int> g_ErrorStk;
|
|
||||||
CVector<regnative *> g_RegNatives;
|
CVector<regnative *> g_RegNatives;
|
||||||
CStack<regnative *> g_NativeStack;
|
CStack<regnative *> g_NativeStack;
|
||||||
|
CVector<String> g_Libraries;
|
||||||
static char g_errorStr[512] = {0};
|
static char g_errorStr[512] = {0};
|
||||||
|
static int g_errorNum = 0;
|
||||||
bool g_Initialized = false;
|
bool g_Initialized = false;
|
||||||
|
|
||||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||||
@ -69,68 +66,39 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
|
||||||
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
|
|
||||||
|
|
||||||
if (!pNativePlugin->isExecutable(pNative->func))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
|
|
||||||
pPlugin->setStatus(ps_paused);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pNative->caller)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Bug caught! Please contact the AMX Mod X Dev Team.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//parameter stack
|
//parameter stack
|
||||||
//NOTE: it is possible that recursive register native calling
|
|
||||||
// could potentially be somehow damaged here.
|
|
||||||
//so, a :TODO: - make the stack unique, rather than a known ptr
|
|
||||||
pNative->caller = amx;
|
pNative->caller = amx;
|
||||||
|
|
||||||
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
cell ret = 0;
|
cell ret = 0;
|
||||||
g_ErrorStk.push(0);
|
g_errorNum = 0;
|
||||||
g_NativeStack.push(pNative);
|
g_NativeStack.push(pNative);
|
||||||
if (pNative->style == 0)
|
if (pNative->style == 0)
|
||||||
{
|
{
|
||||||
amx_Push(pNative->amx, numParams);
|
amx_Push(pNative->amx, numParams);
|
||||||
amx_Push(pNative->amx, pPlugin->getId());
|
amx_Push(pNative->amx, pPlugin->getId());
|
||||||
for (int i=numParams; i>=0; i--)
|
for (int i=numParams; i>=1; i--)
|
||||||
pNative->params[i] = params[i];
|
pNative->params[i] = params[i];
|
||||||
} else if (pNative->style == 1) {
|
} else if (pNative->style == 1) {
|
||||||
//use dJeyL's system .. very clever!
|
//use dJeyL's system .. very clever!
|
||||||
for (int i=numParams; i>=1; i--)
|
for (int i=numParams; i>=1; i--)
|
||||||
amx_Push(pNative->amx, params[i]);
|
amx_Push(pNative->amx, params[i]);
|
||||||
}
|
}
|
||||||
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->BeginExec();
|
|
||||||
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
|
||||||
if (err != AMX_ERR_NONE)
|
|
||||||
{
|
{
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
g_NativeStack.pop();
|
||||||
{
|
LogError(pNative->amx, err, "");
|
||||||
//don't care
|
return 0;
|
||||||
} else if (err != -1) {
|
}
|
||||||
//nothing logged the error
|
if (g_errorNum)
|
||||||
LogError(pNative->amx, err, NULL);
|
{
|
||||||
}
|
g_NativeStack.pop();
|
||||||
pNative->amx->error = AMX_ERR_NONE;
|
LogError(amx, g_errorNum, g_errorStr);
|
||||||
//furthermore, log an error in the parent plugin.
|
return ret;
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
|
|
||||||
} else if (g_ErrorStk.front()) {
|
|
||||||
LogError(amx, g_ErrorStk.front(), g_errorStr);
|
|
||||||
}
|
}
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->EndExec();
|
|
||||||
g_NativeStack.pop();
|
g_NativeStack.pop();
|
||||||
g_ErrorStk.pop();
|
|
||||||
|
|
||||||
pNative->caller = NULL;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -164,8 +132,7 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
|||||||
char *err = format_amxstring(amx, params, 2, len);
|
char *err = format_amxstring(amx, params, 2, len);
|
||||||
|
|
||||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
||||||
g_ErrorStk.pop();
|
g_errorNum = params[1];
|
||||||
g_ErrorStk.push(params[1]);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -178,7 +145,7 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -199,7 +166,7 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -222,7 +189,7 @@ static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -241,7 +208,7 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -262,7 +229,7 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -285,7 +252,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -298,7 +265,8 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
|||||||
|
|
||||||
int size = params[3];
|
int size = params[3];
|
||||||
|
|
||||||
memcpy(dest, source, size * sizeof(cell));
|
while (size-->0)
|
||||||
|
*dest = *source;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -311,7 +279,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style)
|
if (pNative->style)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -324,75 +292,12 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
|||||||
|
|
||||||
int size = params[3];
|
int size = params[3];
|
||||||
|
|
||||||
memcpy(dest, source, size * sizeof(cell));
|
while (size-->0)
|
||||||
|
*dest = *source;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
regnative *pNative = g_NativeStack.front();
|
|
||||||
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vargPos = static_cast<int>(params[4]);
|
|
||||||
int fargPos = static_cast<int>(params[3]);
|
|
||||||
|
|
||||||
/** get the parent parameter array */
|
|
||||||
cell *local_params = pNative->params;
|
|
||||||
|
|
||||||
cell max = local_params[0] / sizeof(cell);
|
|
||||||
if (vargPos > (int)max + 1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (fargPos > (int)max + 1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid fmtarg parameter passed: %d", fargPos);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get destination info */
|
|
||||||
cell *fmt;
|
|
||||||
if (fargPos == 0)
|
|
||||||
{
|
|
||||||
if (params[0] / sizeof(cell) != 5)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Expected fmtarg as fifth parameter, found none");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
fmt = get_amxaddr(amx, params[5]);
|
|
||||||
} else {
|
|
||||||
fmt = get_amxaddr(pNative->caller, pNative->params[fargPos]);
|
|
||||||
}
|
|
||||||
cell *realdest = get_amxaddr(amx, params[1]);
|
|
||||||
size_t maxlen = static_cast<size_t>(params[2]);
|
|
||||||
cell *dest = realdest;
|
|
||||||
|
|
||||||
/* if this is necessary... */
|
|
||||||
static cell cpbuf[4096];
|
|
||||||
dest = cpbuf;
|
|
||||||
|
|
||||||
/* perform format */
|
|
||||||
size_t total = atcprintf(dest, maxlen, fmt, pNative->caller, local_params, &vargPos);
|
|
||||||
|
|
||||||
/* copy back */
|
|
||||||
memcpy(realdest, dest, (total+1) * sizeof(cell));
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is basically right from dJeyL's lib_convert function
|
//This is basically right from dJeyL's lib_convert function
|
||||||
//This awesome hack modifies the stack frame to have an address offset
|
//This awesome hack modifies the stack frame to have an address offset
|
||||||
// that will align to the other plugin's memory.
|
// that will align to the other plugin's memory.
|
||||||
@ -404,7 +309,7 @@ static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
|||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
regnative *pNative = g_NativeStack.front();
|
regnative *pNative = g_NativeStack.top();
|
||||||
if (pNative->style != 1)
|
if (pNative->style != 1)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||||
@ -427,7 +332,7 @@ static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
|||||||
int len;
|
int len;
|
||||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
char *lib = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
|
AddPluginLibrary(lib);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -454,7 +359,6 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
|||||||
regnative *pNative = new regnative;
|
regnative *pNative = new regnative;
|
||||||
pNative->amx = amx;
|
pNative->amx = amx;
|
||||||
pNative->func = idx;
|
pNative->func = idx;
|
||||||
pNative->caller = NULL;
|
|
||||||
|
|
||||||
//we'll apply a safety buffer too
|
//we'll apply a safety buffer too
|
||||||
//make our function
|
//make our function
|
||||||
@ -481,12 +385,30 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LibraryExists(const char *name)
|
||||||
|
{
|
||||||
|
for (size_t i=0; i<g_Libraries.size(); i++)
|
||||||
|
{
|
||||||
|
if (stricmp(g_Libraries[i].c_str(), name)==0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddPluginLibrary(const char *name)
|
||||||
|
{
|
||||||
|
String f(name);
|
||||||
|
g_Libraries.push_back(f);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearPluginLibraries()
|
void ClearPluginLibraries()
|
||||||
{
|
{
|
||||||
ClearLibraries(LibSource_Plugin);
|
g_Libraries.clear();
|
||||||
|
|
||||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||||
{
|
{
|
||||||
delete [] g_RegNatives[i]->pfn;
|
delete g_RegNatives[i]->pfn;
|
||||||
delete g_RegNatives[i];
|
delete g_RegNatives[i];
|
||||||
}
|
}
|
||||||
g_RegNatives.clear();
|
g_RegNatives.clear();
|
||||||
@ -501,7 +423,7 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
|
|||||||
{"get_param", get_param},
|
{"get_param", get_param},
|
||||||
{"get_param_byref", get_param_byref},
|
{"get_param_byref", get_param_byref},
|
||||||
{"set_param_byref", set_param_byref},
|
{"set_param_byref", set_param_byref},
|
||||||
{"get_array", get_array},
|
{"get_array", set_array},
|
||||||
{"set_array", set_array},
|
{"set_array", set_array},
|
||||||
//these are dummy functions for floats ;p
|
//these are dummy functions for floats ;p
|
||||||
{"get_param_f", get_param},
|
{"get_param_f", get_param},
|
||||||
@ -509,7 +431,6 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
|
|||||||
{"set_float_byref", set_param_byref},
|
{"set_float_byref", set_param_byref},
|
||||||
{"get_array_f", get_array},
|
{"get_array_f", get_array},
|
||||||
{"set_array_f", set_array},
|
{"set_array_f", set_array},
|
||||||
{"vdformat", vdformat},
|
|
||||||
{"param_convert", param_convert},
|
{"param_convert", param_convert},
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
|
@ -32,9 +32,7 @@
|
|||||||
#define _INCLUDE_NATIVES_H
|
#define _INCLUDE_NATIVES_H
|
||||||
|
|
||||||
//only 16 for now sorry
|
//only 16 for now sorry
|
||||||
#if !defined CALLFUNC_MAXPARAMS
|
|
||||||
#define CALLFUNC_MAXPARAMS 16
|
#define CALLFUNC_MAXPARAMS 16
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CALLFUNC_FLAG_BYREF 1
|
#define CALLFUNC_FLAG_BYREF 1
|
||||||
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
||||||
@ -61,7 +59,9 @@ extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
|||||||
extern "C" int amxx_DynaCodesize();
|
extern "C" int amxx_DynaCodesize();
|
||||||
|
|
||||||
AMX_NATIVE_INFO *BuildNativeTable();
|
AMX_NATIVE_INFO *BuildNativeTable();
|
||||||
|
void AddPluginLibrary(const char *name);
|
||||||
void ClearPluginLibraries();
|
void ClearPluginLibraries();
|
||||||
|
bool LibraryExists(const char *name);
|
||||||
|
|
||||||
//I couldn't resist :)
|
//I couldn't resist :)
|
||||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
extern AMX_NATIVE_INFO g_NativeNatives[];
|
||||||
|
@ -1,83 +1,13 @@
|
|||||||
/* 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 "amxmodx.h"
|
||||||
#include "newmenus.h"
|
#include "newmenus.h"
|
||||||
|
|
||||||
CVector<Menu *> g_NewMenus;
|
CVector<Menu *> g_NewMenus;
|
||||||
CStack<int> g_MenuFreeStack;
|
|
||||||
|
|
||||||
void ClearMenus()
|
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];
|
delete g_NewMenus[i];
|
||||||
}
|
|
||||||
|
|
||||||
g_NewMenus.clear();
|
g_NewMenus.clear();
|
||||||
while (!g_MenuFreeStack.empty())
|
|
||||||
{
|
|
||||||
g_MenuFreeStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void validate_menu_text(char *str)
|
|
||||||
{
|
|
||||||
if (!g_coloredmenus)
|
|
||||||
{
|
|
||||||
size_t offs = 0;
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
if (*str == '\\')
|
|
||||||
{
|
|
||||||
str++;
|
|
||||||
char c = tolower(*str);
|
|
||||||
if (c == 'r' || c == 'w'
|
|
||||||
|| c== 'w' || c == 'd')
|
|
||||||
{
|
|
||||||
str++;
|
|
||||||
offs += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (offs)
|
|
||||||
{
|
|
||||||
*(str-offs) = *str;
|
|
||||||
}
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
if (offs)
|
|
||||||
{
|
|
||||||
*(str-offs) = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::Menu(const char *title, int mid, int tid)
|
Menu::Menu(const char *title, int mid, int tid)
|
||||||
@ -85,34 +15,12 @@ Menu::Menu(const char *title, int mid, int tid)
|
|||||||
m_Title.assign(title);
|
m_Title.assign(title);
|
||||||
menuId = mid;
|
menuId = mid;
|
||||||
thisId = tid;
|
thisId = tid;
|
||||||
|
|
||||||
m_OptNames[abs(MENU_BACK)].assign("Back");
|
|
||||||
m_OptNames[abs(MENU_MORE)].assign("More");
|
|
||||||
m_OptNames[abs(MENU_EXIT)].assign("Exit");
|
|
||||||
|
|
||||||
m_OptOrders[0] = MENU_BACK;
|
|
||||||
m_OptOrders[1] = MENU_MORE;
|
|
||||||
m_OptOrders[2] = MENU_EXIT;
|
|
||||||
|
|
||||||
m_AlwaysExit = false;
|
|
||||||
m_NeverExit = false;
|
|
||||||
m_AutoColors = g_coloredmenus;
|
|
||||||
|
|
||||||
items_per_page = 7;
|
|
||||||
func = 0;
|
|
||||||
padding = 0;
|
|
||||||
isDestroying = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu::~Menu()
|
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];
|
delete m_Items[i];
|
||||||
}
|
|
||||||
|
|
||||||
unregisterSPForward(this->func);
|
|
||||||
|
|
||||||
m_Items.clear();
|
m_Items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,112 +56,60 @@ size_t Menu::GetItemCount()
|
|||||||
size_t Menu::GetPageCount()
|
size_t Menu::GetPageCount()
|
||||||
{
|
{
|
||||||
size_t items = GetItemCount();
|
size_t items = GetItemCount();
|
||||||
if (items_per_page == 0)
|
page_t numPages = (items / MENUITEMS) + 1;
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((items/items_per_page) + ((items % items_per_page) ? 1 : 0));
|
if (!items)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (numPages % MENUITEMS == 0)
|
||||||
|
numPages--;
|
||||||
|
|
||||||
|
return numPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Menu::PagekeyToItem(page_t page, item_t key)
|
int Menu::PagekeyToItem(page_t page, item_t key)
|
||||||
{
|
{
|
||||||
size_t start = page * items_per_page;
|
page_t pages = GetPageCount();
|
||||||
size_t num_pages = GetPageCount();
|
item_t numItems = GetItemCount();
|
||||||
|
|
||||||
if (num_pages == 1 || !items_per_page)
|
if (page >= pages)
|
||||||
|
return MENU_EXIT;
|
||||||
|
|
||||||
|
item_t start = page * 7;
|
||||||
|
|
||||||
|
if (page == 0)
|
||||||
{
|
{
|
||||||
if (key > m_Items.size())
|
item_t rem = numItems >= 7 ? 7 : numItems;
|
||||||
return MENU_EXIT;
|
if (key == rem)
|
||||||
else
|
|
||||||
return key-1;
|
|
||||||
} else {
|
|
||||||
//first page
|
|
||||||
if (page == 0)
|
|
||||||
{
|
{
|
||||||
/* The algorithm for spaces here is same as a middle page. */
|
if (pages > 1)
|
||||||
item_t new_key = key;
|
|
||||||
for (size_t i=start; i<(start+key-1) && i<m_Items.size(); i++)
|
|
||||||
{
|
|
||||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
|
||||||
{
|
|
||||||
if (m_Items[i]->blanks[j] == 1)
|
|
||||||
{
|
|
||||||
if (!new_key)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_key--;
|
|
||||||
}
|
|
||||||
if (!new_key)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key = new_key;
|
|
||||||
if (key == items_per_page + 1)
|
|
||||||
{
|
|
||||||
return MENU_MORE;
|
return MENU_MORE;
|
||||||
} else if (key == items_per_page + 2) {
|
else
|
||||||
return MENU_EXIT;
|
return MENU_EXIT;
|
||||||
} else {
|
} else if (key == rem+1) {
|
||||||
return (start + key - 1);
|
return MENU_EXIT;
|
||||||
}
|
}
|
||||||
} else if (page == num_pages - 1) {
|
} else if (page == pages - 1) {
|
||||||
//last page
|
//find number of remaining items
|
||||||
size_t remaining = m_Items.size() - start;
|
//for example, 11 items on page 1... means start=7, 11-7=4
|
||||||
/* We have to add one remaining for each "bumping" space */
|
item_t rem = numItems - start;
|
||||||
for (size_t i=m_Items.size() - remaining; i<m_Items.size(); i++)
|
//however, the last item is actually this -1, so...
|
||||||
{
|
if (key == rem)
|
||||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
{
|
||||||
{
|
return MENU_EXIT;
|
||||||
if (m_Items[i]->blanks[j] == 1)
|
} else if (key == rem+1) {
|
||||||
{
|
return MENU_BACK;
|
||||||
remaining++;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (key == 7)
|
||||||
}
|
{
|
||||||
if (key == remaining + 1)
|
return MENU_MORE;
|
||||||
{
|
} else if (key == 8) {
|
||||||
return MENU_BACK;
|
return MENU_BACK;
|
||||||
} else if (key == remaining + 2) {
|
|
||||||
return MENU_EXIT;
|
|
||||||
} else {
|
|
||||||
return (start + key - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* The algorithm for spaces here is a bit harder. We have to subtract
|
|
||||||
* one from the key for each space we find along the way.
|
|
||||||
*/
|
|
||||||
item_t new_key = key;
|
|
||||||
for (size_t i=start; i<(start+key-1) && i<m_Items.size(); i++)
|
|
||||||
{
|
|
||||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
|
||||||
{
|
|
||||||
if (m_Items[i]->blanks[j] == 1)
|
|
||||||
{
|
|
||||||
if (!new_key)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
new_key--;
|
|
||||||
}
|
|
||||||
if (!new_key)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
key = new_key;
|
|
||||||
if (key > items_per_page && (key-items_per_page<=3))
|
|
||||||
{
|
|
||||||
return m_OptOrders[key-items_per_page-1];
|
|
||||||
} else {
|
|
||||||
return (start + key - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (start + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Menu::Display(int player, page_t page)
|
bool Menu::Display(int player, page_t page)
|
||||||
@ -290,217 +146,89 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
|||||||
m_Text.clear();
|
m_Text.clear();
|
||||||
|
|
||||||
char buffer[255];
|
char buffer[255];
|
||||||
if (items_per_page && (pages != 1))
|
if (g_coloredmenus)
|
||||||
{
|
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page+1, pages);
|
||||||
if (m_AutoColors)
|
else
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\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);
|
||||||
else
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
|
||||||
} else {
|
|
||||||
if (m_AutoColors)
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
|
|
||||||
else
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Text.append(buffer);
|
m_Text.append(buffer);
|
||||||
|
|
||||||
enum
|
item_t start = page * 7;
|
||||||
{
|
|
||||||
Display_Back = (1<<0),
|
|
||||||
Display_Next = (1<<1),
|
|
||||||
Display_Exit = (1<<2),
|
|
||||||
};
|
|
||||||
|
|
||||||
int flags = Display_Back|Display_Next;
|
|
||||||
item_t start = page * items_per_page;
|
|
||||||
item_t end = 0;
|
item_t end = 0;
|
||||||
if (items_per_page)
|
if (start + 7 <= numItems)
|
||||||
{
|
{
|
||||||
if (start + items_per_page >= numItems)
|
end = start + 7;
|
||||||
{
|
|
||||||
end = numItems - 1;
|
|
||||||
flags &= ~Display_Next;
|
|
||||||
} else {
|
|
||||||
end = start + items_per_page - 1;
|
|
||||||
}
|
|
||||||
if (!m_NeverExit && (m_AlwaysExit || (page == 0 || page == pages-1)))
|
|
||||||
flags |= Display_Exit;
|
|
||||||
} else {
|
} else {
|
||||||
end = numItems - 1;
|
end = numItems;
|
||||||
if (end > 10)
|
|
||||||
end = 10;
|
|
||||||
flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page == 0)
|
|
||||||
flags &= ~Display_Back;
|
|
||||||
|
|
||||||
menuitem *pItem = NULL;
|
menuitem *pItem = NULL;
|
||||||
|
|
||||||
int option = 0;
|
int option = 0;
|
||||||
keys = 0;
|
keys = 0;
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int slots = 0;
|
for (item_t i=start; i<end; i++)
|
||||||
int option_display = 0;
|
|
||||||
|
|
||||||
for (item_t i = start; i <= end; i++)
|
|
||||||
{
|
{
|
||||||
pItem = m_Items[i];
|
pItem = m_Items[i];
|
||||||
|
|
||||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
||||||
{
|
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
|
||||||
|
|
||||||
if (pItem->handler != -1)
|
if (pItem->handler != -1)
|
||||||
{
|
{
|
||||||
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i));
|
ret = executeForwards(pItem->handler, player, thisId, i);
|
||||||
if (ret == ITEM_ENABLED)
|
if (ret == ITEM_ENABLED)
|
||||||
{
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
} else if (ret == ITEM_DISABLED) {
|
else if (ret == ITEM_DISABLED)
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pItem->pfn)
|
if (pItem->pfn)
|
||||||
{
|
{
|
||||||
ret = (pItem->pfn)(player, thisId, i);
|
ret = (pItem->pfn)(player, thisId, i);
|
||||||
if (ret == ITEM_ENABLED)
|
if (ret == ITEM_ENABLED)
|
||||||
{
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
} else if (ret == ITEM_DISABLED) {
|
else if (ret == ITEM_DISABLED)
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
{
|
{
|
||||||
keys |= (1<<option);
|
keys |= (1<<option);
|
||||||
}
|
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
|
||||||
|
|
||||||
option_display = ++option;
|
|
||||||
if (option_display == 10)
|
|
||||||
{
|
|
||||||
option_display = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
if (m_AutoColors)
|
|
||||||
{
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\r%d.\\w %s\n", option_display, pItem->name.c_str());
|
|
||||||
} else {
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option_display, pItem->name.c_str());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (m_AutoColors)
|
if (g_coloredmenus)
|
||||||
{
|
{
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", option_display, pItem->name.c_str());
|
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
|
||||||
} else {
|
} else {
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
||||||
|
option++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slots++;
|
|
||||||
|
|
||||||
m_Text.append(buffer);
|
m_Text.append(buffer);
|
||||||
|
|
||||||
//attach blanks
|
|
||||||
if (pItem->blanks.size())
|
|
||||||
{
|
|
||||||
for (size_t j=0; j<pItem->blanks.size(); j++)
|
|
||||||
{
|
|
||||||
if (pItem->blanks[j] == 1)
|
|
||||||
{
|
|
||||||
option++;
|
|
||||||
}
|
|
||||||
m_Text.append("\n");
|
|
||||||
slots++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//now for a weird part >:o
|
||||||
if (padding == 1 && items_per_page)
|
//this will either be MORE or BACK..
|
||||||
|
keys |= (1<<option++);
|
||||||
|
if ((page < pages - 1) && (pages > 1))
|
||||||
{
|
{
|
||||||
int pad = items_per_page;
|
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
|
||||||
if (flags & Display_Back)
|
} else {
|
||||||
|
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||||
|
}
|
||||||
|
m_Text.append(buffer);
|
||||||
|
if (pages > 1)
|
||||||
|
{
|
||||||
|
keys |= (1<<option++);
|
||||||
|
if (pages == 0)
|
||||||
{
|
{
|
||||||
pad--;
|
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||||
}
|
} else {
|
||||||
if (flags & Display_Next)
|
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
|
||||||
{
|
|
||||||
pad--;
|
|
||||||
}
|
|
||||||
if (flags & Display_Exit)
|
|
||||||
{
|
|
||||||
pad--;
|
|
||||||
}
|
|
||||||
for (int i=slots+1; i<=pad; i++)
|
|
||||||
{
|
|
||||||
m_Text.append("\n");
|
|
||||||
option++;
|
|
||||||
}
|
}
|
||||||
|
m_Text.append(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<3; i++)
|
|
||||||
{
|
|
||||||
switch (m_OptOrders[i])
|
|
||||||
{
|
|
||||||
case MENU_BACK:
|
|
||||||
{
|
|
||||||
if (flags & Display_Back)
|
|
||||||
{
|
|
||||||
keys |= (1<<option++);
|
|
||||||
_snprintf(buffer,
|
|
||||||
sizeof(buffer)-1,
|
|
||||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
|
||||||
option,
|
|
||||||
m_OptNames[abs(MENU_BACK)].c_str()
|
|
||||||
);
|
|
||||||
m_Text.append(buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_MORE:
|
|
||||||
{
|
|
||||||
if (flags & Display_Next)
|
|
||||||
{
|
|
||||||
keys |= (1<<option++);
|
|
||||||
_snprintf(buffer,
|
|
||||||
sizeof(buffer)-1,
|
|
||||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
|
||||||
option,
|
|
||||||
m_OptNames[abs(MENU_MORE)].c_str()
|
|
||||||
);
|
|
||||||
m_Text.append(buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MENU_EXIT:
|
|
||||||
{
|
|
||||||
if (flags & Display_Exit)
|
|
||||||
{
|
|
||||||
keys |= (1<<option++);
|
|
||||||
_snprintf(buffer,
|
|
||||||
sizeof(buffer)-1,
|
|
||||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
|
||||||
option,
|
|
||||||
m_OptNames[abs(MENU_EXIT)].c_str()
|
|
||||||
);
|
|
||||||
m_Text.append(buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_Text.c_str();
|
return m_Text.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \
|
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
|
||||||
return 0; } \
|
return 0; } \
|
||||||
Menu *pMenu = g_NewMenus[p];
|
Menu *pMenu = g_NewMenus[p];
|
||||||
|
|
||||||
@ -510,11 +238,9 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
|||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *title = get_amxstring(amx, params[1], 0, len);
|
char *title = get_amxstring(amx, params[1], 0, len);
|
||||||
validate_menu_text(title);
|
|
||||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
char *handler = get_amxstring(amx, params[2], 1, len);
|
||||||
|
|
||||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||||
|
|
||||||
if (func == -1)
|
if (func == -1)
|
||||||
{
|
{
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
||||||
@ -522,46 +248,12 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id = g_menucmds.registerMenuId(title, amx);
|
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, 0);
|
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
|
||||||
|
g_NewMenus.push_back(pMenu);
|
||||||
|
|
||||||
pMenu->func = func;
|
return (int)g_NewMenus.size() - 1;
|
||||||
|
|
||||||
if (g_MenuFreeStack.empty())
|
|
||||||
{
|
|
||||||
g_NewMenus.push_back(pMenu);
|
|
||||||
pMenu->thisId = (int)g_NewMenus.size() - 1;
|
|
||||||
return (int)g_NewMenus.size() - 1;
|
|
||||||
} else {
|
|
||||||
int pos = g_MenuFreeStack.front();
|
|
||||||
g_MenuFreeStack.pop();
|
|
||||||
g_NewMenus[pos] = pMenu;
|
|
||||||
pMenu->thisId = pos;
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
if (params[2] && (!pMenu->items_per_page && pMenu->GetItemCount() >= 10))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pMenu->m_Items.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
|
|
||||||
item->blanks.push_back(params[2]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Adds an item to the menu (returns current item count - 1)
|
//Adds an item to the menu (returns current item count - 1)
|
||||||
@ -574,17 +266,10 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
|
|||||||
|
|
||||||
GETMENU(params[1]);
|
GETMENU(params[1]);
|
||||||
|
|
||||||
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = get_amxstring(amx, params[2], 0, len);
|
name = get_amxstring(amx, params[2], 0, len);
|
||||||
validate_menu_text(name);
|
|
||||||
cmd = get_amxstring(amx, params[3], 1, len);
|
cmd = get_amxstring(amx, params[3], 1, len);
|
||||||
access = params[4];
|
access = params[4];
|
||||||
|
|
||||||
menuitem *pItem = pMenu->AddItem(name, cmd, access);
|
menuitem *pItem = pMenu->AddItem(name, cmd, access);
|
||||||
|
|
||||||
pItem->handler = params[5];
|
pItem->handler = params[5];
|
||||||
@ -614,13 +299,9 @@ static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
|
|||||||
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
GETMENU(params[2]);
|
GETMENU(params[2]);
|
||||||
|
|
||||||
int player = params[1];
|
int player = params[1];
|
||||||
int page = params[3];
|
int page = params[3];
|
||||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(player);
|
|
||||||
|
|
||||||
// This will set the expire time of the menu to infinite
|
|
||||||
pPlayer->menuexpire = INFINITE;
|
|
||||||
|
|
||||||
return pMenu->Display(player, page);
|
return pMenu->Display(player, page);
|
||||||
}
|
}
|
||||||
@ -682,285 +363,15 @@ static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
name = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
pItem->name.assign(name);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
cmd = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
pItem->cmd.assign(cmd);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pItem->handler = params[3];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
int len = params[0] / sizeof(cell);
|
|
||||||
if (len < 3)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Expected 3 parameters");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (params[2])
|
|
||||||
{
|
|
||||||
case MPROP_PERPAGE:
|
|
||||||
{
|
|
||||||
cell count = *get_amxaddr(amx, params[3]);
|
|
||||||
if (count < 0 || count > 7)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Cannot set %d items per page", count);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pMenu->items_per_page = count;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_BACKNAME:
|
|
||||||
{
|
|
||||||
char *str = get_amxstring(amx, params[3], 0, len);
|
|
||||||
validate_menu_text(str);
|
|
||||||
pMenu->m_OptNames[abs(MENU_BACK)].assign(str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_NEXTNAME:
|
|
||||||
{
|
|
||||||
char *str = get_amxstring(amx, params[3], 0, len);
|
|
||||||
validate_menu_text(str);
|
|
||||||
pMenu->m_OptNames[abs(MENU_MORE)].assign(str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_EXITNAME:
|
|
||||||
{
|
|
||||||
char *str = get_amxstring(amx, params[3], 0, len);
|
|
||||||
validate_menu_text(str);
|
|
||||||
pMenu->m_OptNames[abs(MENU_EXIT)].assign(str);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_TITLE:
|
|
||||||
{
|
|
||||||
char *str = get_amxstring(amx, params[3], 0, len);
|
|
||||||
int old = pMenu->menuId;
|
|
||||||
g_menucmds.removeMenuId(old);
|
|
||||||
pMenu->m_Title.assign(str);
|
|
||||||
pMenu->menuId = g_menucmds.registerMenuId(str, amx);
|
|
||||||
g_menucmds.registerMenuCmd(
|
|
||||||
g_plugins.findPluginFast(amx),
|
|
||||||
pMenu->menuId,
|
|
||||||
1023,
|
|
||||||
pMenu->func);
|
|
||||||
CPlayer *pl;
|
|
||||||
/**
|
|
||||||
* NOTE - this is actually bogus
|
|
||||||
* the client's screen won't actually match the cmd here
|
|
||||||
* I think, this scenario needs to be tested.
|
|
||||||
*/
|
|
||||||
for (int i=1; i<=gpGlobals->maxClients; i++)
|
|
||||||
{
|
|
||||||
pl = GET_PLAYER_POINTER_I(i);
|
|
||||||
if (pl->menu == old)
|
|
||||||
pl->menu = pMenu->menuId;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_EXITALL:
|
|
||||||
{
|
|
||||||
cell ans = *get_amxaddr(amx, params[3]);
|
|
||||||
if (ans == 1)
|
|
||||||
{
|
|
||||||
pMenu->m_AlwaysExit = true;
|
|
||||||
pMenu->m_NeverExit = false;
|
|
||||||
} else if (ans == 0) {
|
|
||||||
pMenu->m_AlwaysExit = false;
|
|
||||||
pMenu->m_NeverExit = false;
|
|
||||||
} else if (ans == -1) {
|
|
||||||
pMenu->m_NeverExit = true;
|
|
||||||
pMenu->m_AlwaysExit = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_ORDER:
|
|
||||||
{
|
|
||||||
cell *addr = get_amxaddr(amx, params[3]);
|
|
||||||
pMenu->m_OptOrders[0] = addr[0];
|
|
||||||
pMenu->m_OptOrders[1] = addr[1];
|
|
||||||
pMenu->m_OptOrders[2] = addr[2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_NOCOLORS:
|
|
||||||
{
|
|
||||||
pMenu->m_AutoColors = *get_amxaddr(amx, params[3]) ? true : false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MPROP_PADMENU:
|
|
||||||
{
|
|
||||||
pMenu->padding = *get_amxaddr(amx, params[3]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu setting: %d", params[1]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GETMENU_R(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
|
||||||
return 0; } \
|
|
||||||
Menu *pMenu = g_NewMenus[p];
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int index = params[1];
|
|
||||||
|
|
||||||
if (index < 1 || index > gpGlobals->maxClients)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not valid", index);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPlayer *player = GET_PLAYER_POINTER_I(index);
|
|
||||||
if (!player->ingame)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int menu = player->newmenu;
|
|
||||||
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Menu *pMenu = g_NewMenus[menu];
|
|
||||||
|
|
||||||
player->newmenu = -1;
|
|
||||||
player->menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(index),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU_R(params[1]);
|
|
||||||
|
|
||||||
if (pMenu->isDestroying)
|
|
||||||
return 0; //prevent infinite recursion
|
|
||||||
|
|
||||||
pMenu->isDestroying = true;
|
|
||||||
g_menucmds.removeMenuId(pMenu->menuId);
|
|
||||||
CPlayer *player;
|
|
||||||
for (int i=1; i<=gpGlobals->maxClients; i++)
|
|
||||||
{
|
|
||||||
player = GET_PLAYER_POINTER_I(i);
|
|
||||||
if (player->newmenu == pMenu->thisId)
|
|
||||||
{
|
|
||||||
player->newmenu = -1;
|
|
||||||
player->menu = 0;
|
|
||||||
executeForwards(pMenu->func,
|
|
||||||
static_cast<cell>(i),
|
|
||||||
static_cast<cell>(pMenu->thisId),
|
|
||||||
static_cast<cell>(MENU_EXIT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_NewMenus[params[1]] = NULL;
|
|
||||||
delete pMenu;
|
|
||||||
g_MenuFreeStack.push(params[1]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL player_menu_info(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", params[1]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPlayer *player = GET_PLAYER_POINTER_I(params[1]);
|
|
||||||
if (!player->ingame)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not ingame", params[1]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell *m = get_amxaddr(amx, params[2]);
|
|
||||||
cell *n = get_amxaddr(amx, params[3]);
|
|
||||||
|
|
||||||
*m = player->menu;
|
|
||||||
*n = player->newmenu;
|
|
||||||
|
|
||||||
if ( (*m != 0 && *m != -1) || (*n != -1))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
||||||
{
|
{
|
||||||
{"menu_create", menu_create},
|
{"menu_create", menu_create},
|
||||||
{"menu_additem", menu_additem},
|
{"menu_additem", menu_additem},
|
||||||
{"menu_addblank", menu_addblank},
|
|
||||||
{"menu_pages", menu_pages},
|
{"menu_pages", menu_pages},
|
||||||
{"menu_items", menu_items},
|
{"menu_items", menu_items},
|
||||||
{"menu_display", menu_display},
|
{"menu_display", menu_display},
|
||||||
{"menu_find_id", menu_find_id},
|
{"menu_find_id", menu_find_id},
|
||||||
{"menu_item_getinfo", menu_item_getinfo},
|
{"menu_item_getinfo", menu_item_getinfo},
|
||||||
{"menu_makecallback", menu_makecallback},
|
{"menu_makecallback", menu_makecallback},
|
||||||
{"menu_item_setcall", menu_item_setcall},
|
|
||||||
{"menu_item_setcmd", menu_item_setcmd},
|
|
||||||
{"menu_item_setname", menu_item_setname},
|
|
||||||
{"menu_destroy", menu_destroy},
|
|
||||||
{"menu_setprop", menu_setprop},
|
|
||||||
{"menu_cancel", menu_cancel},
|
|
||||||
{"player_menu_info", player_menu_info},
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
@ -1,54 +1,14 @@
|
|||||||
/* 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
|
#ifndef _INCLUDE_NEWMENUS_H
|
||||||
#define _INCLUDE_NEWMENUS_H
|
#define _INCLUDE_NEWMENUS_H
|
||||||
|
|
||||||
#define MENU_EXIT -3
|
#define MENU_EXIT -3
|
||||||
#define MENU_BACK -2
|
#define MENU_BACK -2
|
||||||
#define MENU_MORE -1
|
#define MENU_MORE -1
|
||||||
#define ITEM_IGNORE 0
|
#define ITEM_IGNORE 0
|
||||||
#define ITEM_ENABLED 1
|
#define ITEM_ENABLED 1
|
||||||
#define ITEM_DISABLED 2
|
#define ITEM_DISABLED 2
|
||||||
|
|
||||||
|
#define MENUITEMS 7
|
||||||
#define MPROP_PERPAGE 1
|
|
||||||
#define MPROP_BACKNAME 2
|
|
||||||
#define MPROP_NEXTNAME 3
|
|
||||||
#define MPROP_EXITNAME 4
|
|
||||||
#define MPROP_TITLE 5
|
|
||||||
#define MPROP_EXITALL 6
|
|
||||||
#define MPROP_ORDER 7
|
|
||||||
#define MPROP_NOCOLORS 8
|
|
||||||
#define MPROP_PADMENU 9
|
|
||||||
|
|
||||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
||||||
|
|
||||||
@ -56,57 +16,50 @@ struct menuitem
|
|||||||
{
|
{
|
||||||
String name;
|
String name;
|
||||||
String cmd;
|
String cmd;
|
||||||
|
|
||||||
int access;
|
int access;
|
||||||
int handler;
|
int handler;
|
||||||
|
|
||||||
MENUITEM_CALLBACK pfn;
|
MENUITEM_CALLBACK pfn;
|
||||||
size_t id;
|
size_t id;
|
||||||
|
|
||||||
CVector<int> blanks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned int menu_t;
|
typedef unsigned int menu_t;
|
||||||
typedef unsigned int item_t;
|
typedef unsigned int item_t;
|
||||||
typedef unsigned int page_t;
|
typedef unsigned int page_t;
|
||||||
|
|
||||||
class Menu
|
class Menu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Menu(const char *title, int menuId, int thisId);
|
Menu(const char *title, int menuId, int thisId);
|
||||||
~Menu();
|
~Menu();
|
||||||
|
|
||||||
menuitem *GetMenuItem(item_t item);
|
menuitem *GetMenuItem(item_t item);
|
||||||
size_t GetPageCount();
|
size_t GetPageCount();
|
||||||
size_t GetItemCount();
|
size_t GetItemCount();
|
||||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
menuitem *AddItem(const char *name, const char *cmd, int access);
|
||||||
|
|
||||||
const char *GetTextString(int player, page_t page, int &keys);
|
const char *GetTextString(int player, page_t page, int &keys);
|
||||||
bool Display(int player, page_t page);
|
bool Display(int player, page_t page);
|
||||||
|
|
||||||
int PagekeyToItem(page_t page, item_t key);
|
int PagekeyToItem(page_t page, item_t key);
|
||||||
int GetMenuMenuid();
|
int GetMenuMenuid();
|
||||||
public:
|
private:
|
||||||
CVector<menuitem * > m_Items;
|
CVector<menuitem * > m_Items;
|
||||||
String m_Title;
|
String m_Title;
|
||||||
String m_Text;
|
String m_Text;
|
||||||
|
|
||||||
String m_OptNames[4];
|
|
||||||
int m_OptOrders[3];
|
|
||||||
|
|
||||||
bool m_AlwaysExit;
|
|
||||||
bool m_NeverExit;
|
|
||||||
bool m_AutoColors;
|
|
||||||
|
|
||||||
int menuId;
|
int menuId;
|
||||||
int thisId;
|
int thisId;
|
||||||
int func;
|
|
||||||
int padding;
|
|
||||||
bool isDestroying;
|
|
||||||
public:
|
|
||||||
unsigned int items_per_page;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*Menu *CreateMenu(const char *title);
|
||||||
|
Menu *GetMenuById(menu_t menu);
|
||||||
|
menuitem *GetMenuItem(menu_t menu, item_t item);
|
||||||
|
size_t GetMenuPages(menu_t menu);
|
||||||
|
size_t GetMenuItems(menu_t menu);
|
||||||
|
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
|
||||||
|
bool DisplayMenu(menu_t menu, int player, page_t page);
|
||||||
|
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
|
||||||
|
int FindByMenuid(int menuid);
|
||||||
|
int GetMenuMenuid(menu_t menu);
|
||||||
|
const char *GetItemName(menu_t menu, item_t item);
|
||||||
|
const char *GetItemCmd(menu_t menu, item_t item);*/
|
||||||
|
|
||||||
void ClearMenus();
|
void ClearMenus();
|
||||||
|
|
||||||
extern CVector<Menu *> g_NewMenus;
|
extern CVector<Menu *> g_NewMenus;
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "nongpl_matches.h"
|
|
||||||
|
|
||||||
NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[] =
|
|
||||||
{
|
|
||||||
{"Live", "CZ Gun Game", "czgungame.amxx"},
|
|
||||||
{NULL, NULL, NULL},
|
|
||||||
};
|
|
||||||
|
|
||||||
NONGPL_CVAR_T NONGPL_CVAR_LIST[] =
|
|
||||||
{
|
|
||||||
{"gg_mode", 0},
|
|
||||||
{"gg_warmuptimer", 0},
|
|
||||||
{"gg_ff", 0},
|
|
||||||
{"gg_fflevel", 0},
|
|
||||||
{"gg_stats", 0},
|
|
||||||
{"gg_dm", 0},
|
|
||||||
{"gg_turbo", 0},
|
|
||||||
{"amx_ggreset", 1},
|
|
||||||
{"amx_gg", 1},
|
|
||||||
{NULL, 0},
|
|
||||||
};
|
|
@ -1,123 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "optimizer.h"
|
|
||||||
|
|
||||||
int g_opt_level = 0;
|
|
||||||
|
|
||||||
#define OP_SYSREQ_C 123
|
|
||||||
#define OP_NOP 134
|
|
||||||
#define OP_FLOAT_MUL 138
|
|
||||||
#define OP_FLOAT_DIV 139
|
|
||||||
#define OP_FLOAT_ADD 140
|
|
||||||
#define OP_FLOAT_SUB 141
|
|
||||||
#define OP_FLOAT_TO 142
|
|
||||||
#define OP_FLOAT_ROUND 143
|
|
||||||
#define OP_FLOAT_CMP 144
|
|
||||||
|
|
||||||
cell op_trans_table[N_Total_FloatOps] =
|
|
||||||
{
|
|
||||||
OP_FLOAT_MUL,
|
|
||||||
OP_FLOAT_DIV,
|
|
||||||
OP_FLOAT_ADD,
|
|
||||||
OP_FLOAT_SUB,
|
|
||||||
OP_FLOAT_TO,
|
|
||||||
OP_FLOAT_ROUND,
|
|
||||||
OP_FLOAT_CMP
|
|
||||||
};
|
|
||||||
|
|
||||||
void OnBrowseRelocate(AMX *amx, cell *oplist, cell *cip)
|
|
||||||
{
|
|
||||||
char *codeptr = (char *)amx->base + (long)(((AMX_HEADER *)amx->base)->cod);
|
|
||||||
|
|
||||||
//jump to the parameter;
|
|
||||||
codeptr += *cip;
|
|
||||||
|
|
||||||
int native = -1;
|
|
||||||
cell n_offs = *(cell *)codeptr;
|
|
||||||
optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER];
|
|
||||||
for (int i=0; i<N_Total_FloatOps; i++)
|
|
||||||
{
|
|
||||||
if (opt->natives[i] == n_offs)
|
|
||||||
{
|
|
||||||
native = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (native != -1)
|
|
||||||
{
|
|
||||||
//we're patching this:
|
|
||||||
// 0x7B 0x?? SYSREQ.C float???
|
|
||||||
//with:
|
|
||||||
// 0x8A FLOAT.MUL
|
|
||||||
// 0x86 NOP
|
|
||||||
cell new_opcodes[2];
|
|
||||||
new_opcodes[0] = op_trans_table[native];
|
|
||||||
new_opcodes[1] = OP_NOP;
|
|
||||||
codeptr -= sizeof(cell);
|
|
||||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
|
||||||
*(cell *)codeptr = oplist[new_opcodes[0]];
|
|
||||||
*(cell *)(codeptr + sizeof(cell)) = oplist[new_opcodes[1]];
|
|
||||||
#else
|
|
||||||
*(cell *)codeptr = new_opcodes[0];
|
|
||||||
*(cell *)(codeptr + sizeof(cell)) = new_opcodes[1];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
*cip += sizeof(cell);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FIND_NATIVE(name, bind) \
|
|
||||||
if (amx_FindNative(amx, name, &index) != AMX_ERR_NOTFOUND) \
|
|
||||||
opt->natives[bind] = index;
|
|
||||||
|
|
||||||
void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
amx->usertags[UT_BROWSEHOOK] = (void *)OnBrowseRelocate;
|
|
||||||
|
|
||||||
optimizer_s *opt = new optimizer_s;
|
|
||||||
|
|
||||||
for (int i=0; i<N_Total_FloatOps; i++)
|
|
||||||
opt->natives[i] = -1;
|
|
||||||
|
|
||||||
amx->usertags[UT_OPTIMIZER] = (void *)opt;
|
|
||||||
|
|
||||||
if (g_opt_level & 1)
|
|
||||||
{
|
|
||||||
FIND_NATIVE("floatmul", N_Float_Mul);
|
|
||||||
FIND_NATIVE("floatdiv", N_Float_Div);
|
|
||||||
FIND_NATIVE("floatadd", N_Float_Add);
|
|
||||||
FIND_NATIVE("floatsub", N_Float_Sub);
|
|
||||||
}
|
|
||||||
if (g_opt_level & 4)
|
|
||||||
{
|
|
||||||
FIND_NATIVE("float", N_Float_To);
|
|
||||||
FIND_NATIVE("floatround", N_Float_Round);
|
|
||||||
}
|
|
||||||
if (g_opt_level & 2)
|
|
||||||
{
|
|
||||||
#if !defined AMD64
|
|
||||||
if (amxx_CpuSupport())
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
FIND_NATIVE("floatcmp", N_Float_Cmp);
|
|
||||||
#if !defined AMD64
|
|
||||||
} else {
|
|
||||||
g_opt_level &= ~(2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* we don't do these yet because of radix stuff >:\ */
|
|
||||||
//FIND_NATIVE("floatsin", N_Float_Sin);
|
|
||||||
//FIND_NATIVE("floatcos", N_Float_Cos);
|
|
||||||
//FIND_NATIVE("floattan", N_Float_Tan);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupOptimizer(AMX *amx)
|
|
||||||
{
|
|
||||||
amx->usertags[UT_BROWSEHOOK] = (void *)_Setup_Optimizer_Stage2;
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef _INCLUDE_AMXMODX_OPTIMIZER_H
|
|
||||||
#define _INCLUDE_AMXMODX_OPTIMIZER_H
|
|
||||||
|
|
||||||
#include "amx.h"
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
N_Float_Mul=0,
|
|
||||||
N_Float_Div,
|
|
||||||
N_Float_Add,
|
|
||||||
N_Float_Sub,
|
|
||||||
N_Float_To,
|
|
||||||
N_Float_Round,
|
|
||||||
N_Float_Cmp,
|
|
||||||
/* ------------ */
|
|
||||||
N_Total_FloatOps,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct optimizer_s
|
|
||||||
{
|
|
||||||
int natives[N_Total_FloatOps];
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetupOptimizer(AMX *amx);
|
|
||||||
extern "C" int amxx_CpuSupport();
|
|
||||||
|
|
||||||
extern int g_opt_level;
|
|
||||||
|
|
||||||
#endif //_INCLUDE_AMXMODX_OPTIMIZER_H
|
|
@ -45,6 +45,8 @@
|
|||||||
enginefuncs_t g_engfuncs;
|
enginefuncs_t g_engfuncs;
|
||||||
globalvars_t *gpGlobals;
|
globalvars_t *gpGlobals;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DLL_FUNCTIONS *g_pFunctionTable;
|
DLL_FUNCTIONS *g_pFunctionTable;
|
||||||
DLL_FUNCTIONS *g_pFunctionTable_Post;
|
DLL_FUNCTIONS *g_pFunctionTable_Post;
|
||||||
enginefuncs_t *g_pengfuncsTable;
|
enginefuncs_t *g_pengfuncsTable;
|
||||||
@ -52,6 +54,7 @@ enginefuncs_t *g_pengfuncsTable_Post;
|
|||||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
|
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
|
||||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
|
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
|
||||||
|
|
||||||
|
|
||||||
// GetEntityAPI2 functions
|
// GetEntityAPI2 functions
|
||||||
static DLL_FUNCTIONS g_EntityAPI_Table =
|
static DLL_FUNCTIONS g_EntityAPI_Table =
|
||||||
{
|
{
|
||||||
@ -2327,7 +2330,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FN_META_DETACH
|
#ifdef FN_META_DETACH
|
||||||
FN_META_DETACH();
|
return FN_META_DETACH();
|
||||||
#endif // FN_META_DETACH
|
#endif // FN_META_DETACH
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -2430,14 +2433,11 @@ static amxx_module_info_s g_ModuleInfo =
|
|||||||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
0,
|
0,
|
||||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
MODULE_LOGTAG,
|
MODULE_LOGTAG
|
||||||
MODULE_LIBRARY,
|
|
||||||
MODULE_LIBCLASS
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Storage for the requested functions
|
// Storage for the requested functions
|
||||||
PFN_ADD_NATIVES g_fn_AddNatives;
|
PFN_ADD_NATIVES g_fn_AddNatives;
|
||||||
PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
|
||||||
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||||
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||||
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||||
@ -2481,11 +2481,9 @@ PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting;
|
|||||||
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
||||||
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
||||||
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
PFN_ALLOCATOR g_fn_Allocator;
|
PFN_ALLOCATOR g_fn_Allocator;
|
||||||
PFN_REALLOCATOR g_fn_Reallocator;
|
PFN_REALLOCATOR g_fn_Reallocator;
|
||||||
PFN_DEALLOCATOR g_fn_Deallocator;
|
PFN_DEALLOCATOR g_fn_Deallocator;
|
||||||
#endif
|
|
||||||
PFN_AMX_EXEC g_fn_AmxExec;
|
PFN_AMX_EXEC g_fn_AmxExec;
|
||||||
PFN_AMX_EXECV g_fn_AmxExecv;
|
PFN_AMX_EXECV g_fn_AmxExecv;
|
||||||
PFN_AMX_ALLOT g_fn_AmxAllot;
|
PFN_AMX_ALLOT g_fn_AmxAllot;
|
||||||
@ -2505,18 +2503,6 @@ PFN_FORMAT g_fn_Format;
|
|||||||
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||||
PFN_REQ_FNPTR g_fn_RequestFunction;
|
PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||||
PFN_AMX_PUSH g_fn_AmxPush;
|
PFN_AMX_PUSH g_fn_AmxPush;
|
||||||
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
|
||||||
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
|
||||||
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
|
||||||
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
|
||||||
PFN_FINDLIBRARY g_fn_FindLibrary;
|
|
||||||
PFN_ADDLIBRARIES g_fn_AddLibraries;
|
|
||||||
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
|
||||||
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
|
||||||
PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
|
||||||
PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
|
||||||
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
|
||||||
PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
|
||||||
|
|
||||||
// *** Exports ***
|
// *** Exports ***
|
||||||
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
||||||
@ -2567,7 +2553,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
||||||
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
||||||
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
||||||
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
|
|
||||||
|
|
||||||
// Amx scripts
|
// Amx scripts
|
||||||
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
||||||
@ -2593,7 +2578,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
|
|
||||||
// Natives / Forwards
|
// Natives / Forwards
|
||||||
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
|
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
|
||||||
REQFUNC("AddNewNatives", g_fn_AddNewNatives, PFN_ADD_NEW_NATIVES);
|
|
||||||
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
|
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
|
||||||
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
|
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
|
||||||
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
|
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
|
||||||
@ -2628,27 +2612,11 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
|
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
|
||||||
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
|
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
|
||||||
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
||||||
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
|
|
||||||
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
|
|
||||||
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
|
|
||||||
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
|
|
||||||
|
|
||||||
//Added in 1.75
|
|
||||||
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
|
|
||||||
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
|
|
||||||
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
|
|
||||||
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
|
|
||||||
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
|
|
||||||
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
|
|
||||||
|
|
||||||
REQFUNC("MessageBlock", g_fn_MessageBlock, PFN_MESSAGE_BLOCK);
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
// Memory
|
// Memory
|
||||||
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
||||||
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
|
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
|
||||||
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
|
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
|
||||||
#endif
|
|
||||||
|
|
||||||
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
|
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
|
||||||
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
|
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
|
||||||
@ -2677,27 +2645,14 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
|
|||||||
return AMXX_OK;
|
return AMXX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
C_DLLEXPORT void AMXX_PluginsUnloaded()
|
|
||||||
{
|
|
||||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
|
||||||
FN_AMXX_PLUGINSUNLOADED();
|
|
||||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
|
||||||
}
|
|
||||||
|
|
||||||
C_DLLEXPORT void AMXX_PluginsUnloading()
|
|
||||||
{
|
|
||||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
|
||||||
FN_AMXX_PLUGINSUNLOADING();
|
|
||||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advanced MF functions
|
// Advanced MF functions
|
||||||
void MF_Log(const char *fmt, ...)
|
void MF_Log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
// :TODO: Overflow possible here
|
||||||
char msg[3072];
|
char msg[3072];
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
va_start(arglst, fmt);
|
va_start(arglst, fmt);
|
||||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
vsprintf(msg, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
|
|
||||||
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
||||||
@ -2705,10 +2660,11 @@ void MF_Log(const char *fmt, ...)
|
|||||||
|
|
||||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
// :TODO: Overflow possible here
|
||||||
char msg[3072];
|
char msg[3072];
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
va_start(arglst, fmt);
|
va_start(arglst, fmt);
|
||||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
vsprintf(msg, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
|
|
||||||
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
||||||
@ -2776,21 +2732,9 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||||||
MF_GetPlayerEdict(0);
|
MF_GetPlayerEdict(0);
|
||||||
MF_Format("", 4, "str");
|
MF_Format("", 4, "str");
|
||||||
MF_RegisterFunction(NULL, "");
|
MF_RegisterFunction(NULL, "");
|
||||||
MF_RegisterFunctionEx(NULL, "");
|
|
||||||
MF_SetPlayerTeamInfo(0, 0, "");
|
|
||||||
MF_PlayerPropAddr(0, 0);
|
|
||||||
MF_RegAuthFunc(NULL);
|
|
||||||
MF_UnregAuthFunc(NULL);
|
|
||||||
MF_FindLibrary(NULL, LibType_Class);
|
|
||||||
MF_AddLibraries(NULL, LibType_Class, NULL);
|
|
||||||
MF_RemoveLibraries(NULL);
|
|
||||||
MF_OverrideNatives(NULL, NULL);
|
|
||||||
MF_MessageBlock(0, 0, NULL);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
|
|
||||||
/************* MEMORY *************/
|
/************* MEMORY *************/
|
||||||
// undef all defined macros
|
// undef all defined macros
|
||||||
#undef new
|
#undef new
|
||||||
@ -2962,30 +2906,6 @@ void operator delete[](void *reportedAddress)
|
|||||||
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
|
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
|
|
||||||
void * operator new(size_t size) {
|
|
||||||
return(calloc(1, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void * operator new[](size_t size) {
|
|
||||||
return(calloc(1, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete(void * ptr) {
|
|
||||||
if(ptr)
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator delete[](void * ptr) {
|
|
||||||
if(ptr)
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //MEMORY_TEST
|
|
||||||
|
|
||||||
/************* stuff from dlls/util.cpp *************/
|
/************* stuff from dlls/util.cpp *************/
|
||||||
// must come here because cbase.h declares it's own operator new
|
// must come here because cbase.h declares it's own operator new
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#ifndef __linux__
|
#ifndef __linux__
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define DLLEXPORT __attribute__((visibility("default")))
|
#define DLLEXPORT
|
||||||
#define LINUX
|
#define LINUX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -34,8 +34,7 @@
|
|||||||
// module interface version was 1
|
// module interface version was 1
|
||||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
// 2 - added logtag to struct (amxx1.1-rc1)
|
||||||
// 3 - added new tagAMX structure (amxx1.5)
|
// 3 - added new tagAMX structure (amxx1.5)
|
||||||
// 4 - added new 'library' setting for direct loading
|
#define AMXX_INTERFACE_VERSION 3
|
||||||
#define AMXX_INTERFACE_VERSION 4
|
|
||||||
|
|
||||||
// amxx module info
|
// amxx module info
|
||||||
struct amxx_module_info_s
|
struct amxx_module_info_s
|
||||||
@ -45,10 +44,10 @@ struct amxx_module_info_s
|
|||||||
const char *version;
|
const char *version;
|
||||||
int reload; // reload on mapchange when nonzero
|
int reload; // reload on mapchange when nonzero
|
||||||
const char *logtag; // added in version 2
|
const char *logtag; // added in version 2
|
||||||
const char *library; // added in version 4
|
|
||||||
const char *libclass; // added in version 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return values from functions called by amxx
|
// return values from functions called by amxx
|
||||||
#define AMXX_OK 0 /* no error */
|
#define AMXX_OK 0 /* no error */
|
||||||
#define AMXX_IFVERS 1 /* interface version */
|
#define AMXX_IFVERS 1 /* interface version */
|
||||||
@ -156,137 +155,9 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined _MSC_VER
|
#if defined _MSC_VER
|
||||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||||
* about pragma pack in a header file */
|
* about pragma pack in a header file */
|
||||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#if !defined NO_MSVC8_AUTO_COMPAT
|
|
||||||
|
|
||||||
/* Disable deprecation warnings concerning unsafe CRT functions */
|
|
||||||
#if !defined _CRT_SECURE_NO_DEPRECATE
|
|
||||||
#define _CRT_SECURE_NO_DEPRECATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
|
|
||||||
#define access _access
|
|
||||||
#define cabs _cabs
|
|
||||||
#define cgets _cgets
|
|
||||||
#define chdir _chdir
|
|
||||||
#define chmod _chmod
|
|
||||||
#define chsize _chsize
|
|
||||||
#define close _close
|
|
||||||
#define cprintf _cprintf
|
|
||||||
#define cputs _cputts
|
|
||||||
#define creat _creat
|
|
||||||
#define cscanf _cscanf
|
|
||||||
#define cwait _cwait
|
|
||||||
#define dup _dup
|
|
||||||
#define dup2 _dup2
|
|
||||||
#define ecvt _ecvt
|
|
||||||
#define eof _eof
|
|
||||||
#define execl _execl
|
|
||||||
#define execle _execle
|
|
||||||
#define execlp _execlp
|
|
||||||
#define execlpe _execlpe
|
|
||||||
#define execv _execv
|
|
||||||
#define execve _execv
|
|
||||||
#define execvp _execvp
|
|
||||||
#define execvpe _execvpe
|
|
||||||
#define fcloseall _fcloseall
|
|
||||||
#define fcvt _fcvt
|
|
||||||
#define fdopen _fdopen
|
|
||||||
#define fgetchar _fgetchar
|
|
||||||
#define filelength _filelength
|
|
||||||
#define fileno _fileno
|
|
||||||
#define flushall _flushall
|
|
||||||
#define fputchar _fputchar
|
|
||||||
#define gcvt _gcvt
|
|
||||||
#define getch _getch
|
|
||||||
#define getche _getche
|
|
||||||
#define getcwd _getcwd
|
|
||||||
#define getpid _getpid
|
|
||||||
#define getw _getw
|
|
||||||
#define hypot _hypot
|
|
||||||
#define inp _inp
|
|
||||||
#define inpw _inpw
|
|
||||||
#define isascii __isascii
|
|
||||||
#define isatty _isatty
|
|
||||||
#define iscsym __iscsym
|
|
||||||
#define iscsymf __iscsymf
|
|
||||||
#define itoa _itoa
|
|
||||||
#define j0 _j0
|
|
||||||
#define j1 _j1
|
|
||||||
#define jn _jn
|
|
||||||
#define kbhit _kbhit
|
|
||||||
#define lfind _lfind
|
|
||||||
#define locking _locking
|
|
||||||
#define lsearch _lsearch
|
|
||||||
#define lseek _lseek
|
|
||||||
#define ltoa _ltoa
|
|
||||||
#define memccpy _memccpy
|
|
||||||
#define memicmp _memicmp
|
|
||||||
#define mkdir _mkdir
|
|
||||||
#define mktemp _mktemp
|
|
||||||
#define open _open
|
|
||||||
#define outp _outp
|
|
||||||
#define outpw _outpw
|
|
||||||
#define putch _putch
|
|
||||||
#define putenv _putenv
|
|
||||||
#define putw _putw
|
|
||||||
#define read _read
|
|
||||||
#define rmdir _rmdir
|
|
||||||
#define rmtmp _rmtmp
|
|
||||||
#define setmode _setmode
|
|
||||||
#define sopen _sopen
|
|
||||||
#define spawnl _spawnl
|
|
||||||
#define spawnle _spawnle
|
|
||||||
#define spawnlp _spawnlp
|
|
||||||
#define spawnlpe _spawnlpe
|
|
||||||
#define spawnv _spawnv
|
|
||||||
#define spawnve _spawnve
|
|
||||||
#define spawnvp _spawnvp
|
|
||||||
#define spawnvpe _spawnvpe
|
|
||||||
#define strcmpi _strcmpi
|
|
||||||
#define strdup _strdup
|
|
||||||
#define stricmp _stricmp
|
|
||||||
#define strlwr _strlwr
|
|
||||||
#define strnicmp _strnicmp
|
|
||||||
#define strnset _strnset
|
|
||||||
#define strrev _strrev
|
|
||||||
#define strset _strset
|
|
||||||
#define strupr _strupr
|
|
||||||
#define swab _swab
|
|
||||||
#define tell _tell
|
|
||||||
#define tempnam _tempnam
|
|
||||||
#define toascii __toascii
|
|
||||||
#define tzset _tzset
|
|
||||||
#define ultoa _ultoa
|
|
||||||
#define umask _umask
|
|
||||||
#define ungetch _ungetch
|
|
||||||
#define unlink _unlink
|
|
||||||
#define wcsdup _wcsdup
|
|
||||||
#define wcsicmp _wcsicmp
|
|
||||||
#define wcsicoll _wcsicoll
|
|
||||||
#define wcslwr _wcslwr
|
|
||||||
#define wcsnicmp _wcsnicmp
|
|
||||||
#define wcsnset _wcsnset
|
|
||||||
#define wcsrev _wcsrev
|
|
||||||
#define wcsset _wcsset
|
|
||||||
#define wcsupr _wcsupr
|
|
||||||
#define write _write
|
|
||||||
#define y0 _y0
|
|
||||||
#define y1 _y1
|
|
||||||
#define yn _yn
|
|
||||||
|
|
||||||
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
|
|
||||||
* functions above are deprecated. */
|
|
||||||
#pragma warning (disable:4996)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -1077,7 +948,7 @@ void FN_AlertMessage(ALERT_TYPE atype, char *szFmt, ...);
|
|||||||
#endif // FN_AlertMessage
|
#endif // FN_AlertMessage
|
||||||
|
|
||||||
#ifdef FN_EngineFprintf
|
#ifdef FN_EngineFprintf
|
||||||
void FN_EngineFprintf(void *pfile, char *szFmt, ...);
|
void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
|
||||||
#endif // FN_EngineFprintf
|
#endif // FN_EngineFprintf
|
||||||
|
|
||||||
#ifdef FN_PvAllocEntPrivateData
|
#ifdef FN_PvAllocEntPrivateData
|
||||||
@ -1141,11 +1012,11 @@ void FN_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, flo
|
|||||||
#endif // FN_GetBonePosition
|
#endif // FN_GetBonePosition
|
||||||
|
|
||||||
#ifdef FN_FunctionFromName
|
#ifdef FN_FunctionFromName
|
||||||
uint32 FN_FunctionFromName(const char *pName);
|
unsigned long FN_FunctionFromName(const char *pName);
|
||||||
#endif // FN_FunctionFromName
|
#endif // FN_FunctionFromName
|
||||||
|
|
||||||
#ifdef FN_NameForFunction
|
#ifdef FN_NameForFunction
|
||||||
const char *FN_NameForFunction(uint32);
|
const char *FN_NameForFunction(unsigned long function);
|
||||||
#endif // FN_NameForFunction
|
#endif // FN_NameForFunction
|
||||||
|
|
||||||
#ifdef FN_ClientPrintf
|
#ifdef FN_ClientPrintf
|
||||||
@ -1189,7 +1060,7 @@ CRC32_t FN_CRC32_Final(CRC32_t pulCRC);
|
|||||||
#endif // FN_CRC32_Final
|
#endif // FN_CRC32_Final
|
||||||
|
|
||||||
#ifdef FN_RandomLong
|
#ifdef FN_RandomLong
|
||||||
int32 FN_RandomLong(int32 lLow, int32 lHigh);
|
long FN_RandomLong(long lLow, long lHigh);
|
||||||
#endif // FN_RandomLong
|
#endif // FN_RandomLong
|
||||||
|
|
||||||
#ifdef FN_RandomFloat
|
#ifdef FN_RandomFloat
|
||||||
@ -1658,11 +1529,11 @@ void FN_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...);
|
|||||||
#endif // FN_AlertMessage_Post
|
#endif // FN_AlertMessage_Post
|
||||||
|
|
||||||
#ifdef FN_EngineFprintf_Post
|
#ifdef FN_EngineFprintf_Post
|
||||||
void FN_EngineFprintf_Post(void *pfile, char *szFmt, ...);
|
void FN_EngineFprintf_Post(FILE *pfile, char *szFmt, ...);
|
||||||
#endif // FN_EngineFprintf_Post
|
#endif // FN_EngineFprintf_Post
|
||||||
|
|
||||||
#ifdef FN_PvAllocEntPrivateData_Post
|
#ifdef FN_PvAllocEntPrivateData_Post
|
||||||
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, int32 cb);
|
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, long cb);
|
||||||
#endif // FN_PvAllocEntPrivateData_Post
|
#endif // FN_PvAllocEntPrivateData_Post
|
||||||
|
|
||||||
#ifdef FN_PvEntPrivateData_Post
|
#ifdef FN_PvEntPrivateData_Post
|
||||||
@ -1722,11 +1593,11 @@ void FN_GetBonePosition_Post(const edict_t *pEdict, int iBone, float *rgflOrigin
|
|||||||
#endif // FN_GetBonePosition_Post
|
#endif // FN_GetBonePosition_Post
|
||||||
|
|
||||||
#ifdef FN_FunctionFromName_Post
|
#ifdef FN_FunctionFromName_Post
|
||||||
uint32 FN_FunctionFromName_Post(const char *pName);
|
unsigned long FN_FunctionFromName_Post(const char *pName);
|
||||||
#endif // FN_FunctionFromName_Post
|
#endif // FN_FunctionFromName_Post
|
||||||
|
|
||||||
#ifdef FN_NameForFunction_Post
|
#ifdef FN_NameForFunction_Post
|
||||||
const char *FN_NameForFunction_Post(uint32);
|
const char *FN_NameForFunction_Post(unsigned long function);
|
||||||
#endif // FN_NameForFunction_Post
|
#endif // FN_NameForFunction_Post
|
||||||
|
|
||||||
#ifdef FN_ClientPrintf_Post
|
#ifdef FN_ClientPrintf_Post
|
||||||
@ -1770,7 +1641,7 @@ CRC32_t FN_CRC32_Final_Post(CRC32_t pulCRC);
|
|||||||
#endif // FN_CRC32_Final_Post
|
#endif // FN_CRC32_Final_Post
|
||||||
|
|
||||||
#ifdef FN_RandomLong_Post
|
#ifdef FN_RandomLong_Post
|
||||||
int32 FN_RandomLong_Post(int32 lLow, int32 lHigh);
|
long FN_RandomLong_Post(long lLow, long lHigh);
|
||||||
#endif // FN_RandomLong_Post
|
#endif // FN_RandomLong_Post
|
||||||
|
|
||||||
#ifdef FN_RandomFloat_Post
|
#ifdef FN_RandomFloat_Post
|
||||||
@ -2035,14 +1906,6 @@ void FN_AMXX_DETACH(void);
|
|||||||
void FN_AMXX_PLUGINSLOADED(void);
|
void FN_AMXX_PLUGINSLOADED(void);
|
||||||
#endif // FN_AMXX_PLUGINSLOADED
|
#endif // FN_AMXX_PLUGINSLOADED
|
||||||
|
|
||||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
|
||||||
void FN_AMXX_PLUGINSUNLOADING(void);
|
|
||||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
|
||||||
|
|
||||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
|
||||||
void FN_AMXX_PLUGINSUNLOADED(void);
|
|
||||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
|
||||||
|
|
||||||
// *** Types ***
|
// *** Types ***
|
||||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
|
|
||||||
@ -2066,45 +1929,8 @@ enum ForwardParam
|
|||||||
FP_ARRAY, // array; use the return value of prepareArray.
|
FP_ARRAY, // array; use the return value of prepareArray.
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PlayerProp
|
|
||||||
{
|
|
||||||
Player_Name, //String
|
|
||||||
Player_Ip, //String
|
|
||||||
Player_Team, //String
|
|
||||||
Player_Ingame, //bool
|
|
||||||
Player_Authorized, //bool
|
|
||||||
Player_Vgui, //bool
|
|
||||||
Player_Time, //float
|
|
||||||
Player_Playtime, //float
|
|
||||||
Player_MenuExpire, //float
|
|
||||||
Player_Weapons, //struct{int,int}[32]
|
|
||||||
Player_CurrentWeapon, //int
|
|
||||||
Player_TeamID, //int
|
|
||||||
Player_Deaths, //int
|
|
||||||
Player_Aiming, //int
|
|
||||||
Player_Menu, //int
|
|
||||||
Player_Keys, //int
|
|
||||||
Player_Flags, //int[32]
|
|
||||||
Player_Newmenu, //int
|
|
||||||
Player_NewmenuPage, //int
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LibType
|
|
||||||
{
|
|
||||||
LibType_Library,
|
|
||||||
LibType_Class
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MSGBLOCK_SET 0
|
|
||||||
#define MSGBLOCK_GET 1
|
|
||||||
#define BLOCK_NOT 0
|
|
||||||
#define BLOCK_ONCE 1
|
|
||||||
#define BLOCK_SET 2
|
|
||||||
|
|
||||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
|
||||||
|
|
||||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||||
typedef int (*PFN_ADD_NEW_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
|
||||||
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
||||||
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
||||||
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
||||||
@ -2154,16 +1980,13 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
|||||||
#else
|
#else
|
||||||
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
||||||
#endif
|
#endif
|
||||||
typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/);
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const size_t /*size*/);
|
const unsigned int /*type*/, const size_t /*size*/);
|
||||||
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
|
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
|
||||||
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const void* /*addr*/ );
|
const unsigned int /*type*/, const void* /*addr*/ );
|
||||||
#endif
|
|
||||||
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
|
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
|
||||||
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
||||||
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
||||||
@ -2180,20 +2003,8 @@ typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
|
|||||||
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
||||||
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
||||||
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
||||||
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
|
|
||||||
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
|
|
||||||
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
|
|
||||||
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
|
|
||||||
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
|
|
||||||
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
|
|
||||||
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const char * /*myname*/);
|
|
||||||
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
|
|
||||||
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
|
|
||||||
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
|
|
||||||
typedef void (*PFN_MESSAGE_BLOCK) (int /* mode */, int /* message */, int * /* opt */);
|
|
||||||
|
|
||||||
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
||||||
extern PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
|
||||||
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||||
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||||
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||||
@ -2237,6 +2048,7 @@ extern PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
|||||||
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
||||||
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
||||||
extern PFN_AMX_EXEC g_fn_AmxExec;
|
extern PFN_AMX_EXEC g_fn_AmxExec;
|
||||||
|
extern PFN_AMX_EXECV g_fn_AmxExecv;
|
||||||
extern PFN_AMX_ALLOT g_fn_AmxAllot;
|
extern PFN_AMX_ALLOT g_fn_AmxAllot;
|
||||||
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
|
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
|
||||||
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
|
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
|
||||||
@ -2255,24 +2067,11 @@ extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
|
|||||||
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||||
extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||||
extern PFN_AMX_PUSH g_fn_AmxPush;
|
extern PFN_AMX_PUSH g_fn_AmxPush;
|
||||||
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
|
||||||
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
|
||||||
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
|
||||||
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
|
||||||
extern PFN_FINDLIBRARY g_fn_FindLibrary;
|
|
||||||
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
|
|
||||||
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
|
||||||
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
|
||||||
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
|
||||||
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
|
||||||
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
|
||||||
extern PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
|
||||||
|
|
||||||
#ifdef MAY_NEVER_BE_DEFINED
|
#ifdef MAY_NEVER_BE_DEFINED
|
||||||
// Function prototypes for intellisense and similar systems
|
// Function prototypes for intellisense and similar systems
|
||||||
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
||||||
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
||||||
int MF_AddNewNatives (const AMX_NATIVE_INFO *list) { }
|
|
||||||
char * MF_BuildPathname (const char * format, ...) { }
|
char * MF_BuildPathname (const char * format, ...) { }
|
||||||
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
||||||
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
||||||
@ -2328,22 +2127,9 @@ void MF_RegisterFunction (void *pfn, const char *description) { }
|
|||||||
void * MF_RequestFunction (const char *description) { }
|
void * MF_RequestFunction (const char *description) { }
|
||||||
int MF_AmxPush (AMX *amx, cell *params) { }
|
int MF_AmxPush (AMX *amx, cell *params) { }
|
||||||
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
||||||
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
|
|
||||||
void * MF_PlayerPropAddr (int id, int prop) { }
|
|
||||||
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
|
|
||||||
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
|
|
||||||
int MF_FindLibrary (const char *name, LibType type) { }
|
|
||||||
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
|
|
||||||
size_t MF_RemoveLibraries (void *parent) { }
|
|
||||||
void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
|
|
||||||
const char * MF_GetLocalInfo (const char *name, const char *def) { }
|
|
||||||
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
|
|
||||||
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
|
|
||||||
void * MF_MessageBlock (int mode, int msg, int *opt) { }
|
|
||||||
#endif // MAY_NEVER_BE_DEFINED
|
#endif // MAY_NEVER_BE_DEFINED
|
||||||
|
|
||||||
#define MF_AddNatives g_fn_AddNatives
|
#define MF_AddNatives g_fn_AddNatives
|
||||||
#define MF_AddNewNatives g_fn_AddNewNatives
|
|
||||||
#define MF_BuildPathname g_fn_BuildPathname
|
#define MF_BuildPathname g_fn_BuildPathname
|
||||||
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
||||||
#define MF_FormatAmxString g_fn_FormatAmxString
|
#define MF_FormatAmxString g_fn_FormatAmxString
|
||||||
@ -2404,22 +2190,9 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|||||||
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
||||||
#define MF_Format g_fn_Format
|
#define MF_Format g_fn_Format
|
||||||
#define MF_RegisterFunction g_fn_RegisterFunction
|
#define MF_RegisterFunction g_fn_RegisterFunction
|
||||||
#define MF_RequestFunction g_fn_RequestFunction
|
#define MF_RequestFunction g_fn_RequestFunction;
|
||||||
#define MF_AmxPush g_fn_AmxPush
|
#define MF_AmxPush g_fn_AmxPush
|
||||||
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
|
|
||||||
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
|
|
||||||
#define MF_RegAuthFunc g_fn_RegAuthFunc
|
|
||||||
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
|
|
||||||
#define MF_FindLibrary g_fn_FindLibrary
|
|
||||||
#define MF_AddLibraries g_fn_AddLibraries
|
|
||||||
#define MF_RemoveLibraries g_fn_RemoveLibraries
|
|
||||||
#define MF_OverrideNatives g_fn_OverrideNatives
|
|
||||||
#define MF_GetLocalInfo g_fn_GetLocalInfo
|
|
||||||
#define MF_AmxReRegister g_fn_AmxReRegister
|
|
||||||
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
|
|
||||||
#define MF_MessageBlock g_fn_MessageBlock
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
/*** Memory ***/
|
/*** Memory ***/
|
||||||
void *operator new(size_t reportedSize);
|
void *operator new(size_t reportedSize);
|
||||||
void *operator new[](size_t reportedSize);
|
void *operator new[](size_t reportedSize);
|
||||||
@ -2463,6 +2236,4 @@ void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, cons
|
|||||||
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
|
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
|
||||||
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
|
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
|
||||||
|
|
||||||
#endif //MEMORY_TEST
|
|
||||||
|
|
||||||
#endif // #ifndef __AMXXMODULE_H__
|
#endif // #ifndef __AMXXMODULE_H__
|
||||||
|
@ -3,24 +3,12 @@
|
|||||||
#ifndef __MODULECONFIG_H__
|
#ifndef __MODULECONFIG_H__
|
||||||
#define __MODULECONFIG_H__
|
#define __MODULECONFIG_H__
|
||||||
|
|
||||||
/** Module info
|
// Module info
|
||||||
* -The logtag is the tag that the module's log messages will be
|
|
||||||
* prepended with.
|
|
||||||
* -The library is the name that the #pragma library
|
|
||||||
* message will have prepended.
|
|
||||||
* -The library class is the class of libraries that
|
|
||||||
* a module belongs to (like DBI). Keep it "" to
|
|
||||||
* ignore.
|
|
||||||
* -For both library and library class, you can use a comma
|
|
||||||
* to add multiple entries.
|
|
||||||
*/
|
|
||||||
#define MODULE_NAME "--ENTER NAME HERE--"
|
#define MODULE_NAME "--ENTER NAME HERE--"
|
||||||
#define MODULE_VERSION "--ENTER VERSION HERE--"
|
#define MODULE_VERSION "--ENTER VERSION HERE--"
|
||||||
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
|
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
|
||||||
#define MODULE_URL "--ENTER URL HERE--"
|
#define MODULE_URL "--ENTER URL HERE--"
|
||||||
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
|
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
|
||||||
#define MODULE_LIBRARY "--ENTER LIBRARY HERE--"
|
|
||||||
#define MODULE_LIBCLASS ""
|
|
||||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||||
#define MODULE_RELOAD_ON_MAPCHANGE
|
#define MODULE_RELOAD_ON_MAPCHANGE
|
||||||
|
|
||||||
@ -33,45 +21,18 @@
|
|||||||
// metamod plugin?
|
// metamod plugin?
|
||||||
// #define USE_METAMOD
|
// #define USE_METAMOD
|
||||||
|
|
||||||
// use memory manager/tester?
|
// - AMXX Init functions
|
||||||
// note that if you use this, you cannot construct/allocate
|
// Also consider using FN_META_*
|
||||||
// anything before the module attached (OnAmxxAttach).
|
// AMXX query
|
||||||
// be careful of default constructors using new/malloc!
|
|
||||||
// #define MEMORY_TEST
|
|
||||||
|
|
||||||
// Unless you use STL or exceptions, keep this commented.
|
|
||||||
// It allows you to compile without libstdc++.so as a dependency
|
|
||||||
// #define NO_ALLOC_OVERRIDES
|
|
||||||
|
|
||||||
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
|
||||||
// #define NO_MSVC8_AUTO_COMPAT
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AMXX Init functions
|
|
||||||
* Also consider using FN_META_*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** AMXX query */
|
|
||||||
//#define FN_AMXX_QUERY OnAmxxQuery
|
//#define FN_AMXX_QUERY OnAmxxQuery
|
||||||
|
// AMXX attach
|
||||||
/** AMXX attach
|
// Do native functions init here (MF_AddNatives)
|
||||||
* Do native functions init here (MF_AddNatives)
|
// #define FN_AMXX_ATTACH OnAmxxAttach
|
||||||
*/
|
// AMXX detach
|
||||||
//#define FN_AMXX_ATTACH OnAmxxAttach
|
|
||||||
|
|
||||||
/** AMXX Detach (unload) */
|
|
||||||
//#define FN_AMXX_DETACH OnAmxxDetach
|
//#define FN_AMXX_DETACH OnAmxxDetach
|
||||||
|
// All plugins loaded
|
||||||
/** All plugins loaded
|
// Do forward functions init here (MF_RegisterForward)
|
||||||
* Do forward functions init here (MF_RegisterForward)
|
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||||
*/
|
|
||||||
//#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
|
||||||
|
|
||||||
/** All plugins are about to be unloaded */
|
|
||||||
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
|
||||||
|
|
||||||
/** All plugins are now unloaded */
|
|
||||||
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
|
||||||
|
|
||||||
/**** METAMOD ****/
|
/**** METAMOD ****/
|
||||||
// If your module doesn't use metamod, you may close the file now :)
|
// If your module doesn't use metamod, you may close the file now :)
|
||||||
@ -498,4 +459,4 @@
|
|||||||
|
|
||||||
#endif // USE_METAMOD
|
#endif // USE_METAMOD
|
||||||
|
|
||||||
#endif // __MODULECONFIG_H__
|
#endif // __MODULECONFIG_H__
|
@ -1,297 +0,0 @@
|
|||||||
/* ======== 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
|
|
||||||
|
|
||||||
// MSVC8 fix for offsetof macro redefition warnings
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#undef offsetof
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
//namespace SourceHook
|
|
||||||
//{
|
|
||||||
//This class is from CSDM for AMX Mod X
|
|
||||||
/*
|
|
||||||
A circular, doubly-linked list with one sentinel node
|
|
||||||
|
|
||||||
Empty:
|
|
||||||
m_Head = sentinel
|
|
||||||
m_Head->next = m_Head;
|
|
||||||
m_Head->prev = m_Head;
|
|
||||||
One element:
|
|
||||||
m_Head = sentinel
|
|
||||||
m_Head->next = node1
|
|
||||||
m_Head->prev = node1
|
|
||||||
node1->next = m_Head
|
|
||||||
node1->prev = m_Head
|
|
||||||
Two elements:
|
|
||||||
m_Head = sentinel
|
|
||||||
m_Head->next = node1
|
|
||||||
m_Head->prev = node2
|
|
||||||
node1->next = node2
|
|
||||||
node1->prev = m_Head
|
|
||||||
node2->next = m_Head
|
|
||||||
node2->prev = node1
|
|
||||||
*/
|
|
||||||
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:
|
|
||||||
// Initializes the sentinel node.
|
|
||||||
// BAIL used malloc instead of new in order to bypass the need for a constructor.
|
|
||||||
ListNode *_Initialize()
|
|
||||||
{
|
|
||||||
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
|
|
||||||
n->next = n;
|
|
||||||
n->prev = n;
|
|
||||||
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();
|
|
||||||
|
|
||||||
// Don't forget to free the sentinel
|
|
||||||
if (m_Head)
|
|
||||||
{
|
|
||||||
free(m_Head);
|
|
||||||
m_Head = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void push_back(const T &obj)
|
|
||||||
{
|
|
||||||
ListNode *node = new ListNode(obj);
|
|
||||||
|
|
||||||
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 = m_Head;
|
|
||||||
m_Head->prev = m_Head;
|
|
||||||
|
|
||||||
// Iterate through the nodes until we find g_Head (the sentinel) again
|
|
||||||
while (node != m_Head)
|
|
||||||
{
|
|
||||||
temp = node->next;
|
|
||||||
delete node;
|
|
||||||
node = temp;
|
|
||||||
}
|
|
||||||
m_Size = 0;
|
|
||||||
}
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
return (m_Size == 0);
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
//pre decrement
|
|
||||||
iterator & operator--()
|
|
||||||
{
|
|
||||||
if (m_This)
|
|
||||||
m_This = m_This->prev;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//post decrement
|
|
||||||
iterator operator--(int)
|
|
||||||
{
|
|
||||||
iterator old(*this);
|
|
||||||
if (m_This)
|
|
||||||
m_This = m_This->prev;
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T & operator * () const
|
|
||||||
{
|
|
||||||
return m_This->obj;
|
|
||||||
}
|
|
||||||
T & operator * ()
|
|
||||||
{
|
|
||||||
return m_This->obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
T * operator -> ()
|
|
||||||
{
|
|
||||||
return &(m_This->obj);
|
|
||||||
}
|
|
||||||
const 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
|
|
||||||
{
|
|
||||||
return iterator(m_Head->next);
|
|
||||||
}
|
|
||||||
iterator end() const
|
|
||||||
{
|
|
||||||
return iterator(m_Head);
|
|
||||||
}
|
|
||||||
iterator erase(iterator &where)
|
|
||||||
{
|
|
||||||
ListNode *pNode = where.m_This;
|
|
||||||
iterator iter(where);
|
|
||||||
iter++;
|
|
||||||
|
|
||||||
|
|
||||||
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
|
|
||||||
pNode->prev->next = pNode->next;
|
|
||||||
pNode->next->prev = pNode->prev;
|
|
||||||
|
|
||||||
delete pNode;
|
|
||||||
m_Size--;
|
|
||||||
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator insert(iterator where, const T &obj)
|
|
||||||
{
|
|
||||||
// Insert obj right before where
|
|
||||||
|
|
||||||
ListNode *node = new ListNode(obj);
|
|
||||||
ListNode *pWhereNode = where.m_This;
|
|
||||||
|
|
||||||
pWhereNode->prev->next = node;
|
|
||||||
node->prev = pWhereNode->prev;
|
|
||||||
pWhereNode->prev = node;
|
|
||||||
node->next = pWhereNode;
|
|
||||||
|
|
||||||
m_Size++;
|
|
||||||
|
|
||||||
return iterator(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 =(const List &src)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
iterator iter;
|
|
||||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
|
||||||
push_back( (*iter) );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//}; //NAMESPACE
|
|
||||||
|
|
||||||
#endif //_INCLUDE_CSDM_LIST_H
|
|
@ -1,219 +0,0 @@
|
|||||||
/* ======== SourceMM ========
|
|
||||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
|
||||||
* No warranties of any kind
|
|
||||||
*
|
|
||||||
* License: zlib/libpng
|
|
||||||
*
|
|
||||||
* Author(s): Pavol "PM OnoTo" Marko
|
|
||||||
* ============================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SH_STACK_H__
|
|
||||||
#define __SH_STACK_H__
|
|
||||||
|
|
||||||
#define SH_STACK_DEFAULT_SIZE 4
|
|
||||||
|
|
||||||
//namespace SourceHook
|
|
||||||
//{/
|
|
||||||
// Vector
|
|
||||||
template <class T> class CStack
|
|
||||||
{
|
|
||||||
T *m_Elements;
|
|
||||||
size_t m_AllocatedSize;
|
|
||||||
size_t m_UsedSize;
|
|
||||||
public:
|
|
||||||
friend class iterator;
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
CStack<T> *m_pParent;
|
|
||||||
size_t m_Index;
|
|
||||||
public:
|
|
||||||
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator() : m_pParent(NULL), m_Index(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
T &operator *()
|
|
||||||
{
|
|
||||||
return m_pParent->m_Elements[m_Index];
|
|
||||||
}
|
|
||||||
const T &operator *() const
|
|
||||||
{
|
|
||||||
return m_pParent->m_Elements[m_Index];
|
|
||||||
}
|
|
||||||
|
|
||||||
T * operator->()
|
|
||||||
{
|
|
||||||
return m_pParent->m_Elements + m_Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
const T * operator->() const
|
|
||||||
{
|
|
||||||
return m_pParent->m_Elements + m_Index;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator & operator++() // preincrement
|
|
||||||
{
|
|
||||||
++m_Index;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator++(int) // postincrement
|
|
||||||
{
|
|
||||||
iterator tmp = *this;
|
|
||||||
++m_Index;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator & operator--() // predecrement
|
|
||||||
{
|
|
||||||
--m_Index;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator operator--(int) // postdecrememnt
|
|
||||||
{
|
|
||||||
iterator tmp = *this;
|
|
||||||
--m_Index;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const iterator & right) const
|
|
||||||
{
|
|
||||||
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const iterator & right) const
|
|
||||||
{
|
|
||||||
return !(*this == right);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
|
|
||||||
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
|
|
||||||
m_UsedSize(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
CStack(size_t size) : m_Elements(new T[size]),
|
|
||||||
m_AllocatedSize(size),
|
|
||||||
m_UsedSize(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CStack(const CStack &other) : m_Elements(NULL),
|
|
||||||
m_AllocatedSize(0),
|
|
||||||
m_UsedSize(0)
|
|
||||||
{
|
|
||||||
reserve(other.m_AllocatedSize);
|
|
||||||
m_UsedSize = other.m_UsedSize;
|
|
||||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
|
||||||
m_Elements[i] = other.m_Elements[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
~CStack()
|
|
||||||
{
|
|
||||||
if (m_Elements)
|
|
||||||
delete [] m_Elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator=(const CStack &other)
|
|
||||||
{
|
|
||||||
if (m_AllocatedSize < other.m_AllocatedSize)
|
|
||||||
{
|
|
||||||
if (m_Elements)
|
|
||||||
delete [] m_Elements;
|
|
||||||
m_Elements = new T[other.m_AllocatedSize];
|
|
||||||
m_AllocatedSize = other.m_AllocatedSize;
|
|
||||||
}
|
|
||||||
m_UsedSize = other.m_UsedSize;
|
|
||||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
|
||||||
m_Elements[i] = other.m_Elements[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool push(const T &val)
|
|
||||||
{
|
|
||||||
if (m_UsedSize + 1 == m_AllocatedSize)
|
|
||||||
{
|
|
||||||
// zOHNOES! REALLOCATE!
|
|
||||||
m_AllocatedSize *= 2;
|
|
||||||
T *newElements = new T[m_AllocatedSize];
|
|
||||||
if (!newElements)
|
|
||||||
{
|
|
||||||
m_AllocatedSize /= 2;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (m_Elements)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
|
||||||
newElements[i] = m_Elements[i];
|
|
||||||
delete [] m_Elements;
|
|
||||||
}
|
|
||||||
m_Elements = newElements;
|
|
||||||
}
|
|
||||||
m_Elements[m_UsedSize++] = val;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void pop()
|
|
||||||
{
|
|
||||||
--m_UsedSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
T &front()
|
|
||||||
{
|
|
||||||
return m_Elements[m_UsedSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
const T &front() const
|
|
||||||
{
|
|
||||||
return m_Elements[m_UsedSize - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return iterator(this, 0);
|
|
||||||
}
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
return iterator(this, m_UsedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return m_UsedSize;
|
|
||||||
}
|
|
||||||
size_t capacity()
|
|
||||||
{
|
|
||||||
return m_AllocatedSize;
|
|
||||||
}
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
return m_UsedSize == 0 ? true : false;
|
|
||||||
}
|
|
||||||
bool reserve(size_t size)
|
|
||||||
{
|
|
||||||
if (size > m_AllocatedSize)
|
|
||||||
{
|
|
||||||
T *newElements = new T[size];
|
|
||||||
if (!newElements)
|
|
||||||
return false;
|
|
||||||
if (m_Elements)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
|
||||||
newElements[i] = m_Elements[i];
|
|
||||||
delete [] m_Elements;
|
|
||||||
}
|
|
||||||
m_Elements = newElements;
|
|
||||||
m_AllocatedSize = size;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//}; //namespace SourceHook
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,526 +0,0 @@
|
|||||||
/* ======== SourceMM ========
|
|
||||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
|
||||||
* No warranties of any kind
|
|
||||||
*
|
|
||||||
* License: zlib/libpng
|
|
||||||
*
|
|
||||||
* Author(s): David "BAILOPAN" Anderson
|
|
||||||
* ============================
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_SH_TINYHASH_H_
|
|
||||||
#define _INCLUDE_SH_TINYHASH_H_
|
|
||||||
|
|
||||||
#include "sh_list.h"
|
|
||||||
|
|
||||||
#define _T_INIT_HASH_SIZE 512
|
|
||||||
|
|
||||||
//namespace SourceHook
|
|
||||||
//{
|
|
||||||
template <class K>
|
|
||||||
int HashFunction(const K & k);
|
|
||||||
|
|
||||||
template <class K>
|
|
||||||
int Compare(const K & k1, const K & k2);
|
|
||||||
|
|
||||||
template <class U, class K>
|
|
||||||
int CompareAlt(const U &k1, const K &k2);
|
|
||||||
|
|
||||||
template <class U>
|
|
||||||
int HashAlt(const U &u);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a tiny, growable hash class.
|
|
||||||
* Meant for quick and dirty dictionaries only!
|
|
||||||
*/
|
|
||||||
template <class K, class V>
|
|
||||||
class THash
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct THashNode
|
|
||||||
{
|
|
||||||
THashNode(const K & k, const V & v) :
|
|
||||||
key(k), val(v)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
THashNode & operator =(const THashNode &other)
|
|
||||||
{
|
|
||||||
key = other.key;
|
|
||||||
val = other.val;
|
|
||||||
}
|
|
||||||
K key;
|
|
||||||
V val;
|
|
||||||
};
|
|
||||||
typedef List<THashNode *> * NodePtr;
|
|
||||||
public:
|
|
||||||
class const_iterator;
|
|
||||||
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_items(0)
|
|
||||||
{
|
|
||||||
_Refactor();
|
|
||||||
}
|
|
||||||
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
|
|
||||||
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed), m_items(0)
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
|
||||||
_FindOrInsert(iter->key)->val = iter->val;
|
|
||||||
}
|
|
||||||
void operator=(const THash &other)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
|
|
||||||
_FindOrInsert(iter->key)->val = iter->val;
|
|
||||||
}
|
|
||||||
|
|
||||||
~THash()
|
|
||||||
{
|
|
||||||
_Clear();
|
|
||||||
}
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
_Clear();
|
|
||||||
_Refactor();
|
|
||||||
}
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return m_items;
|
|
||||||
}
|
|
||||||
size_t GetBuckets()
|
|
||||||
{
|
|
||||||
return m_numBuckets;
|
|
||||||
}
|
|
||||||
float PercentUsed()
|
|
||||||
{
|
|
||||||
return m_percentUsed;
|
|
||||||
}
|
|
||||||
V & operator [](const K & key)
|
|
||||||
{
|
|
||||||
THashNode *pNode = _FindOrInsert(key);
|
|
||||||
return pNode->val;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Clear()
|
|
||||||
{
|
|
||||||
typename List<THashNode *>::iterator iter, end;
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (m_Buckets[i])
|
|
||||||
{
|
|
||||||
end = m_Buckets[i]->end();
|
|
||||||
iter = m_Buckets[i]->begin();
|
|
||||||
while (iter != end)
|
|
||||||
{
|
|
||||||
delete (*iter);
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
delete m_Buckets[i];
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_Buckets)
|
|
||||||
delete [] m_Buckets;
|
|
||||||
m_Buckets = NULL;
|
|
||||||
m_numBuckets = 0;
|
|
||||||
m_items = 0;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
template <typename U>
|
|
||||||
V & AltFindOrInsert(const U & ukey)
|
|
||||||
{
|
|
||||||
size_t place = HashAlt(ukey) % m_numBuckets;
|
|
||||||
THashNode *pNode = NULL;
|
|
||||||
if (!m_Buckets[place])
|
|
||||||
{
|
|
||||||
m_Buckets[place] = new List<THashNode *>;
|
|
||||||
pNode = new THashNode(ukey, V());
|
|
||||||
m_Buckets[place]->push_back(pNode);
|
|
||||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
|
||||||
m_items++;
|
|
||||||
} else {
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
|
||||||
{
|
|
||||||
if (CompareAlt(ukey, (*iter)->key) == 0)
|
|
||||||
return (*iter)->val;
|
|
||||||
}
|
|
||||||
pNode = new THashNode(ukey, V());
|
|
||||||
m_Buckets[place]->push_back(pNode);
|
|
||||||
m_items++;
|
|
||||||
}
|
|
||||||
if (PercentUsed() > 0.75f)
|
|
||||||
_Refactor();
|
|
||||||
return pNode->val;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
THashNode *_FindOrInsert(const K & key)
|
|
||||||
{
|
|
||||||
size_t place = HashFunction(key) % m_numBuckets;
|
|
||||||
THashNode *pNode = NULL;
|
|
||||||
if (!m_Buckets[place])
|
|
||||||
{
|
|
||||||
m_Buckets[place] = new List<THashNode *>;
|
|
||||||
pNode = new THashNode(key, V());
|
|
||||||
m_Buckets[place]->push_back(pNode);
|
|
||||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
|
||||||
m_items++;
|
|
||||||
} else {
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
|
|
||||||
{
|
|
||||||
if (Compare((*iter)->key, key) == 0)
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
//node does not exist
|
|
||||||
pNode = new THashNode(key, V());
|
|
||||||
m_Buckets[place]->push_back(pNode);
|
|
||||||
m_items++;
|
|
||||||
}
|
|
||||||
if (PercentUsed() > 0.75f)
|
|
||||||
_Refactor();
|
|
||||||
return pNode;
|
|
||||||
}
|
|
||||||
void _Refactor()
|
|
||||||
{
|
|
||||||
m_percentUsed = 0.0f;
|
|
||||||
if (!m_numBuckets)
|
|
||||||
{
|
|
||||||
m_numBuckets = _T_INIT_HASH_SIZE;
|
|
||||||
m_Buckets = new NodePtr[m_numBuckets];
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
} else {
|
|
||||||
size_t oldSize = m_numBuckets;
|
|
||||||
m_numBuckets *= 2;
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
size_t place;
|
|
||||||
THashNode *pHashNode;
|
|
||||||
NodePtr *temp = new NodePtr[m_numBuckets];
|
|
||||||
for (size_t i=0; i<m_numBuckets; i++)
|
|
||||||
temp[i] = NULL;
|
|
||||||
//look in old hash table
|
|
||||||
for (size_t i=0; i<oldSize; i++)
|
|
||||||
{
|
|
||||||
//does a bucket have anything?
|
|
||||||
if (m_Buckets[i])
|
|
||||||
{
|
|
||||||
//go through the list of items
|
|
||||||
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
|
|
||||||
{
|
|
||||||
pHashNode = (*iter);
|
|
||||||
//rehash it with the new bucket filter
|
|
||||||
place = HashFunction(pHashNode->key) % m_numBuckets;
|
|
||||||
//add it to the new hash table
|
|
||||||
if (!temp[place])
|
|
||||||
{
|
|
||||||
temp[place] = new List<THashNode *>;
|
|
||||||
m_percentUsed += (1.0f / (float)m_numBuckets);
|
|
||||||
}
|
|
||||||
temp[place]->push_back(pHashNode);
|
|
||||||
}
|
|
||||||
//delete that bucket!
|
|
||||||
delete m_Buckets[i];
|
|
||||||
m_Buckets[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//reassign bucket table
|
|
||||||
delete [] m_Buckets;
|
|
||||||
m_Buckets = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
friend class iterator;
|
|
||||||
friend class const_iterator;
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
friend class THash;
|
|
||||||
public:
|
|
||||||
iterator() : curbucket(-1), hash(NULL), end(true)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
iterator(THash *h) : curbucket(-1), hash(h), end(false)
|
|
||||||
{
|
|
||||||
if (!h->m_Buckets)
|
|
||||||
end = true;
|
|
||||||
else
|
|
||||||
_Inc();
|
|
||||||
};
|
|
||||||
//pre increment
|
|
||||||
iterator & operator++()
|
|
||||||
{
|
|
||||||
_Inc();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//post increment
|
|
||||||
iterator operator++(int)
|
|
||||||
{
|
|
||||||
iterator old(*this);
|
|
||||||
_Inc();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
const THashNode & operator * () const
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
THashNode & operator * ()
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
const THashNode * operator ->() const
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
THashNode * operator ->()
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
bool operator ==(const iterator &where) const
|
|
||||||
{
|
|
||||||
if (where.hash == this->hash
|
|
||||||
&& where.end == this->end
|
|
||||||
&&
|
|
||||||
(this->end ||
|
|
||||||
((where.curbucket == this->curbucket)
|
|
||||||
&& (where.iter == iter))
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator !=(const iterator &where) const
|
|
||||||
{
|
|
||||||
return !( (*this) == where );
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Remove this element and move to the next one
|
|
||||||
iterator tmp = *this;
|
|
||||||
++tmp;
|
|
||||||
delete (*iter);
|
|
||||||
hash->m_Buckets[curbucket]->erase(iter);
|
|
||||||
*this = tmp;
|
|
||||||
|
|
||||||
// :TODO: Maybe refactor to a lower size if required
|
|
||||||
|
|
||||||
m_items--;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Inc()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
if (curbucket < 0)
|
|
||||||
{
|
|
||||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (hash->m_Buckets[i])
|
|
||||||
{
|
|
||||||
iter = hash->m_Buckets[i]->begin();
|
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
|
||||||
continue;
|
|
||||||
curbucket = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (curbucket < 0)
|
|
||||||
end = true;
|
|
||||||
} else {
|
|
||||||
if (iter != hash->m_Buckets[curbucket]->end())
|
|
||||||
iter++;
|
|
||||||
if (iter == hash->m_Buckets[curbucket]->end())
|
|
||||||
{
|
|
||||||
int oldbucket = curbucket;
|
|
||||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (hash->m_Buckets[i])
|
|
||||||
{
|
|
||||||
iter = hash->m_Buckets[i]->begin();
|
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
|
||||||
continue;
|
|
||||||
curbucket = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (curbucket == oldbucket)
|
|
||||||
end = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
int curbucket;
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
THash *hash;
|
|
||||||
bool end;
|
|
||||||
};
|
|
||||||
class const_iterator
|
|
||||||
{
|
|
||||||
friend class THash;
|
|
||||||
public:
|
|
||||||
const_iterator() : curbucket(-1), hash(NULL), end(true)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
|
|
||||||
{
|
|
||||||
if (!h->m_Buckets)
|
|
||||||
end = true;
|
|
||||||
else
|
|
||||||
_Inc();
|
|
||||||
};
|
|
||||||
//pre increment
|
|
||||||
const_iterator & operator++()
|
|
||||||
{
|
|
||||||
_Inc();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
//post increment
|
|
||||||
const_iterator operator++(int)
|
|
||||||
{
|
|
||||||
iterator old(*this);
|
|
||||||
_Inc();
|
|
||||||
return old;
|
|
||||||
}
|
|
||||||
const THashNode & operator * () const
|
|
||||||
{
|
|
||||||
return *(*iter);
|
|
||||||
}
|
|
||||||
const THashNode * operator ->() const
|
|
||||||
{
|
|
||||||
return (*iter);
|
|
||||||
}
|
|
||||||
bool operator ==(const const_iterator &where) const
|
|
||||||
{
|
|
||||||
if (where.hash == this->hash
|
|
||||||
&& where.end == this->end
|
|
||||||
&&
|
|
||||||
(this->end ||
|
|
||||||
((where.curbucket == this->curbucket)
|
|
||||||
&& (where.iter == iter))
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool operator !=(const const_iterator &where) const
|
|
||||||
{
|
|
||||||
return !( (*this) == where );
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
void _Inc()
|
|
||||||
{
|
|
||||||
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
|
|
||||||
return;
|
|
||||||
if (curbucket < 0)
|
|
||||||
{
|
|
||||||
for (int i=0; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (hash->m_Buckets[i])
|
|
||||||
{
|
|
||||||
iter = hash->m_Buckets[i]->begin();
|
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
|
||||||
continue;
|
|
||||||
curbucket = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (curbucket < 0)
|
|
||||||
end = true;
|
|
||||||
} else {
|
|
||||||
if (iter != hash->m_Buckets[curbucket]->end())
|
|
||||||
iter++;
|
|
||||||
if (iter == hash->m_Buckets[curbucket]->end())
|
|
||||||
{
|
|
||||||
int oldbucket = curbucket;
|
|
||||||
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
|
|
||||||
{
|
|
||||||
if (hash->m_Buckets[i])
|
|
||||||
{
|
|
||||||
iter = hash->m_Buckets[i]->begin();
|
|
||||||
if (iter == hash->m_Buckets[i]->end())
|
|
||||||
continue;
|
|
||||||
curbucket = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (curbucket == oldbucket)
|
|
||||||
end = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
int curbucket;
|
|
||||||
typename List<THashNode *>::iterator iter;
|
|
||||||
const THash *hash;
|
|
||||||
bool end;
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return iterator(this);
|
|
||||||
}
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
iterator iter;
|
|
||||||
iter.hash = this;
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const
|
|
||||||
{
|
|
||||||
return const_iterator(this);
|
|
||||||
}
|
|
||||||
const_iterator end() const
|
|
||||||
{
|
|
||||||
const_iterator iter;
|
|
||||||
iter.hash = this;
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
iterator find(const U & u) const
|
|
||||||
{
|
|
||||||
iterator b = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (iterator iter = b; iter != e; iter++)
|
|
||||||
{
|
|
||||||
if ( (*iter).key == u )
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
iterator find(const U & u)
|
|
||||||
{
|
|
||||||
iterator b = begin();
|
|
||||||
iterator e = end();
|
|
||||||
for (iterator iter = b; iter != e; iter++)
|
|
||||||
{
|
|
||||||
if ( (*iter).key == u )
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator erase(iterator where)
|
|
||||||
{
|
|
||||||
where.erase();
|
|
||||||
return where;
|
|
||||||
}
|
|
||||||
template <typename U>
|
|
||||||
void erase(const U & u)
|
|
||||||
{
|
|
||||||
iterator iter = find(u);
|
|
||||||
if (iter == end())
|
|
||||||
return;
|
|
||||||
iter.erase();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
NodePtr *m_Buckets;
|
|
||||||
size_t m_numBuckets;
|
|
||||||
float m_percentUsed;
|
|
||||||
size_t m_items;
|
|
||||||
};
|
|
||||||
//};
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SH_TINYHASH_H_
|
|
@ -1,359 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/***********************************
|
|
||||||
* About the double array hack *
|
|
||||||
***************************
|
|
||||||
|
|
||||||
Double arrays in Pawn are vectors offset by the current offset. For example:
|
|
||||||
|
|
||||||
new array[2][2]
|
|
||||||
|
|
||||||
In this array, index 0 contains the offset from the current offset which
|
|
||||||
results in the final vector [2] (at [0][2]). Meaning, to dereference [1][2],
|
|
||||||
it is equivalent to:
|
|
||||||
|
|
||||||
address = &array[1] + array[1] + 2 * sizeof(cell)
|
|
||||||
|
|
||||||
The fact that each offset is from the _current_ position rather than the _base_
|
|
||||||
position is very important. It means that if you to try to swap vector positions,
|
|
||||||
the offsets will no longer match, because their current position has changed. A
|
|
||||||
simple and ingenious way around this is to back up the positions in a separate array,
|
|
||||||
then to overwrite each position in the old array with absolute indices. Pseudo C++ code:
|
|
||||||
|
|
||||||
cell *array; //assumed to be set to the 2+D array
|
|
||||||
cell *old_offsets = new cell[2];
|
|
||||||
for (int i=0; i<2; i++)
|
|
||||||
{
|
|
||||||
old_offsets = array[i];
|
|
||||||
array[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
Now, you can swap the array indices with no problem, and do a reverse-lookup to find the original addresses.
|
|
||||||
After sorting/modification is done, you must relocate the new indices. For example, if the two vectors in our
|
|
||||||
demo array were swapped, array[0] would be 1 and array[1] would be 0. This is invalid to the virtual machine.
|
|
||||||
Luckily, this is also simple -- all the information is there.
|
|
||||||
|
|
||||||
for (int i=0; i<2; i++)
|
|
||||||
{
|
|
||||||
//get the # of the vector we want to relocate in
|
|
||||||
cell vector_index = array[i];
|
|
||||||
//get the real address of this vector
|
|
||||||
char *real_address = (char *)array + (vector_index * sizeof(cell)) + old_offsets[vector_index];
|
|
||||||
//calc and store the new distance offset
|
|
||||||
array[i] = real_address - ( (char *)array + (vector_index + sizeof(cell)) )
|
|
||||||
}
|
|
||||||
|
|
||||||
Note that the inner expression can be heavily reduced; it is expanded for readability.
|
|
||||||
**********************************/
|
|
||||||
|
|
||||||
enum SortOrder
|
|
||||||
{
|
|
||||||
Sort_Ascending = 0,
|
|
||||||
Sort_Descending = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
int sort_ints_asc(const void *int1, const void *int2)
|
|
||||||
{
|
|
||||||
return (*(int *)int1) - (*(int *)int2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sort_ints_desc(const void *int1, const void *int2)
|
|
||||||
{
|
|
||||||
return (*(int *)int2) - (*(int *)int1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SortIntegers(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *array = get_amxaddr(amx, params[1]);
|
|
||||||
cell array_size = params[2];
|
|
||||||
cell type = params[3];
|
|
||||||
|
|
||||||
if (type == Sort_Ascending)
|
|
||||||
{
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_ints_asc);
|
|
||||||
} else {
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_ints_desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sort_floats_asc(const void *float1, const void *float2)
|
|
||||||
{
|
|
||||||
REAL r1 = *(REAL *)float1;
|
|
||||||
REAL r2 = *(REAL *)float2;
|
|
||||||
|
|
||||||
if (r1 < r2)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
} else if (r2 < r1) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sort_floats_desc(const void *float1, const void *float2)
|
|
||||||
{
|
|
||||||
REAL r1 = *(REAL *)float1;
|
|
||||||
REAL r2 = *(REAL *)float2;
|
|
||||||
|
|
||||||
if (r1 < r2)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
} else if (r2 < r1) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SortFloats(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *array = get_amxaddr(amx, params[1]);
|
|
||||||
cell array_size = params[2];
|
|
||||||
cell type = params[3];
|
|
||||||
|
|
||||||
if (type == Sort_Ascending)
|
|
||||||
{
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_floats_asc);
|
|
||||||
} else {
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_floats_desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell *g_CurStringArray = NULL;
|
|
||||||
static cell *g_CurRebaseMap = NULL;
|
|
||||||
|
|
||||||
int sort_strings_asc(const void *blk1, const void *blk2)
|
|
||||||
{
|
|
||||||
cell reloc1 = *(cell *)blk1;
|
|
||||||
cell reloc2 = *(cell *)blk2;
|
|
||||||
|
|
||||||
register cell *str1 = (cell *)((char *)(&g_CurStringArray[reloc1]) + g_CurRebaseMap[reloc1]);
|
|
||||||
register cell *str2 = (cell *)((char *)(&g_CurStringArray[reloc2]) + g_CurRebaseMap[reloc2]);
|
|
||||||
|
|
||||||
while (*str1 == *str2++)
|
|
||||||
{
|
|
||||||
if (*str1++ == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*str1 - *(str2 - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
int sort_strings_desc(const void *blk1, const void *blk2)
|
|
||||||
{
|
|
||||||
cell reloc1 = *(cell *)blk1;
|
|
||||||
cell reloc2 = *(cell *)blk2;
|
|
||||||
|
|
||||||
register cell *str1 = (cell *)((char *)(&g_CurStringArray[reloc1]) + g_CurRebaseMap[reloc1]);
|
|
||||||
register cell *str2 = (cell *)((char *)(&g_CurStringArray[reloc2]) + g_CurRebaseMap[reloc2]);
|
|
||||||
|
|
||||||
while (*str1 == *str2++)
|
|
||||||
{
|
|
||||||
if (*str1++ == 0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*(str2 - 1) - *str1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SortStrings(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *array = get_amxaddr(amx, params[1]);
|
|
||||||
cell array_size = params[2];
|
|
||||||
cell type = params[3];
|
|
||||||
|
|
||||||
/** HACKHACK - back up the old indices, replace the indices with something easier */
|
|
||||||
cell amx_addr, *phys_addr;
|
|
||||||
int err;
|
|
||||||
if ((err=amx_Allot(amx, array_size, &amx_addr, &phys_addr)) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
LogError(amx, err, "Ran out of memory");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_CurStringArray = array;
|
|
||||||
g_CurRebaseMap = phys_addr;
|
|
||||||
|
|
||||||
for (int i=0; i<array_size; i++)
|
|
||||||
{
|
|
||||||
phys_addr[i] = array[i];
|
|
||||||
array[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Sort_Ascending)
|
|
||||||
{
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_strings_asc);
|
|
||||||
} else {
|
|
||||||
qsort(array, array_size, sizeof(cell), sort_strings_desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END HACKHACK - restore what we damaged so Pawn doesn't throw up.
|
|
||||||
* We'll browse through each index of the array and patch up the distance.
|
|
||||||
*/
|
|
||||||
for (int i=0; i<array_size; i++)
|
|
||||||
{
|
|
||||||
/* Compute the final address of the old array and subtract the new location.
|
|
||||||
* This is the fixed up distance.
|
|
||||||
*/
|
|
||||||
array[i] = ((char *)&array[array[i]] + phys_addr[array[i]]) - (char *)&array[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
amx_Release(amx, amx_addr);
|
|
||||||
|
|
||||||
g_CurStringArray = NULL;
|
|
||||||
g_CurRebaseMap = NULL;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sort_info
|
|
||||||
{
|
|
||||||
int pfn;
|
|
||||||
cell data_addr;
|
|
||||||
cell data_size;
|
|
||||||
cell array_addr;
|
|
||||||
cell *array_base;
|
|
||||||
cell *array_remap;
|
|
||||||
AMX *amx;
|
|
||||||
};
|
|
||||||
|
|
||||||
static CStack<sort_info *> g_AMXSortStack;
|
|
||||||
|
|
||||||
int sort1d_amx_custom(const void *elem1, const void *elem2)
|
|
||||||
{
|
|
||||||
cell c1 = *(cell *)elem1;
|
|
||||||
cell c2 = *(cell *)elem2;
|
|
||||||
sort_info *pInfo = g_AMXSortStack.front();
|
|
||||||
|
|
||||||
return executeForwards(pInfo->pfn, c1, c2, pInfo->array_addr, pInfo->data_addr, pInfo->data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SortCustom1D(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *array = get_amxaddr(amx, params[1]);
|
|
||||||
cell array_size = params[2];
|
|
||||||
int len;
|
|
||||||
const char *funcname = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
int pfn = registerSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
if (pfn < 0)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sort_info *pInfo = new sort_info;
|
|
||||||
|
|
||||||
pInfo->pfn = pfn;
|
|
||||||
pInfo->data_addr = params[4];
|
|
||||||
pInfo->data_size = params[5];
|
|
||||||
pInfo->array_addr = params[1];
|
|
||||||
pInfo->array_remap = NULL;
|
|
||||||
pInfo->array_base = NULL;
|
|
||||||
|
|
||||||
g_AMXSortStack.push(pInfo);
|
|
||||||
qsort(array, array_size, sizeof(cell), sort1d_amx_custom);
|
|
||||||
g_AMXSortStack.pop();
|
|
||||||
|
|
||||||
delete pInfo;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sort2d_amx_custom(const void *elem1, const void *elem2)
|
|
||||||
{
|
|
||||||
cell c1 = *(cell *)elem1;
|
|
||||||
cell c2 = *(cell *)elem2;
|
|
||||||
sort_info *pInfo = g_AMXSortStack.front();
|
|
||||||
|
|
||||||
cell c1_addr = pInfo->array_addr + (c1 * sizeof(cell)) + pInfo->array_remap[c1];
|
|
||||||
cell c2_addr = pInfo->array_addr + (c2 * sizeof(cell)) + pInfo->array_remap[c2];
|
|
||||||
|
|
||||||
//cell *c1_r = get_amxaddr(pInfo->amx, c1_addr);
|
|
||||||
//cell *c2_r = get_amxaddr(pInfo->amx, c2_addr);
|
|
||||||
|
|
||||||
return executeForwards(pInfo->pfn, c1_addr, c2_addr, pInfo->array_addr, pInfo->data_addr, pInfo->data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL SortCustom2D(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *array = get_amxaddr(amx, params[1]);
|
|
||||||
cell array_size = params[2];
|
|
||||||
int len;
|
|
||||||
const char *funcname = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
/** back up the old indices, replace the indices with something easier */
|
|
||||||
cell amx_addr, *phys_addr;
|
|
||||||
int err;
|
|
||||||
if ((err=amx_Allot(amx, array_size, &amx_addr, &phys_addr)) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
LogError(amx, err, "Ran out of memory");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pfn = registerSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
if (pfn < 0)
|
|
||||||
{
|
|
||||||
amx_Release(amx, amx_addr);
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sort_info *pInfo = new sort_info;
|
|
||||||
|
|
||||||
pInfo->pfn = pfn;
|
|
||||||
pInfo->data_addr = params[4];
|
|
||||||
pInfo->data_size = params[5];
|
|
||||||
pInfo->array_addr = params[1];
|
|
||||||
pInfo->amx = amx;
|
|
||||||
|
|
||||||
/** Same process as in strings, back up the old indices for later fixup */
|
|
||||||
pInfo->array_base = array;
|
|
||||||
pInfo->array_remap = phys_addr;
|
|
||||||
|
|
||||||
for (int i=0; i<array_size; i++)
|
|
||||||
{
|
|
||||||
phys_addr[i] = array[i];
|
|
||||||
array[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_AMXSortStack.push(pInfo);
|
|
||||||
qsort(array, array_size, sizeof(cell), sort2d_amx_custom);
|
|
||||||
g_AMXSortStack.pop();
|
|
||||||
|
|
||||||
/** Fixup process! */
|
|
||||||
for (int i=0; i<array_size; i++)
|
|
||||||
{
|
|
||||||
/* Compute the final address of the old array and subtract the new location.
|
|
||||||
* This is the fixed up distance.
|
|
||||||
*/
|
|
||||||
array[i] = ((char *)&array[array[i]] + phys_addr[array[i]]) - (char *)&array[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
amx_Release(amx, amx_addr);
|
|
||||||
unregisterSPForward(pInfo->pfn);
|
|
||||||
delete pInfo;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_SortNatives[] =
|
|
||||||
{
|
|
||||||
{"SortIntegers", SortIntegers},
|
|
||||||
{"SortFloats", SortFloats},
|
|
||||||
{"SortStrings", SortStrings},
|
|
||||||
{"SortCustom1D", SortCustom1D},
|
|
||||||
{"SortCustom2D", SortCustom2D},
|
|
||||||
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
@ -31,262 +31,251 @@
|
|||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
void amx_command()
|
void amx_command(){
|
||||||
{
|
|
||||||
const char* cmd = CMD_ARGV(1);
|
|
||||||
|
|
||||||
if (!strcmp(cmd, "plugins") || !strcmp(cmd, "list"))
|
const char* cmd = CMD_ARGV(1);
|
||||||
{
|
|
||||||
|
|
||||||
print_srvconsole("Currently loaded plugins:\n");
|
|
||||||
print_srvconsole(" %-23.22s %-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] %-23.22s %-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();
|
|
||||||
|
|
||||||
int num = 0;
|
|
||||||
while (a)
|
|
||||||
{
|
|
||||||
num++;
|
|
||||||
if ((*a).getStatusCode() == ps_bad_load)
|
|
||||||
{
|
|
||||||
//error
|
|
||||||
print_srvconsole("(%3d) Load fails: %s\n", num, (*a).getError());
|
|
||||||
} else if ( (*a).getStatusCode() == ps_error) {
|
|
||||||
//error
|
|
||||||
print_srvconsole("(%3d) Error: %s\n", num, (*a).getError());
|
|
||||||
}
|
|
||||||
++a;
|
|
||||||
}
|
|
||||||
|
|
||||||
print_srvconsole("%d plugins, %d running\n", plugins, running);
|
|
||||||
}
|
|
||||||
else if (!strcmp(cmd, "pause") && CMD_ARGC() > 2)
|
|
||||||
{
|
|
||||||
const char* sPlugin = CMD_ARGV(2);
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
|
||||||
|
|
||||||
if (plugin && plugin->isValid())
|
|
||||||
{
|
|
||||||
if (plugin->isPaused())
|
|
||||||
{
|
|
||||||
if (plugin->isStopped())
|
|
||||||
{
|
|
||||||
print_srvconsole("Plugin \"%s\" is stopped and may not be paused.\n",plugin->getName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_srvconsole("Plugin \"%s\" is already paused.\n",plugin->getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
if (plugin->isStopped())
|
|
||||||
{
|
|
||||||
print_srvconsole("Plugin \"%s\" is stopped and may not be unpaused.\n", plugin->getName());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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.\n", sPlugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!strcmp(cmd, "cvars"))
|
|
||||||
{
|
|
||||||
print_srvconsole("Registered cvars:\n");
|
|
||||||
print_srvconsole(" %-24.23s %-24.23s %-16.15s\n", "name", "value", "plugin");
|
|
||||||
|
|
||||||
int ammount = 0;
|
|
||||||
|
|
||||||
for (CList<CCVar>::iterator a = g_cvars.begin(); a; ++a)
|
|
||||||
{
|
|
||||||
print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName());
|
|
||||||
}
|
|
||||||
|
|
||||||
print_srvconsole("%d cvars\n", ammount);
|
if (!strcmp(cmd,"plugins") || !strcmp(cmd,"list"))
|
||||||
}
|
{
|
||||||
else if (!strcmp(cmd, "cmds"))
|
|
||||||
{
|
print_srvconsole( "Currently loaded plugins:\n");
|
||||||
print_srvconsole("Registered commands:\n");
|
print_srvconsole( " %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
|
||||||
print_srvconsole(" %-24.23s %-16.15s %-8.7s %-16.15s\n", "name", "access", "type", "plugin");
|
"name","version","author","file","status");
|
||||||
|
|
||||||
|
int plugins = 0;
|
||||||
|
int running = 0;
|
||||||
|
|
||||||
|
|
||||||
|
CPluginMngr::iterator a = g_plugins.begin();
|
||||||
|
|
||||||
int ammount = 0;
|
while (a)
|
||||||
char access[32];
|
{
|
||||||
|
++plugins;
|
||||||
|
|
||||||
CmdMngr::iterator a = g_commands.begin(CMD_ConsoleCommand);
|
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 );
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
|
||||||
|
{
|
||||||
|
const char* sPlugin = CMD_ARGV(2);
|
||||||
|
|
||||||
print_srvconsole("%d commands\n",ammount);
|
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
||||||
}
|
|
||||||
else if (!strcmp(cmd, "version"))
|
if ( plugin && plugin->isValid() )
|
||||||
{
|
{
|
||||||
print_srvconsole("%s %s (%s)\n", Plugin_info.name, Plugin_info.version, Plugin_info.url);
|
plugin->pausePlugin();
|
||||||
print_srvconsole("Authors:\n\tDavid \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko\n");
|
print_srvconsole("Paused plugin \"%s\"\n",plugin->getName() );
|
||||||
print_srvconsole("\tFelix \"SniperBeamer\" Geyer, Jonny \"Got His Gun\" Bergstrom\n");
|
}
|
||||||
print_srvconsole("\tLukasz \"SidLuke\" Wlasinski, Christian \"Basic-Master\" Hammacher\n");
|
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
|
||||||
print_srvconsole("\tBorja \"faluco\" Ferrer, Scott \"Damaged Soul\" Ehlert\n");
|
|
||||||
print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__);
|
}
|
||||||
|
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
|
||||||
|
{
|
||||||
|
const char* sPlugin = CMD_ARGV(2);
|
||||||
|
|
||||||
|
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
||||||
|
|
||||||
|
if ( plugin && plugin->isValid() )
|
||||||
|
{
|
||||||
|
plugin->unpausePlugin();
|
||||||
|
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
|
||||||
|
}
|
||||||
|
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!strcmp(cmd,"cvars"))
|
||||||
|
{
|
||||||
|
print_srvconsole( "Registered cvars:\n");
|
||||||
|
print_srvconsole( " %-24.23s %-24.23s %-16.15s\n",
|
||||||
|
"name","value","plugin");
|
||||||
|
|
||||||
|
int ammount = 0;
|
||||||
|
|
||||||
|
for( CList<CCVar>::iterator a = g_cvars.begin(); a ; ++a )
|
||||||
|
{
|
||||||
|
print_srvconsole( " [%3d] %-24.23s %-24.23s %-16.15s\n",++ammount,
|
||||||
|
(*a).getName() ,CVAR_GET_STRING( (*a).getName() ),(*a).getPluginName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
print_srvconsole( "%d cvars\n",ammount);
|
||||||
|
}
|
||||||
|
else if ( !strcmp(cmd,"cmds") )
|
||||||
|
{
|
||||||
|
|
||||||
|
print_srvconsole( "Registered commands:\n");
|
||||||
|
print_srvconsole( " %-24.23s %-16.15s %-8.7s %-16.15s\n",
|
||||||
|
"name","access" ,"type" ,"plugin");
|
||||||
|
|
||||||
|
int ammount = 0;
|
||||||
|
|
||||||
|
char access[32];
|
||||||
|
|
||||||
|
CmdMngr::iterator a = g_commands.begin( CMD_ConsoleCommand );
|
||||||
|
|
||||||
|
while( a )
|
||||||
|
{
|
||||||
|
UTIL_GetFlags( access , (*a).getFlags() );
|
||||||
|
print_srvconsole( " [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n",
|
||||||
|
++ammount,(*a).getCmdLine() , access , (*a).getCmdType() , (*a).getPlugin()->getName());
|
||||||
|
++a;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_srvconsole( "%d commands\n",ammount);
|
||||||
|
}
|
||||||
|
else if (!strcmp(cmd,"version"))
|
||||||
|
{
|
||||||
|
|
||||||
|
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
||||||
|
print_srvconsole( "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
|
#if defined JIT && !defined ASM32
|
||||||
print_srvconsole("Core mode: JIT Only\n");
|
print_srvconsole( "Core mode: JIT Only\n");
|
||||||
#elif !defined JIT && defined ASM32
|
#elif !defined JIT && defined ASM32
|
||||||
print_srvconsole("Core mode: ASM32 Only\n");
|
print_srvconsole( "Core mode: ASM32 Only\n");
|
||||||
#elif defined JIT && defined ASM32
|
#elif defined JIT && defined ASM32
|
||||||
print_srvconsole("Core mode: JIT+ASM32\n");
|
print_srvconsole( "Core mode: JIT+ASM32\n");
|
||||||
#else
|
#else
|
||||||
print_srvconsole("Core mode: Normal\n");
|
print_srvconsole( "Core mode: Normal\n");
|
||||||
#endif
|
#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;
|
|
||||||
}
|
}
|
||||||
|
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");
|
||||||
|
|
||||||
print_srvconsole("%d modules, %d correct\n", modules, running);
|
int running = 0;
|
||||||
}
|
int modules = 0;
|
||||||
else if (!strcmp(cmd, "gpl"))
|
|
||||||
{
|
CList<CModule,const char *>::iterator a = g_modules.begin();
|
||||||
print_srvconsole("AMX Mod X\n");
|
|
||||||
print_srvconsole("\n");
|
while ( a )
|
||||||
print_srvconsole(" by the AMX Mod X Development Team\n");
|
{
|
||||||
print_srvconsole(" originally developed by OLO\n");
|
if ( (*a).getStatusValue() == MODULE_LOADED )
|
||||||
print_srvconsole("\n");
|
++running;
|
||||||
print_srvconsole("\n");
|
|
||||||
print_srvconsole(" This program is free software; you can redistribute it and/or modify it\n");
|
++modules;
|
||||||
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( " [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules,
|
||||||
print_srvconsole(" your option) any later version.\n");
|
(*a).getName(), (*a).getVersion(), (*a).getAuthor() , (*a).getStatus() );
|
||||||
print_srvconsole("\n");
|
|
||||||
print_srvconsole(" This program is distributed in the hope that it will be useful, but\n");
|
++a;
|
||||||
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( "%d modules, %d correct\n",modules,running);
|
||||||
print_srvconsole("\n");
|
} else if (!strcmp(cmd, "gpl"))
|
||||||
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("AMX Mod X\n");
|
||||||
print_srvconsole(" Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n");
|
print_srvconsole("\n");
|
||||||
print_srvconsole("\n");
|
print_srvconsole(" by the AMX Mod X Development Team\n");
|
||||||
print_srvconsole(" In addition, as a special exception, the author gives permission to\n");
|
print_srvconsole(" originally developed by OLO\n");
|
||||||
print_srvconsole(" link the code of this program with the Half-Life Game Engine (\"HL\n");
|
print_srvconsole("\n");
|
||||||
print_srvconsole(" Engine\") and Modified Game Libraries (\"MODs\") developed by Valve,\n");
|
print_srvconsole("\n");
|
||||||
print_srvconsole(" L.L.C (\"Valve\"). You must obey the GNU General Public License in all\n");
|
print_srvconsole(" This program is free software; you can redistribute it and/or modify it\n");
|
||||||
print_srvconsole(" respects for all of the code used other than the HL Engine and MODs\n");
|
print_srvconsole(" under the terms of the GNU General Public License as published by the\n");
|
||||||
print_srvconsole(" from Valve. If you modify this file, you may extend this exception\n");
|
print_srvconsole(" Free Software Foundation; either version 2 of the License, or (at\n");
|
||||||
print_srvconsole(" to your version of the file, but you are not obligated to do so. If\n");
|
print_srvconsole(" your option) any later version.\n");
|
||||||
print_srvconsole(" you do not wish to do so, delete this exception statement from your\n");
|
print_srvconsole("\n");
|
||||||
print_srvconsole(" version.\n");
|
print_srvconsole(" This program is distributed in the hope that it will be useful, but\n");
|
||||||
print_srvconsole("\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");
|
||||||
else if (!strcmp(cmd, "\x74\x75\x72\x74\x6C\x65")) // !! Hidden Command :D !!
|
print_srvconsole(" General Public License for more details.\n");
|
||||||
{
|
print_srvconsole("\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\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(" You should have received a copy of the GNU General Public License\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(" along with this program; if not, write to the Free Software Foundation,\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(" Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\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("\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(" In addition, as a special exception, the author gives permission to\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(" link the code of this program with the Half-Life Game Engine (\"HL\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(" Engine\") and Modified Game Libraries (\"MODs\") developed by Valve,\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(" L.L.C (\"Valve\"). You must obey the GNU General Public License in all\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(" respects for all of the code used other than the HL Engine and MODs\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(" from Valve. If you modify this file, you may extend this exception\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(" to your version of the file, but you are not obligated to do so. If\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(" you do not wish to do so, delete this exception statement from your\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(" version.\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("\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");
|
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\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\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\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\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\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\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\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\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("\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");
|
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");
|
||||||
} else {
|
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("Usage: amxx < command > [ argument ]\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("Commands:\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(" version - display amxx version info\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(" gpl - print the license\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(" plugins - list plugins currently loaded\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(" modules - list modules currently loaded\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(" cvars - list cvars registered by plugins\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(" cmds - list commands registered by plugins\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(" pause < plugin > - pause a running plugin\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(" unpause < plugin > - unpause a previously paused plugin\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()
|
void plugin_srvcmd()
|
||||||
{
|
{
|
||||||
|
cell ret = 0;
|
||||||
const char* cmd = CMD_ARGV(0);
|
const char* cmd = CMD_ARGV(0);
|
||||||
|
|
||||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
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(), static_cast<cell>(g_srvindex),
|
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
|
||||||
static_cast<cell>((*a).getFlags()), static_cast<cell>((*a).getId()));
|
if ( ret ) break;
|
||||||
if (ret) break;
|
|
||||||
}
|
}
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
|
1292
amxmodx/string.cpp
1292
amxmodx/string.cpp
File diff suppressed because it is too large
Load Diff
@ -14,16 +14,6 @@
|
|||||||
#define strnicmp strncasecmp
|
#define strnicmp strncasecmp
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _MSC_VER
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
|
|
||||||
#define stricmp _stricmp
|
|
||||||
|
|
||||||
// Need this because of some stupid bug
|
|
||||||
#pragma warning (disable : 4996)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
#include "mmgr/mmgr.h"
|
#include "mmgr/mmgr.h"
|
||||||
|
180
amxmodx/util.cpp
180
amxmodx/util.cpp
@ -30,10 +30,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
#if defined __linux__ && !defined _vsnprintf
|
#ifdef __linux__
|
||||||
#define _vsnprintf vsnprintf
|
#define _vsnprintf vsnprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *UTIL_VarArgs(const char *fmt, ...)
|
char *UTIL_VarArgs(const char *fmt, ...)
|
||||||
@ -51,47 +52,40 @@ char *UTIL_VarArgs(const char *fmt, ...)
|
|||||||
int UTIL_ReadFlags(const char* c)
|
int UTIL_ReadFlags(const char* c)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
|
||||||
while (*c)
|
|
||||||
flags |= (1<<(*c++ - 'a'));
|
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_GetFlags(char* f, int a)
|
void UTIL_GetFlags(char* f,int a)
|
||||||
{
|
{
|
||||||
for (int i = 'a'; i <= 'z'; ++i)
|
for(int i='a';i<='z';++i){
|
||||||
{
|
if ( a & 1 ) *f++ = i;
|
||||||
if (a & 1) *f++ = i;
|
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*f = 0;
|
*f = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning - don't pass here const string */
|
/* 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 *n = menu;
|
||||||
char c = 0;
|
char c = 0;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
if (!gmsgShowMenu)
|
if (!gmsgShowMenu)
|
||||||
return; // some games don't support ShowMenu (Firearms)
|
return; // some games don't support ShowMenu (Firearms)
|
||||||
|
|
||||||
while (*n)
|
while ( *n ) {
|
||||||
{
|
|
||||||
a = mlen;
|
a = mlen;
|
||||||
if (a > 175) a = 175;
|
if ( a > 175 ) a = 175;
|
||||||
mlen -= a;
|
mlen -= a;
|
||||||
c = *(n+=a);
|
c = *(n+=a);
|
||||||
*n = 0;
|
*n = 0;
|
||||||
|
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
|
||||||
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pEdict);
|
WRITE_SHORT( slots );
|
||||||
WRITE_SHORT(slots);
|
WRITE_CHAR( time );
|
||||||
WRITE_CHAR(time);
|
WRITE_BYTE( c ? TRUE : FALSE);
|
||||||
WRITE_BYTE(c ? TRUE : FALSE);
|
WRITE_STRING( menu );
|
||||||
WRITE_STRING(menu);
|
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
*n = c;
|
*n = c;
|
||||||
menu = n;
|
menu = n;
|
||||||
@ -99,14 +93,14 @@ void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* warning - don't pass here const string */
|
/* 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)
|
if (!gmsgMOTD)
|
||||||
return; // :TODO: Maybe output a warning log?
|
return; // :TODO: Maybe output a warning log?
|
||||||
|
|
||||||
if (gmsgServerName)
|
if (gmsgServerName)
|
||||||
{
|
{
|
||||||
MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client);
|
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||||
WRITE_STRING(name);
|
WRITE_STRING(name);
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
@ -115,17 +109,15 @@ void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name)
|
|||||||
char c = 0;
|
char c = 0;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
while (*n)
|
while ( *n ) {
|
||||||
{
|
|
||||||
a = mlen;
|
a = mlen;
|
||||||
if (a > 175) a = 175;
|
if ( a > 175 ) a = 175;
|
||||||
mlen -= a;
|
mlen -= a;
|
||||||
c = *(n += a);
|
c = *(n+=a);
|
||||||
*n = 0;
|
*n = 0;
|
||||||
|
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
|
||||||
MESSAGE_BEGIN(MSG_ONE, gmsgMOTD, NULL, client);
|
WRITE_BYTE( c ? FALSE : TRUE );
|
||||||
WRITE_BYTE(c ? FALSE : TRUE);
|
WRITE_STRING( motd );
|
||||||
WRITE_STRING(motd);
|
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
*n = c;
|
*n = c;
|
||||||
motd = n;
|
motd = n;
|
||||||
@ -133,52 +125,42 @@ void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name)
|
|||||||
|
|
||||||
if (gmsgServerName)
|
if (gmsgServerName)
|
||||||
{
|
{
|
||||||
MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client);
|
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||||
WRITE_STRING(hostname->string);
|
WRITE_STRING( hostname->string );
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_IntToString(int value, char *output)
|
void UTIL_IntToString(int value, char *output)
|
||||||
{
|
{
|
||||||
static const char *words[] =
|
static const char *words[] = {"zero ","one ","two ","three ","four ",
|
||||||
{"zero ","one ","two ","three ","four ",
|
|
||||||
"five ", "six ","seven ","eight ","nine ","ten ",
|
"five ", "six ","seven ","eight ","nine ","ten ",
|
||||||
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
||||||
"sixteen ","seventeen ","eighteen ","nineteen ",
|
"sixteen ","seventeen ","eighteen ","nineteen ",
|
||||||
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
||||||
"seventy ","eighty ","ninety ",
|
"seventy ","eighty ","ninety ",
|
||||||
"hundred ","thousand "};
|
"hundred ","thousand "};
|
||||||
|
|
||||||
*output = 0;
|
*output = 0;
|
||||||
if (value < 0) value = -value;
|
if (value < 0) value = -value;
|
||||||
int tho = value / 1000;
|
int tho = value / 1000;
|
||||||
int aaa = 0;
|
int aaa = 0;
|
||||||
|
if (tho){
|
||||||
if (tho)
|
aaa += sprintf(&output[aaa], words[ tho ] );
|
||||||
{
|
aaa += sprintf(&output[aaa], words[29] );
|
||||||
aaa += sprintf(&output[aaa], words[tho]);
|
value = value % 1000;
|
||||||
aaa += sprintf(&output[aaa], words[29]);
|
|
||||||
value = value % 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hun = value / 100;
|
int hun = value / 100;
|
||||||
|
if (hun) {
|
||||||
if (hun)
|
aaa += sprintf(&output[aaa], words[ hun ] );
|
||||||
{
|
aaa += sprintf(&output[aaa], words[28] );
|
||||||
aaa += sprintf(&output[aaa], words[hun]);
|
value = value % 100;
|
||||||
aaa += sprintf(&output[aaa], words[28]);
|
|
||||||
value = value % 100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ten = value / 10;
|
int ten = value / 10;
|
||||||
int unit = value % 10;
|
int unit = value % 10;
|
||||||
|
if ( ten )
|
||||||
if (ten)
|
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
|
||||||
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 != 1 && (unit || (!value && !hun && !tho)))
|
|
||||||
sprintf(&output[aaa], words[unit]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* UTIL_SplitHudMessage(const char *src)
|
char* UTIL_SplitHudMessage(const char *src)
|
||||||
@ -186,57 +168,50 @@ char* UTIL_SplitHudMessage(const char *src)
|
|||||||
static char message[512];
|
static char message[512];
|
||||||
short b = 0, d = 0, e = 0, c = -1;
|
short b = 0, d = 0, e = 0, c = -1;
|
||||||
|
|
||||||
while (src[d] && e < 480)
|
while ( src[ d ] && e < 480 ) {
|
||||||
{
|
if ( src[ d ] == ' ' ) {
|
||||||
if (src[d] == ' ')
|
|
||||||
{
|
|
||||||
c = e;
|
c = e;
|
||||||
}
|
}
|
||||||
else if (src[d] == '\n')
|
else if ( src[ d ] == '\n' ) {
|
||||||
{
|
|
||||||
c = -1;
|
c = -1;
|
||||||
b = 0;
|
b = 0;
|
||||||
}
|
}
|
||||||
|
message[ e++ ] = src[ d++ ];
|
||||||
message[e++] = src[d++];
|
if ( ++b == 69 ) {
|
||||||
|
if ( c == -1 ) {
|
||||||
if (++b == 69)
|
message[ e++ ] = '\n';
|
||||||
{
|
|
||||||
if (c == -1)
|
|
||||||
{
|
|
||||||
message[e++] = '\n';
|
|
||||||
b = 0;
|
b = 0;
|
||||||
} else {
|
}
|
||||||
message[c] = '\n';
|
else {
|
||||||
|
message[ c ] = '\n';
|
||||||
b = e - c - 1;
|
b = e - c - 1;
|
||||||
c = -1;
|
c = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
message[ e ] = 0;
|
||||||
message[e] = 0;
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short FixedUnsigned16(float value, float scale)
|
unsigned short FixedUnsigned16( float value, float scale )
|
||||||
{
|
{
|
||||||
int output = (int)(value * scale);
|
int output = (int)(value * scale);
|
||||||
|
|
||||||
if (output < 0)
|
if ( output < 0 )
|
||||||
output = 0;
|
output = 0;
|
||||||
else if (output > 0xFFFF)
|
else if ( output > 0xFFFF )
|
||||||
output = 0xFFFF;
|
output = 0xFFFF;
|
||||||
|
|
||||||
return (unsigned short)output;
|
return (unsigned short)output;
|
||||||
}
|
}
|
||||||
|
|
||||||
short FixedSigned16(float value, float scale)
|
short FixedSigned16( float value, float scale )
|
||||||
{
|
{
|
||||||
int output = (int)(value * scale);
|
int output = (int)(value * scale);
|
||||||
|
|
||||||
if (output > 32767)
|
if ( output > 32767 )
|
||||||
output = 32767;
|
output = 32767;
|
||||||
else if (output < -32768)
|
else if ( output < -32768 )
|
||||||
output = -32768;
|
output = -32768;
|
||||||
|
|
||||||
return (short)output;
|
return (short)output;
|
||||||
@ -244,15 +219,15 @@ short FixedSigned16(float value, float scale)
|
|||||||
|
|
||||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
|
||||||
{
|
{
|
||||||
if (pEntity)
|
if ( pEntity )
|
||||||
MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity);
|
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
|
||||||
else
|
else
|
||||||
MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
|
||||||
|
|
||||||
WRITE_BYTE(29);
|
WRITE_BYTE(29);
|
||||||
WRITE_BYTE(textparms.channel & 0xFF);
|
WRITE_BYTE(textparms.channel & 0xFF);
|
||||||
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13)));
|
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) ));
|
||||||
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13)));
|
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) ));
|
||||||
WRITE_BYTE(textparms.effect);
|
WRITE_BYTE(textparms.effect);
|
||||||
WRITE_BYTE(textparms.r1);
|
WRITE_BYTE(textparms.r1);
|
||||||
WRITE_BYTE(textparms.g1);
|
WRITE_BYTE(textparms.g1);
|
||||||
@ -262,34 +237,30 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pM
|
|||||||
WRITE_BYTE(255);
|
WRITE_BYTE(255);
|
||||||
WRITE_BYTE(250);
|
WRITE_BYTE(250);
|
||||||
WRITE_BYTE(0);
|
WRITE_BYTE(0);
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8)));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8)));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8)));
|
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
|
||||||
|
if (textparms.effect==2)
|
||||||
if (textparms.effect == 2)
|
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8)));
|
|
||||||
|
|
||||||
WRITE_STRING(pMessage);
|
WRITE_STRING(pMessage);
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning - buffer of msg must be longer than 190 chars!
|
/* warning - buffer of msg must be longer than 190 chars!
|
||||||
(here in AMX it is always longer) */
|
(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)
|
if (!gmsgTextMsg)
|
||||||
return; // :TODO: Maybe output a warning log?
|
return; // :TODO: Maybe output a warning log?
|
||||||
|
|
||||||
char c = msg[190];
|
char c = msg[190];
|
||||||
msg[190] = 0; // truncate without checking with strlen()
|
msg[190] = 0; // truncate without checking with strlen()
|
||||||
|
if ( pEntity )
|
||||||
if (pEntity)
|
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
||||||
MESSAGE_BEGIN(MSG_ONE, gmsgTextMsg, NULL, pEntity);
|
|
||||||
else
|
else
|
||||||
MESSAGE_BEGIN(MSG_BROADCAST, gmsgTextMsg);
|
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
|
||||||
|
WRITE_BYTE( msg_dest );
|
||||||
WRITE_BYTE(msg_dest);
|
WRITE_STRING( msg );
|
||||||
WRITE_STRING(msg);
|
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
msg[190] = c;
|
msg[190] = c;
|
||||||
}
|
}
|
||||||
@ -304,7 +275,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)
|
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2)
|
||||||
{
|
{
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return; // no command
|
return; // no command
|
||||||
|
|
||||||
// store command
|
// store command
|
||||||
g_fakecmd.argv[0] = cmd;
|
g_fakecmd.argv[0] = cmd;
|
||||||
@ -333,7 +304,7 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
|||||||
// store argument
|
// store argument
|
||||||
g_fakecmd.argv[1] = arg1;
|
g_fakecmd.argv[1] = arg1;
|
||||||
// build argument line
|
// 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
|
// if snprintf reached 255 chars limit, this will make sure there will be no access violation
|
||||||
g_fakecmd.args[255] = 0;
|
g_fakecmd.args[255] = 0;
|
||||||
}
|
}
|
||||||
@ -347,4 +318,3 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
|||||||
// unset the global "fake" flag
|
// unset the global "fake" flag
|
||||||
g_fakecmd.fake = false;
|
g_fakecmd.fake = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,49 +34,52 @@
|
|||||||
|
|
||||||
Vault g_vault;
|
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.put( get_amxstring(amx,params[1],0,iLen) , get_amxstring(amx,params[2],1,iLen) );
|
||||||
g_vault.saveVault();
|
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);
|
|
||||||
|
|
||||||
if (params[3])
|
const char* key = get_amxstring(amx,params[1],0,iLen);
|
||||||
return set_amxstring(amx, params[2], g_vault.get(key), params[3]);
|
|
||||||
|
|
||||||
return g_vault.get_number(key);
|
if ( params[3] )
|
||||||
|
return set_amxstring( amx , params[2] , g_vault.get( key ) , params[3] );
|
||||||
|
|
||||||
|
return g_vault.get_number( key );
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx, cell *params)
|
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.remove( get_amxstring(amx,params[1],0,iLen) );
|
||||||
g_vault.saveVault();
|
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;
|
int iLen;
|
||||||
return g_vault.exists(get_amxstring(amx, params[1], 0, iLen)) ? 1 : 0;
|
|
||||||
|
return g_vault.exists( get_amxstring(amx,params[1],0,iLen) ) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO vault_Natives[] =
|
AMX_NATIVE_INFO vault_Natives[] = {
|
||||||
{
|
{ "set_vaultdata", set_vaultdata },
|
||||||
{"set_vaultdata", set_vaultdata},
|
{ "get_vaultdata", get_vaultdata },
|
||||||
{"get_vaultdata", get_vaultdata},
|
{ "remove_vaultdata", remove_vaultdata },
|
||||||
{"remove_vaultdata", remove_vaultdata},
|
{ "delete_vaultdata", remove_vaultdata },
|
||||||
{"delete_vaultdata", remove_vaultdata},
|
{ "vaultdata_exists", vaultdata_exists },
|
||||||
{"vaultdata_exists", vaultdata_exists},
|
{ 0, 0 }
|
||||||
{0, 0}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,205 +0,0 @@
|
|||||||
/* 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"
|
|
||||||
|
|
||||||
#define ANGLEVECTORS_FORWARD 1
|
|
||||||
#define ANGLEVECTORS_RIGHT 2
|
|
||||||
#define ANGLEVECTORS_UP 3
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_distance(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *cpVec1 = get_amxaddr(amx, params[1]);
|
|
||||||
cell *cpVec2 = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
Vector vec1 = Vector((float)cpVec1[0], (float)cpVec1[1], (float)cpVec1[2]);
|
|
||||||
Vector vec2 = Vector((float)cpVec2[0], (float)cpVec2[1], (float)cpVec2[2]);
|
|
||||||
|
|
||||||
int iDist = (int)((vec1 - vec2).Length());
|
|
||||||
|
|
||||||
return iDist;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_distance_f(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *cpVec1 = get_amxaddr(amx, params[1]);
|
|
||||||
cell *cpVec2 = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
Vector vec1 = Vector((float)amx_ctof(cpVec1[0]), (float)amx_ctof(cpVec1[1]), (float)amx_ctof(cpVec1[2]));
|
|
||||||
Vector vec2 = Vector((float)amx_ctof(cpVec2[0]), (float)amx_ctof(cpVec2[1]), (float)amx_ctof(cpVec2[2]));
|
|
||||||
|
|
||||||
REAL fDist = (REAL) (vec1 - vec2).Length();
|
|
||||||
|
|
||||||
return amx_ftoc(fDist);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL VelocityByAim(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int iEnt = params[1];
|
|
||||||
int iVelocity = params[2];
|
|
||||||
cell *vRet = get_amxaddr(amx, params[3]);
|
|
||||||
Vector vVector = Vector(0, 0, 0);
|
|
||||||
edict_t *pEnt = NULL;
|
|
||||||
|
|
||||||
if (iEnt < 0 || iEnt > gpGlobals->maxEntities)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", iEnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (iEnt > 0 && iEnt <= gpGlobals->maxClients)
|
|
||||||
{
|
|
||||||
if (!GET_PLAYER_POINTER_I(iEnt)->ingame)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not ingame)", iEnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pEnt = GET_PLAYER_POINTER_I(iEnt)->pEdict;
|
|
||||||
} else {
|
|
||||||
pEnt = INDEXENT(iEnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pEnt)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d (nullent)", iEnt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MAKE_VECTORS(pEnt->v.v_angle);
|
|
||||||
vVector = gpGlobals->v_forward * iVelocity;
|
|
||||||
|
|
||||||
vRet[0] = FloatToCell(vVector.x);
|
|
||||||
vRet[1] = FloatToCell(vVector.y);
|
|
||||||
vRet[2] = FloatToCell(vVector.z);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vector_to_angle(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *cAddr = get_amxaddr(amx, params[1]);
|
|
||||||
|
|
||||||
REAL fX = amx_ctof(cAddr[0]);
|
|
||||||
REAL fY = amx_ctof(cAddr[1]);
|
|
||||||
REAL fZ = amx_ctof(cAddr[2]);
|
|
||||||
|
|
||||||
Vector vVector = Vector(fX, fY, fZ);
|
|
||||||
Vector vAngle = Vector(0, 0, 0);
|
|
||||||
VEC_TO_ANGLES(vVector, vAngle);
|
|
||||||
|
|
||||||
cell *vRet = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
vRet[0] = FloatToCell(vAngle.x);
|
|
||||||
vRet[1] = FloatToCell(vAngle.y);
|
|
||||||
vRet[2] = FloatToCell(vAngle.z);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL angle_vector(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
Vector v_angles, v_forward, v_right, v_up, v_return;
|
|
||||||
|
|
||||||
cell *vCell = get_amxaddr(amx, params[1]);
|
|
||||||
v_angles.x = amx_ctof(vCell[0]);
|
|
||||||
v_angles.y = amx_ctof(vCell[1]);
|
|
||||||
v_angles.z = amx_ctof(vCell[2]);
|
|
||||||
|
|
||||||
g_engfuncs.pfnAngleVectors(v_angles, v_forward, v_right, v_up);
|
|
||||||
|
|
||||||
switch (params[2])
|
|
||||||
{
|
|
||||||
case ANGLEVECTORS_FORWARD:
|
|
||||||
v_return = v_forward;
|
|
||||||
break;
|
|
||||||
case ANGLEVECTORS_RIGHT:
|
|
||||||
v_return = v_right;
|
|
||||||
break;
|
|
||||||
case ANGLEVECTORS_UP:
|
|
||||||
v_return = v_up;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vCell = get_amxaddr(amx, params[3]);
|
|
||||||
vCell[0] = FloatToCell(v_return.x);
|
|
||||||
vCell[1] = FloatToCell(v_return.y);
|
|
||||||
vCell[2] = FloatToCell(v_return.z);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vector_length(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *cAddr = get_amxaddr(amx, params[1]);
|
|
||||||
|
|
||||||
REAL fX = amx_ctof(cAddr[0]);
|
|
||||||
REAL fY = amx_ctof(cAddr[1]);
|
|
||||||
REAL fZ = amx_ctof(cAddr[2]);
|
|
||||||
|
|
||||||
Vector vVector = Vector(fX, fY, fZ);
|
|
||||||
|
|
||||||
REAL fLength = vVector.Length();
|
|
||||||
|
|
||||||
return amx_ftoc(fLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vector_distance(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *cAddr = get_amxaddr(amx, params[1]);
|
|
||||||
cell *cAddr2 = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
REAL fX = amx_ctof(cAddr[0]);
|
|
||||||
REAL fY = amx_ctof(cAddr[1]);
|
|
||||||
REAL fZ = amx_ctof(cAddr[2]);
|
|
||||||
REAL fX2 = amx_ctof(cAddr2[0]);
|
|
||||||
REAL fY2 = amx_ctof(cAddr2[1]);
|
|
||||||
REAL fZ2 = amx_ctof(cAddr2[2]);
|
|
||||||
|
|
||||||
Vector vVector = Vector(fX, fY, fZ);
|
|
||||||
Vector vVector2 = Vector(fX2, fY2, fZ2);
|
|
||||||
|
|
||||||
REAL fLength = (vVector - vVector2).Length();
|
|
||||||
|
|
||||||
return amx_ftoc(fLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO vector_Natives[] = {
|
|
||||||
{"get_distance", get_distance},
|
|
||||||
{"get_distance_f", get_distance_f},
|
|
||||||
{"velocity_by_aim", VelocityByAim},
|
|
||||||
{"vector_to_angle", vector_to_angle},
|
|
||||||
{"angle_vector", angle_vector},
|
|
||||||
{"vector_length", vector_length},
|
|
||||||
{"vector_distance", vector_distance},
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,7,6,3387
|
FILEVERSION 1,5,0,1
|
||||||
PRODUCTVERSION 1,7,6,3387
|
PRODUCTVERSION 1,5,0,1
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -45,12 +45,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "AMX Mod X"
|
VALUE "Comments", "AMX Mod X"
|
||||||
VALUE "FileDescription", "AMX Mod X"
|
VALUE "FileDescription", "AMX Mod X"
|
||||||
VALUE "FileVersion", "1.76d"
|
VALUE "FileVersion", "1.50"
|
||||||
VALUE "InternalName", "amxmodx"
|
VALUE "InternalName", "amxmodx"
|
||||||
VALUE "LegalCopyright", "Copyright (c) 2004-2006, AMX Mod X Dev Team"
|
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
||||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
||||||
VALUE "ProductName", "AMX Mod X"
|
VALUE "ProductName", "AMX Mod X"
|
||||||
VALUE "ProductVersion", "1.76d"
|
VALUE "ProductVersion", "1.50-RC1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user