Compare commits
1 Commits
amxmodx-1.
...
amxmodx-0.
Author | SHA1 | Date | |
---|---|---|---|
b5680a27f5 |
190
amxmodx/CCmd.cpp
190
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,86 +73,95 @@ 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) )
|
||||||
|
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;
|
||||||
@ -161,101 +169,84 @@ void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
|
|||||||
|
|
||||||
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;
|
||||||
@ -273,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;
|
||||||
|
@ -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) != 0)); }
|
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
|
||||||
}
|
}
|
||||||
@ -411,22 +396,41 @@ void EventsMngr::parseValue(const char *sz)
|
|||||||
|
|
||||||
void EventsMngr::executeEvents()
|
void EventsMngr::executeEvents()
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
if (!m_ParseFun)
|
if (!m_ParseFun)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if ((*iter).m_Done)
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||||
{
|
{
|
||||||
(*iter).m_Done = false;
|
if ( (*iter).m_Done )
|
||||||
continue;
|
{
|
||||||
|
(*iter).m_Done = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*iter).m_Stamp = (float)*m_Timer;
|
||||||
|
|
||||||
|
if ((err = amx_Exec((*iter).m_Plugin->getAMX(), NULL, (*iter).m_Func, 1, m_ParseVault ? m_ParseVault[0].iValue : 0)) != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err,
|
||||||
|
(*iter).m_Plugin->getAMX()->curline, (*iter).m_Plugin->getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(*iter).m_Stamp = (float)*m_Timer;
|
#ifdef ENABLEEXEPTIONS
|
||||||
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0));
|
|
||||||
}
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
AMXXLOG_Log( "[AMXX] fatal error at event execution");
|
||||||
|
}
|
||||||
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
|
|
||||||
m_CurrentMsgType = -1;
|
m_CurrentMsgType = -1;
|
||||||
m_ParseFun = NULL;
|
m_ParseFun = NULL;
|
||||||
@ -439,53 +443,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 +499,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 +517,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 )
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
|
||||||
|
*buf++ = c;
|
||||||
|
*buf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (*this)
|
// trim 0x0a and 0x0d characters at the end
|
||||||
{
|
while (buf != origBuf)
|
||||||
int c;
|
{
|
||||||
while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
|
if (*buf == 0x0a || *buf == 0x0d)
|
||||||
*buf++ = c;
|
|
||||||
*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();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,418 +0,0 @@
|
|||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "sh_list.h"
|
|
||||||
#include "CString.h"
|
|
||||||
|
|
||||||
#include "amxmodx.h"
|
|
||||||
|
|
||||||
#include "CFlagManager.h"
|
|
||||||
|
|
||||||
void CFlagManager::SetFile(const char *Filename)
|
|
||||||
{
|
|
||||||
|
|
||||||
m_strConfigFile.assign(g_mod_name.c_str());
|
|
||||||
m_strConfigFile.append("/");
|
|
||||||
m_strConfigFile.append(get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
|
|
||||||
m_strConfigFile.append("/");
|
|
||||||
m_strConfigFile.append(Filename);
|
|
||||||
|
|
||||||
|
|
||||||
CreateIfNotExist();
|
|
||||||
}
|
|
||||||
|
|
||||||
const int CFlagManager::LoadFile(const int force)
|
|
||||||
{
|
|
||||||
CheckIfDisabled();
|
|
||||||
// If we're disabled get the hell out. now.
|
|
||||||
if (m_iDisabled)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// if we're not forcing this, and NeedToLoad says we dont have to
|
|
||||||
// then just stop
|
|
||||||
if (!force && !NeedToLoad())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
this->Clear();
|
|
||||||
|
|
||||||
|
|
||||||
// We need to load the file
|
|
||||||
|
|
||||||
FILE *File;
|
|
||||||
|
|
||||||
File=fopen(m_strConfigFile.c_str(),"r");
|
|
||||||
|
|
||||||
if (!File)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)",m_strConfigFile.c_str());
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Trying to copy this almost exactly as other configs are read...
|
|
||||||
String Line;
|
|
||||||
|
|
||||||
char Command[256];
|
|
||||||
char Flags[256];
|
|
||||||
|
|
||||||
String TempLine;
|
|
||||||
while (!feof(File))
|
|
||||||
{
|
|
||||||
|
|
||||||
Line._fread(File);
|
|
||||||
|
|
||||||
char *nonconst=const_cast<char *>(Line.c_str());
|
|
||||||
|
|
||||||
|
|
||||||
// Strip out comments
|
|
||||||
while (*nonconst)
|
|
||||||
{
|
|
||||||
if (*nonconst==';') // End the line at comments
|
|
||||||
{
|
|
||||||
*nonconst='\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nonconst++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Command[0]='\0';
|
|
||||||
Flags[0]='\0';
|
|
||||||
|
|
||||||
// Extract the command
|
|
||||||
TempLine.assign(Line.c_str());
|
|
||||||
|
|
||||||
nonconst=const_cast<char *>(TempLine.c_str());
|
|
||||||
|
|
||||||
char *start=NULL;
|
|
||||||
char *end=NULL;
|
|
||||||
|
|
||||||
// move up line until the first ", mark this down as the start
|
|
||||||
// then find the second " and mark it down as the end
|
|
||||||
while (*nonconst!='\0')
|
|
||||||
{
|
|
||||||
if (*nonconst=='"')
|
|
||||||
{
|
|
||||||
if (start==NULL)
|
|
||||||
{
|
|
||||||
start=nonconst+1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
end=nonconst;
|
|
||||||
goto done_with_command;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nonconst++;
|
|
||||||
}
|
|
||||||
done_with_command:
|
|
||||||
|
|
||||||
// invalid line?
|
|
||||||
if (start==NULL || end==NULL)
|
|
||||||
{
|
|
||||||
// TODO: maybe warn for an invalid non-commented line?
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*end='\0';
|
|
||||||
|
|
||||||
strncpy(Command,start,sizeof(Command)-1);
|
|
||||||
|
|
||||||
|
|
||||||
// Now do the same thing for the flags
|
|
||||||
nonconst=++end;
|
|
||||||
|
|
||||||
start=NULL;
|
|
||||||
end=NULL;
|
|
||||||
|
|
||||||
// move up line until the first ", mark this down as the start
|
|
||||||
// then find the second " and mark it down as the end
|
|
||||||
while (*nonconst!='\0')
|
|
||||||
{
|
|
||||||
if (*nonconst=='"')
|
|
||||||
{
|
|
||||||
if (start==NULL)
|
|
||||||
{
|
|
||||||
start=nonconst+1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
end=nonconst;
|
|
||||||
goto done_with_flags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nonconst++;
|
|
||||||
}
|
|
||||||
done_with_flags:
|
|
||||||
// invalid line?
|
|
||||||
if (start==NULL || end==NULL)
|
|
||||||
{
|
|
||||||
// TODO: maybe warn for an invalid non-commented line?
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*end='\0';
|
|
||||||
|
|
||||||
strncpy(Flags,start,sizeof(Flags)-1);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//if (!isalnum(*Command))
|
|
||||||
if (*Command == '"' ||
|
|
||||||
*Command == '\0')
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Done sucking the command and flags out of the line
|
|
||||||
// now insert this command into the linked list
|
|
||||||
|
|
||||||
AddFromFile(const_cast<const char*>(&Command[0]),&Flags[0]);
|
|
||||||
|
|
||||||
nonconst=const_cast<char *>(Line.c_str());
|
|
||||||
*nonconst='\0';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
fclose(File);
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This gets called from LoadFile
|
|
||||||
* Do NOT flag the entries as NeedToWrite
|
|
||||||
* No comment is passed from the file because
|
|
||||||
* this should never get written
|
|
||||||
*/
|
|
||||||
void CFlagManager::AddFromFile(const char *Command, const char *Flags)
|
|
||||||
{
|
|
||||||
|
|
||||||
CFlagEntry *Entry=new CFlagEntry;
|
|
||||||
|
|
||||||
Entry->SetName(Command);
|
|
||||||
Entry->SetFlags(Flags);
|
|
||||||
|
|
||||||
// Link it
|
|
||||||
m_FlagList.push_back(Entry);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
|
|
||||||
{
|
|
||||||
if (m_iDisabled) // if disabled in core.ini stop
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int TempFlags=Flags;
|
|
||||||
if (TempFlags==-1)
|
|
||||||
{
|
|
||||||
TempFlags=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CFlagEntry *>::iterator iter;
|
|
||||||
List<CFlagEntry *>::iterator end;
|
|
||||||
|
|
||||||
iter=m_FlagList.begin();
|
|
||||||
end=m_FlagList.end();
|
|
||||||
|
|
||||||
while (iter!=end)
|
|
||||||
{
|
|
||||||
if (strcmp((*iter)->GetName()->c_str(),Command)==0)
|
|
||||||
{
|
|
||||||
CFlagEntry *Entry=(*iter);
|
|
||||||
|
|
||||||
if (Entry->IsHidden()) // "!" flag, exclude this function
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Found, byref the new flags
|
|
||||||
Flags=Entry->Flags();
|
|
||||||
|
|
||||||
// Move it to the back of the list for faster lookup for the rest
|
|
||||||
m_FlagList.erase(iter);
|
|
||||||
|
|
||||||
m_FlagList.push_back(Entry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// was not found, add it
|
|
||||||
|
|
||||||
CFlagEntry *Entry=new CFlagEntry;
|
|
||||||
|
|
||||||
Entry->SetName(Command);
|
|
||||||
Entry->SetFlags(TempFlags);
|
|
||||||
|
|
||||||
if (Plugin)
|
|
||||||
{
|
|
||||||
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(Plugin);
|
|
||||||
|
|
||||||
if (a)
|
|
||||||
{
|
|
||||||
Entry->SetComment(a->getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This entry was added from a register_* native
|
|
||||||
// it needs to be written during map change
|
|
||||||
Entry->SetNeedWritten(1);
|
|
||||||
|
|
||||||
// Link it
|
|
||||||
m_FlagList.push_back(Entry);
|
|
||||||
|
|
||||||
}
|
|
||||||
void CFlagManager::WriteCommands(void)
|
|
||||||
{
|
|
||||||
List<CFlagEntry *>::iterator iter;
|
|
||||||
List<CFlagEntry *>::iterator end;
|
|
||||||
FILE *File;
|
|
||||||
int NeedToRead=0;
|
|
||||||
|
|
||||||
// First off check the modified time of this file
|
|
||||||
// if it matches the stored modified time, then update
|
|
||||||
// after we write so we do not re-read next map
|
|
||||||
struct stat TempStat;
|
|
||||||
|
|
||||||
stat(m_strConfigFile.c_str(),&TempStat);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
|
||||||
{
|
|
||||||
NeedToRead=1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
File=fopen(m_strConfigFile.c_str(),"a");
|
|
||||||
|
|
||||||
if (!File)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iter=m_FlagList.begin();
|
|
||||||
end=m_FlagList.end();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
while (iter!=end)
|
|
||||||
{
|
|
||||||
if ((*iter)->NeedWritten())
|
|
||||||
{
|
|
||||||
if ((*iter)->GetComment()->size())
|
|
||||||
{
|
|
||||||
fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str(),(*iter)->GetComment()->c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str());
|
|
||||||
}
|
|
||||||
(*iter)->SetNeedWritten(0);
|
|
||||||
}
|
|
||||||
++iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
fclose(File);
|
|
||||||
|
|
||||||
|
|
||||||
// If NeedToRead was 0, then update the timestamp
|
|
||||||
// that was saved so we do not re-read this file
|
|
||||||
// next map
|
|
||||||
if (!NeedToRead)
|
|
||||||
{
|
|
||||||
stat(m_strConfigFile.c_str(),&TempStat);
|
|
||||||
|
|
||||||
m_Stat.st_mtime=TempStat.st_mtime;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const
|
|
||||||
{
|
|
||||||
|
|
||||||
// If flagmanager is disabled then ignore this
|
|
||||||
if (m_iDisabled)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// If 5th param exists it was compiled after this change was made
|
|
||||||
// if it does not exist, try our logic at the end of this function
|
|
||||||
// 5th param being > 0 means explicit yes
|
|
||||||
// < 0 means auto detect (default is -1), treat it like there was no 5th param
|
|
||||||
// 0 means explicit no
|
|
||||||
|
|
||||||
if ((params[0] / sizeof(cell)) >= 5)
|
|
||||||
{
|
|
||||||
if (params[5]>0) // This command was explicitly told to be included
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (params[5]==0) // this command was explicitly told to NOT be used
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto detect if we should use this command
|
|
||||||
|
|
||||||
// if command access is -1 (default, not set to ADMIN_ALL or any other access), then no
|
|
||||||
if (params[3]==-1)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// if command is (or starts with) "say", then no
|
|
||||||
if (strncmp(cmdname,"say",3)==0)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// else use it
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void CFlagManager::Clear(void)
|
|
||||||
{
|
|
||||||
List<CFlagEntry *>::iterator iter;
|
|
||||||
List<CFlagEntry *>::iterator end;
|
|
||||||
|
|
||||||
iter=m_FlagList.begin();
|
|
||||||
end=m_FlagList.end();
|
|
||||||
|
|
||||||
while (iter!=end)
|
|
||||||
{
|
|
||||||
delete (*iter);
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_FlagList.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
void CFlagManager::CheckIfDisabled(void)
|
|
||||||
{
|
|
||||||
if (atoi(get_localinfo("disableflagman","0"))==0)
|
|
||||||
{
|
|
||||||
m_iDisabled=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_iDisabled=1;
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,218 +0,0 @@
|
|||||||
#ifndef CFLAGMANAGER_H
|
|
||||||
#define CFLAGMANAGER_H
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "sh_list.h"
|
|
||||||
#include "CString.h"
|
|
||||||
|
|
||||||
#include "amxmodx.h"
|
|
||||||
|
|
||||||
class CFlagEntry
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
String m_strName; // command name ("amx_slap")
|
|
||||||
String m_strFlags; // string flags ("a","b")
|
|
||||||
String m_strComment; // comment to write ("; admincmd.amxx")
|
|
||||||
int m_iFlags; // bitmask flags
|
|
||||||
int m_iNeedWritten; // write this command on map change?
|
|
||||||
int m_iHidden; // set to 1 when the command is set to "!" access in
|
|
||||||
// the .ini file: this means do not process this command
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
CFlagEntry()
|
|
||||||
{
|
|
||||||
m_iNeedWritten=0;
|
|
||||||
m_iFlags=0;
|
|
||||||
m_iHidden=0;
|
|
||||||
};
|
|
||||||
const int NeedWritten(void) const
|
|
||||||
{
|
|
||||||
return m_iNeedWritten;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetNeedWritten(const int i=1)
|
|
||||||
{
|
|
||||||
m_iNeedWritten=i;
|
|
||||||
};
|
|
||||||
|
|
||||||
const String *GetName(void) const
|
|
||||||
{
|
|
||||||
return &m_strName;
|
|
||||||
};
|
|
||||||
|
|
||||||
const String *GetFlags(void) const
|
|
||||||
{
|
|
||||||
return &m_strFlags;
|
|
||||||
};
|
|
||||||
const String *GetComment(void) const
|
|
||||||
{
|
|
||||||
return &m_strComment;
|
|
||||||
};
|
|
||||||
|
|
||||||
const int Flags(void) const
|
|
||||||
{
|
|
||||||
return m_iFlags;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetName(const char *data)
|
|
||||||
{
|
|
||||||
m_strName.assign(data);
|
|
||||||
};
|
|
||||||
void SetFlags(const char *flags)
|
|
||||||
{
|
|
||||||
// If this is a "!" entry then stop
|
|
||||||
if (flags && flags[0]=='!')
|
|
||||||
{
|
|
||||||
SetHidden(1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_strFlags.assign(flags);
|
|
||||||
m_iFlags=UTIL_ReadFlags(flags);
|
|
||||||
};
|
|
||||||
void SetFlags(const int flags)
|
|
||||||
{
|
|
||||||
m_iFlags=flags;
|
|
||||||
|
|
||||||
char FlagsString[32];
|
|
||||||
UTIL_GetFlags(FlagsString, flags);
|
|
||||||
|
|
||||||
m_strFlags.assign(FlagsString);
|
|
||||||
};
|
|
||||||
void SetComment(const char *comment)
|
|
||||||
{
|
|
||||||
m_strComment.assign(comment);
|
|
||||||
};
|
|
||||||
void SetHidden(int i=1)
|
|
||||||
{
|
|
||||||
m_iHidden=i;
|
|
||||||
};
|
|
||||||
int IsHidden(void) const
|
|
||||||
{
|
|
||||||
return m_iHidden;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
class CFlagManager
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
List<CFlagEntry *> m_FlagList;
|
|
||||||
String m_strConfigFile;
|
|
||||||
struct stat m_Stat;
|
|
||||||
int m_iForceRead;
|
|
||||||
int m_iDisabled;
|
|
||||||
|
|
||||||
|
|
||||||
void CreateIfNotExist(void) const
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
fp=fopen(m_strConfigFile.c_str(),"r");
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
// File does not exist, create the header
|
|
||||||
fp=fopen(m_strConfigFile.c_str(),"a");
|
|
||||||
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fprintf(fp,"; This file will store the commands used by plugins, and their access level\n");
|
|
||||||
fprintf(fp,"; To change the access of a command, edit the flags beside it and then\n");
|
|
||||||
fprintf(fp,"; change the server's map.\n;\n");
|
|
||||||
fprintf(fp,"; Example: If I wanted to change the amx_slap access to require\n");
|
|
||||||
fprintf(fp,"; RCON access (flag \"l\") I would change this:\n");
|
|
||||||
fprintf(fp,"; \"amx_slap\" \"e\" ; admincmd.amxx\n");
|
|
||||||
fprintf(fp,"; To this:\n");
|
|
||||||
fprintf(fp,"; \"amx_slap\" \"l\" ; admincmd.amxx\n;\n");
|
|
||||||
fprintf(fp,"; To disable a specific command from being used with the command manager\n");
|
|
||||||
fprintf(fp,"; and to only use the plugin-specified access set the flag to \"!\"\n;\n");
|
|
||||||
fprintf(fp,"; NOTE: The plugin name at the end is just for reference to what plugin\n");
|
|
||||||
fprintf(fp,"; uses what commands. It is ignored.\n\n");
|
|
||||||
fclose(fp);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Returns 1 if the timestamp for the file is different than the one we have loaded
|
|
||||||
* 0 otherwise
|
|
||||||
*/
|
|
||||||
inline int NeedToLoad(void)
|
|
||||||
{
|
|
||||||
struct stat TempStat;
|
|
||||||
|
|
||||||
stat(m_strConfigFile.c_str(),&TempStat);
|
|
||||||
|
|
||||||
// If the modified timestamp does not match the stored
|
|
||||||
// timestamp than we need to re-read this file.
|
|
||||||
// Otherwise, ignore the file.
|
|
||||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
|
||||||
{
|
|
||||||
// Save down the modified timestamp
|
|
||||||
m_Stat.st_mtime=TempStat.st_mtime;
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
};
|
|
||||||
public:
|
|
||||||
|
|
||||||
CFlagManager()
|
|
||||||
{
|
|
||||||
memset(&m_Stat,0x0,sizeof(struct stat));
|
|
||||||
m_iDisabled=0;
|
|
||||||
m_iForceRead=0;
|
|
||||||
};
|
|
||||||
~CFlagManager()
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the filename in relation to amxmodx/configs
|
|
||||||
*/
|
|
||||||
void SetFile(const char *Filename="cmdaccess.ini");
|
|
||||||
|
|
||||||
const char *GetFile(void) const { return m_strConfigFile.c_str(); };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse the file, and load all entries
|
|
||||||
* Returns 1 on success, 0 on refusal (no need to), and -1 on error
|
|
||||||
*/
|
|
||||||
const int LoadFile(const int force=0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the command exists in the list
|
|
||||||
* If it does, it byrefs the flags for it
|
|
||||||
* If it does not, it adds it to the list
|
|
||||||
* These are added from register_*cmd calls
|
|
||||||
*/
|
|
||||||
void LookupOrAdd(const char *Command, int &Flags, AMX *Plugin);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the commands back to the file
|
|
||||||
*/
|
|
||||||
void WriteCommands(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add this straight from the cmdaccess.ini file
|
|
||||||
*/
|
|
||||||
void AddFromFile(const char *Command, const char *Flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if this command should be added to flagman or not
|
|
||||||
* This is only checked when adding commands from the register_* natives
|
|
||||||
* If an admin manually adds a command to cmdaccess.ini it will be used
|
|
||||||
* regardless of whatever this function would say should be done with it
|
|
||||||
*/
|
|
||||||
int ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const;
|
|
||||||
|
|
||||||
void Clear(void);
|
|
||||||
|
|
||||||
void CheckIfDisabled(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CFLAGMANAGER_H
|
|
@ -30,30 +30,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#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)
|
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 +51,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,86 +62,55 @@ 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++)
|
||||||
{
|
{
|
||||||
if (iter->pPlugin->isExecutable(iter->func))
|
if (iter->pPlugin->isExecutable(iter->func))
|
||||||
{
|
{
|
||||||
// Get debug info
|
|
||||||
AMX *amx = (*iter).pPlugin->getAMX();
|
|
||||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
|
||||||
|
|
||||||
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]);
|
|
||||||
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_SetString(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(iter->pPlugin->getAMX(), 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!
|
|
||||||
for (i = m_NumParams-1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
amx_Push(amx, realParams[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// exec
|
// exec
|
||||||
cell retVal = 0;
|
cell retVal;
|
||||||
#if defined BINLOG_ENABLED
|
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
||||||
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
|
|
||||||
#endif
|
|
||||||
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)
|
||||||
{
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err, iter->pPlugin->getAMX()->curline, iter->pPlugin->getName());
|
||||||
//Did something else set an error?
|
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
|
||||||
{
|
|
||||||
//we don't care, something else logged the error.
|
|
||||||
}
|
|
||||||
else if (err != -1)
|
|
||||||
{
|
|
||||||
//nothing logged the error so spit it out anyway
|
|
||||||
LogError(amx, err, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
@ -166,24 +122,22 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
// copy back
|
// copy back
|
||||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
// copy back
|
// copy back
|
||||||
if (preparedArrays[params[i]].copyBack)
|
cell *tmp = physAddrs[i];
|
||||||
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
cell *tmp = physAddrs[i];
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
}
|
||||||
{
|
else
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
{
|
||||||
} 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)
|
||||||
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||||
}
|
}
|
||||||
@ -192,42 +146,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,97 +184,63 @@ 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)
|
||||||
{
|
{
|
||||||
if (isFree)
|
if (isFree)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const int STRINGEX_MAXLENGTH = 128;
|
const int STRINGEX_MAXLENGTH = 128;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
|
||||||
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_SetString(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--)
|
|
||||||
amx_Push(m_Amx, realParams[i]);
|
|
||||||
|
|
||||||
// exec
|
// exec
|
||||||
cell retVal;
|
cell retVal;
|
||||||
#if defined BINLOG_ENABLED
|
amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams);
|
||||||
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
|
|
||||||
#endif
|
|
||||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
//Did something else set an error?
|
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
|
||||||
{
|
|
||||||
//we don't care, something else logged the error.
|
|
||||||
}
|
|
||||||
else if (err != -1)
|
|
||||||
{
|
|
||||||
//nothing logged the error so spit it out anyway
|
|
||||||
LogError(m_Amx, err, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDebugger)
|
|
||||||
pDebugger->EndExec();
|
|
||||||
|
|
||||||
m_Amx->error = AMX_ERR_NONE;
|
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
@ -339,73 +252,58 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
// copy back
|
// copy back
|
||||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||||
amx_Release(m_Amx, realParams[i]);
|
amx_Release(m_Amx, realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
// copy back
|
// copy back
|
||||||
if (preparedArrays[params[i]].copyBack)
|
cell *tmp = physAddrs[i];
|
||||||
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
cell *tmp = physAddrs[i];
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
}
|
||||||
{
|
else
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
{
|
||||||
} 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)
|
||||||
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
amx_Release(m_Amx, realParams[i]);
|
amx_Release(m_Amx, realParams[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
{
|
{
|
||||||
int retVal = -1;
|
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||||
CSPForward *pForward;
|
CSPForward *pForward;
|
||||||
|
|
||||||
if (!m_FreeSPForwards.empty())
|
if (!m_FreeSPForwards.empty())
|
||||||
{
|
{
|
||||||
retVal = m_FreeSPForwards.front();
|
pForward = m_SPForwards[m_FreeSPForwards.front() >> 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;
|
{
|
||||||
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 +312,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 +319,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 +377,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 +385,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,160 +398,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 CForwardMngr::duplicateSPForward(int id)
|
|
||||||
{
|
|
||||||
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSPForward *fwd = m_SPForwards.at(id >> 1);
|
|
||||||
|
|
||||||
return registerSPForward(fwd->m_Func, fwd->m_Amx, fwd->m_NumParams, fwd->m_ParamTypes);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CForwardMngr::isSameSPForward(int id1, int id2)
|
|
||||||
{
|
|
||||||
if (!isIdValid(id1) || !isIdValid(id2))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSPForward *fwd1 = m_SPForwards.at(id1 >> 1);
|
|
||||||
CSPForward *fwd2 = m_SPForwards.at(id2 >> 1);
|
|
||||||
|
|
||||||
if (fwd1->isFree || fwd2->isFree)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((fwd1->m_Amx == fwd2->m_Amx)
|
|
||||||
&& (fwd1->m_Func == fwd2->m_Func)
|
|
||||||
&& (fwd1->m_NumParams == fwd2->m_NumParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,12 +475,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)
|
||||||
@ -718,45 +485,28 @@ cell executeForwards(int id, ...)
|
|||||||
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
||||||
params[i] = *(cell*)&tmp;
|
params[i] = *(cell*)&tmp;
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack)
|
cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type)
|
||||||
{
|
{
|
||||||
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
|
||||||
{
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
m_validateAllAllocUnits();
|
|
||||||
#endif // MEMORY_TEST
|
|
||||||
|
|
||||||
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
|
||||||
m_TmpArraysNum = 0;
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
m_TmpArrays[m_TmpArraysNum].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;
|
||||||
m_TmpArrays[m_TmpArraysNum].copyBack = copyBack;
|
|
||||||
|
|
||||||
return m_TmpArraysNum++;
|
return m_TmpArraysNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack)
|
cell prepareCellArray(cell *ptr, unsigned int size)
|
||||||
{
|
{
|
||||||
return g_forwards.prepareArray((void*)ptr, size, Type_Cell, copyBack);
|
return g_forwards.prepareArray((void*)ptr, size, Type_Cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack)
|
cell prepareCharArray(char *ptr, unsigned int size)
|
||||||
{
|
{
|
||||||
return g_forwards.prepareArray((void*)ptr, size, Type_Char, copyBack);
|
return g_forwards.prepareArray((void*)ptr, size, Type_Char);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregisterSPForward(int id)
|
void unregisterSPForward(int id)
|
||||||
|
@ -46,14 +46,7 @@
|
|||||||
#ifndef FORWARD_H
|
#ifndef FORWARD_H
|
||||||
#define FORWARD_H
|
#define FORWARD_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
const int FORWARD_MAX_PARAMS = 16;
|
||||||
#include "sh_stack.h"
|
|
||||||
|
|
||||||
const int FORWARD_MAX_PARAMS = 32;
|
|
||||||
|
|
||||||
#define FORWARD_ONLY_OLD 1
|
|
||||||
#define FORWARD_ONLY_NEW 2
|
|
||||||
#define FORWARD_ALL 3
|
|
||||||
|
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
{
|
{
|
||||||
@ -84,11 +77,8 @@ enum ForwardArrayElemType
|
|||||||
struct ForwardPreparedArray
|
struct ForwardPreparedArray
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
ForwardArrayElemType type;
|
ForwardArrayElemType type;
|
||||||
|
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
bool copyBack;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Normal forward
|
// Normal forward
|
||||||
@ -97,45 +87,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 +119,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 +133,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,59 +153,52 @@ 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);
|
||||||
int duplicateSPForward(int id);
|
|
||||||
int isSameSPForward(int id1, int id2);
|
|
||||||
|
|
||||||
// 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); // 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);
|
||||||
|
|
||||||
// execute forwards
|
// execute forwards
|
||||||
cell executeForwards(int id, ...);
|
cell executeForwards(int id, ...);
|
||||||
// prepare array
|
// prepare array
|
||||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
|
cell prepareCellArray(cell *ptr, unsigned int size);
|
||||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
|
cell prepareCharArray(char *ptr, unsigned int size);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //FORWARD_H
|
|
||||||
|
1230
amxmodx/CLang.cpp
1230
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,284 +35,217 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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;
|
int err;
|
||||||
|
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) break;
|
||||||
if (!valid)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid)
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
try
|
||||||
{
|
{
|
||||||
executeForwards(a->func);
|
#endif
|
||||||
|
|
||||||
|
if (valid){
|
||||||
|
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")",
|
||||||
|
err,a->plugin->getAMX()->curline,a->plugin->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLEEXEPTIONS
|
||||||
}
|
}
|
||||||
}
|
catch( ... )
|
||||||
}
|
|
||||||
|
|
||||||
void LogEventsMngr::clearLogEvents()
|
|
||||||
{
|
|
||||||
logCurrent = logCounter = 0;
|
|
||||||
arelogevents = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_LOGARGS + 1; ++i)
|
|
||||||
{
|
|
||||||
CLogEvent **a = &logevents[i];
|
|
||||||
while (*a)
|
|
||||||
{
|
{
|
||||||
CLogEvent* bb = (*a)->next;
|
AMXXLOG_Log( "[AMXX] fatal error at log forward function execution");
|
||||||
delete *a;
|
|
||||||
*a = bb;
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
clearConditions();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::clearConditions()
|
void LogEventsMngr::clearLogEvents(){
|
||||||
{
|
logCurrent = logCounter = 0;
|
||||||
while (logcmplist)
|
arelogevents = false;
|
||||||
{
|
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
|
||||||
CLogCmp* a = logcmplist->next;
|
CLogEvent **a = &logevents[i];
|
||||||
delete logcmplist;
|
while(*a){
|
||||||
logcmplist = a;
|
CLogEvent* bb = (*a)->next;
|
||||||
}
|
delete *a;
|
||||||
|
*a = bb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent::LogCond::~LogCond()
|
void LogEventsMngr::clearConditions() {
|
||||||
{
|
while (logcmplist){
|
||||||
while (list)
|
CLogCmp* a = logcmplist->next;
|
||||||
{
|
delete logcmplist;
|
||||||
|
logcmplist = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
|
||||||
|
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; }
|
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
|
||||||
inline int getLogArgNum() { return logArgc; }
|
inline bool logEventsExist() { return arelogevents; }
|
||||||
inline const char* getLogArg(int i) { return (i < 0 || i >= logArgc) ? "" : logArgs[i]; }
|
void setLogString( char* frmt, va_list& vaptr );
|
||||||
void clearLogEvents();
|
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:
|
class iterator {
|
||||||
inline iterator(CLogEvent*aa, LogEventsMngr* bb) : a(aa), b(bb) {}
|
CLogEvent* a;
|
||||||
|
LogEventsMngr* b;
|
||||||
inline iterator& operator++()
|
public:
|
||||||
{
|
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
|
||||||
a = b->getValidLogEvent(a->next);
|
inline iterator& operator++() {
|
||||||
return *this;
|
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 a == c.a; }
|
||||||
inline bool operator!=(const iterator& c) const { return !operator == (c); }
|
inline bool operator!=(const iterator& c) const { return !operator==(c); }
|
||||||
CLogEvent& operator*() { return *a; }
|
CLogEvent& operator*() { return *a; }
|
||||||
operator bool () const { return a ? true : false; }
|
operator bool ( ) const { return a ? true : false; }
|
||||||
};
|
};
|
||||||
|
inline iterator begin() { return iterator(getValidLogEvent(logevents[ logArgc ]),this); }
|
||||||
inline iterator begin() { return iterator(getValidLogEvent(logevents[logArgc]), this); }
|
inline iterator end() { return iterator(0,this); }
|
||||||
inline iterator end() { return iterator(0, this); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //LOGEVENTS_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,101 +35,60 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class MenuMngr
|
// class MenuMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu)
|
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
|
||||||
{
|
|
||||||
plugin = a;
|
plugin = a;
|
||||||
keys = k;
|
keys = k;
|
||||||
menuid = mi;
|
menuid = mi;
|
||||||
next = 0;
|
|
||||||
is_new_menu = new_menu;
|
|
||||||
|
|
||||||
function = f;
|
function = f;
|
||||||
|
next = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 ( (!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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MenuMngr::registerMenuId(const char* n, AMX* a)
|
int MenuMngr::registerMenuId(const char* n, AMX* a )
|
||||||
{
|
{
|
||||||
int id = findMenuId(n, a);
|
int id = findMenuId( n, a );
|
||||||
|
if (id) return id;
|
||||||
if (id)
|
headid = new MenuIdEle( n, a , headid );
|
||||||
{
|
if (!headid)
|
||||||
return id;
|
return 0; // :TODO: Better error report
|
||||||
}
|
return headid->id;
|
||||||
|
|
||||||
headid = new MenuIdEle(n, a, headid);
|
|
||||||
|
|
||||||
return headid->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu)
|
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
|
||||||
{
|
{
|
||||||
MenuCommand **temp = &headcmd;
|
MenuCommand** temp = &headcmd;
|
||||||
if (from_new_menu)
|
while(*temp) temp = &(*temp)->next;
|
||||||
{
|
*temp = new MenuCommand(a,mi, k,f);
|
||||||
MenuCommand *ptr;
|
|
||||||
while (*temp)
|
|
||||||
{
|
|
||||||
ptr = *temp;
|
|
||||||
if (ptr->is_new_menu
|
|
||||||
&& ptr->plugin == a
|
|
||||||
&& ptr->menuid == mi)
|
|
||||||
{
|
|
||||||
if (g_forwards.isSameSPForward(ptr->function, f))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
temp = &(*temp)->next;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (*temp)
|
|
||||||
{
|
|
||||||
temp = &(*temp)->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*temp = new MenuCommand(a, mi, k, f, from_new_menu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
MenuMngr::iterator old = m_watch_iter;
|
|
||||||
|
|
||||||
m_watch_iter = iter;
|
|
||||||
|
|
||||||
return old;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int MenuMngr::MenuIdEle::uniqueid = 0;
|
int MenuMngr::MenuIdEle::uniqueid = 0;
|
@ -38,62 +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;
|
||||||
int is_new_menu;
|
MenuCommand* next;
|
||||||
|
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
|
||||||
MenuCommand* next;
|
public:
|
||||||
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu=false);
|
inline int getFunction() { return function; }
|
||||||
public:
|
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||||
inline int getFunction() { return function; }
|
inline bool matchCommand( int m, int k ) { return ((m == menuid) && (keys & k)); }
|
||||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
} *headcmd;
|
||||||
inline bool matchCommand(int m, int k)
|
|
||||||
{
|
|
||||||
return ((m == menuid) && (keys & k));
|
|
||||||
}
|
|
||||||
} *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 registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu=false);
|
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) {}
|
||||||
@ -103,16 +96,12 @@ 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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MenuMngr g_menucmds;
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif //MENUS_H
|
|
||||||
|
@ -29,17 +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 = false;
|
||||||
authorized = false;
|
authorized = false;
|
||||||
|
|
||||||
current = 0;
|
current = 0;
|
||||||
@ -48,8 +48,6 @@ 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();
|
||||||
@ -57,266 +55,178 @@ void CPlayer::Init(edict_t* e, int i)
|
|||||||
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();
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 ){
|
||||||
|
if ( (*a)->time > gpGlobals->time ) {
|
||||||
|
if ( (*a)->grenade == enemy ) {
|
||||||
|
found = true;
|
||||||
|
(*p) = (*a)->player;
|
||||||
|
type = (*a)->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Obj* b = (*a)->next;
|
||||||
|
delete *a;
|
||||||
|
*a = b;
|
||||||
|
|
||||||
while (*a)
|
continue;
|
||||||
{
|
|
||||||
if ((*a)->time > gpGlobals->time)
|
|
||||||
{
|
|
||||||
if ((*a)->grenade == enemy)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
(*p) = (*a)->player;
|
|
||||||
type = (*a)->type;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Obj* b = (*a)->next;
|
|
||||||
delete *a;
|
|
||||||
*a = b;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
a = &(*a)->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
}
|
||||||
|
a = &(*a)->next;
|
||||||
|
}
|
||||||
|
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 ( !strcmpi(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;
|
||||||
|
|
||||||
|
300
amxmodx/CMisc.h
300
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,15 +74,13 @@ public:
|
|||||||
|
|
||||||
bool initialized;
|
bool initialized;
|
||||||
bool ingame;
|
bool ingame;
|
||||||
|
bool bot;
|
||||||
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];
|
||||||
@ -111,48 +99,26 @@ public:
|
|||||||
int death_victim;
|
int death_victim;
|
||||||
bool death_tk;
|
bool death_tk;
|
||||||
String death_weapon;
|
String death_weapon;
|
||||||
int newmenu;
|
|
||||||
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(){
|
||||||
|
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
|
||||||
inline bool IsBot()
|
|
||||||
{
|
|
||||||
if ((pEdict->v.flags & FL_FAKECLIENT) == FL_FAKECLIENT)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *auth = GETPLAYERAUTHID(pEdict);
|
|
||||||
if (auth && (strcmp(auth, "BOT") == 0))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
@ -161,44 +127,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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -208,175 +170,81 @@ public:
|
|||||||
|
|
||||||
class XVars
|
class XVars
|
||||||
{
|
{
|
||||||
struct XVarEle
|
struct XVarEle {
|
||||||
{
|
AMX* amx;
|
||||||
AMX* amx;
|
cell* value;
|
||||||
cell* value;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
XVarEle* head;
|
XVarEle* head;
|
||||||
|
int size;
|
||||||
|
int num;
|
||||||
|
|
||||||
int size;
|
int realloc_array( int nsize );
|
||||||
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(){ --uid; }
|
||||||
|
} *head;
|
||||||
|
|
||||||
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
|
int newTeam;
|
||||||
{
|
|
||||||
tid = uid++;
|
|
||||||
}
|
|
||||||
|
|
||||||
~TeamEle() { --uid; }
|
|
||||||
} *head;
|
|
||||||
|
|
||||||
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; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CAdminData
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
cell m_AuthData[44];
|
|
||||||
cell m_Password[32];
|
|
||||||
cell m_Flags;
|
|
||||||
cell m_Access;
|
|
||||||
public:
|
|
||||||
|
|
||||||
CAdminData()
|
|
||||||
{
|
|
||||||
m_AuthData[0]=0;
|
|
||||||
m_Password[0]=0;
|
|
||||||
m_Flags=0;
|
|
||||||
m_Access=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetAccess(cell Access)
|
#endif
|
||||||
{
|
|
||||||
m_Access=Access;
|
|
||||||
};
|
|
||||||
cell GetAccess(void) const
|
|
||||||
{
|
|
||||||
return m_Access;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetFlags(cell Flags)
|
|
||||||
{
|
|
||||||
m_Flags=Flags;
|
|
||||||
};
|
|
||||||
cell GetFlags(void) const
|
|
||||||
{
|
|
||||||
return m_Flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetAuthID(const cell *Input)
|
|
||||||
{
|
|
||||||
unsigned int i=0;
|
|
||||||
while (i<sizeof(m_AuthData)-1)
|
|
||||||
{
|
|
||||||
if ((m_AuthData[i++]=*Input++)==0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_AuthData[sizeof(m_AuthData)-1]=0;
|
|
||||||
|
|
||||||
};
|
|
||||||
const cell *GetAuthID(void) const
|
|
||||||
{
|
|
||||||
return &m_AuthData[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetPass(const cell *Input)
|
|
||||||
{
|
|
||||||
unsigned int i=0;
|
|
||||||
while (i<sizeof(m_Password)-1)
|
|
||||||
{
|
|
||||||
if ((m_Password[i++]=*Input++)==0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Password[sizeof(m_Password)-1]=0;
|
|
||||||
|
|
||||||
};
|
|
||||||
const cell *GetPass(void) const
|
|
||||||
{
|
|
||||||
return &m_Password[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
CAdminData & operator = (const CAdminData &src)
|
|
||||||
{
|
|
||||||
this->SetAccess(src.GetAccess());
|
|
||||||
this->SetFlags(src.GetFlags());
|
|
||||||
this->SetAuthID(src.GetAuthID());
|
|
||||||
this->SetPass(src.GetPass());
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif //CMISC_H
|
|
||||||
|
@ -30,21 +30,97 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "libraries.h"
|
|
||||||
|
|
||||||
#ifndef FAR
|
#ifndef FAR
|
||||||
#define FAR
|
#define FAR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Old
|
||||||
|
typedef int (FAR *QUERYMOD)(module_info_s**);
|
||||||
|
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
|
||||||
|
typedef int (FAR *DETACHMOD)(void);
|
||||||
|
|
||||||
// New
|
// New
|
||||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||||
typedef int (FAR *CHECKGAME_NEW)(const char *);
|
|
||||||
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);
|
// Old
|
||||||
|
// These functions are needed since Small Abstract Machine 2.5.0
|
||||||
|
int wamx_FindPublic(AMX *amx, char *name, int *index)
|
||||||
|
{ return amx_FindPublic(amx, name, index); }
|
||||||
|
|
||||||
|
int wamx_FindPubVar(AMX *amx, char *varname, cell *amx_addr)
|
||||||
|
{ return amx_FindPubVar(amx, varname, amx_addr); }
|
||||||
|
|
||||||
|
int wamx_GetString(char *dest, cell *source)
|
||||||
|
{ return amx_GetString(dest, source, 0); }
|
||||||
|
|
||||||
|
AMX_NATIVE_INFO *wamx_NativeInfo(char *name, AMX_NATIVE func)
|
||||||
|
{ return amx_NativeInfo(name, func); }
|
||||||
|
|
||||||
|
int wamx_SetString(cell *dest, char *source, int pack)
|
||||||
|
{ return amx_SetString(dest, source, pack, 0); }
|
||||||
|
|
||||||
|
pfnamx_engine_g engAmxFunc = {
|
||||||
|
amx_Align16,
|
||||||
|
amx_Align32,
|
||||||
|
amx_Allot,
|
||||||
|
amx_Callback,
|
||||||
|
amx_Clone,
|
||||||
|
amx_Debug,
|
||||||
|
amx_Exec,
|
||||||
|
amx_Execv,
|
||||||
|
wamx_FindPublic,
|
||||||
|
wamx_FindPubVar,
|
||||||
|
amx_FindTagId,
|
||||||
|
amx_Flags,
|
||||||
|
amx_GetAddr,
|
||||||
|
amx_GetPublic,
|
||||||
|
amx_GetPubVar,
|
||||||
|
wamx_GetString,
|
||||||
|
amx_GetTag,
|
||||||
|
amx_GetUserData,
|
||||||
|
amx_Init,
|
||||||
|
amx_InitJIT,
|
||||||
|
amx_MemInfo,
|
||||||
|
amx_NameLength,
|
||||||
|
wamx_NativeInfo,
|
||||||
|
amx_NumPublics,
|
||||||
|
amx_NumPubVars,
|
||||||
|
amx_NumTags,
|
||||||
|
amx_RaiseError,
|
||||||
|
amx_Register,
|
||||||
|
amx_Release,
|
||||||
|
amx_SetCallback,
|
||||||
|
amx_SetDebugHook,
|
||||||
|
wamx_SetString,
|
||||||
|
amx_SetUserData,
|
||||||
|
amx_StrLen,
|
||||||
|
};
|
||||||
|
|
||||||
|
pfnmodule_engine_g engModuleFunc = {
|
||||||
|
add_amxnatives,
|
||||||
|
build_pathname,
|
||||||
|
copy_amxmemory,
|
||||||
|
format_amxstring,
|
||||||
|
get_amxaddr,
|
||||||
|
get_amxscript,
|
||||||
|
get_amxscriptname,
|
||||||
|
get_amxstring,
|
||||||
|
get_modname,
|
||||||
|
load_amxscript,
|
||||||
|
print_srvconsole,
|
||||||
|
report_error,
|
||||||
|
set_amxnatives,
|
||||||
|
set_amxstring,
|
||||||
|
amxstring_len,
|
||||||
|
unload_amxscript,
|
||||||
|
alloc_amxmemory,
|
||||||
|
free_amxmemory,
|
||||||
|
};
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CModule
|
// class CModule
|
||||||
@ -59,7 +135,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();
|
||||||
@ -71,10 +147,11 @@ 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");
|
||||||
|
|
||||||
|
// old
|
||||||
|
m_InfoOld = NULL;
|
||||||
// new
|
// new
|
||||||
m_Amxx = false;
|
m_Amxx = false;
|
||||||
m_InfoNew.author = "unknown";
|
m_InfoNew.author = "unknown";
|
||||||
@ -83,81 +160,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)
|
|
||||||
{
|
|
||||||
void **handle;
|
|
||||||
void *dummy = NULL;
|
|
||||||
|
|
||||||
if (!m_Handle)
|
|
||||||
handle = &dummy;
|
|
||||||
else
|
|
||||||
handle = (void **)&m_Handle;
|
|
||||||
|
|
||||||
int res = LoadMetamodPlugin(mmfile, handle, now);
|
|
||||||
|
|
||||||
if (!res)
|
|
||||||
{
|
|
||||||
m_Metamod = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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()
|
||||||
@ -173,7 +176,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);
|
||||||
@ -182,47 +184,43 @@ 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 {
|
|
||||||
m_Status = MODULE_BADLOAD;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (m_Status == MODULE_LOADED)
|
|
||||||
{
|
{
|
||||||
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
|
// old
|
||||||
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
|
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
|
||||||
|
|
||||||
|
if (AttachFunc)
|
||||||
|
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
|
||||||
|
m_Status = MODULE_LOADED;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
if (!m_Handle)
|
if (!m_Handle)
|
||||||
{
|
{
|
||||||
#if defined __linux__
|
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" failed to load (%s)", m_Filename.c_str(), dlerror());
|
|
||||||
#endif
|
|
||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -233,7 +231,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;
|
||||||
@ -243,51 +240,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
|
||||||
@ -297,39 +267,49 @@ bool CModule::queryModule()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lastly, check to see if this module is able to load on this game mod
|
|
||||||
CHECKGAME_NEW checkGame_New = (CHECKGAME_NEW)DLPROC(m_Handle, "AMXX_CheckGame");
|
|
||||||
|
|
||||||
if (checkGame_New)
|
|
||||||
{
|
|
||||||
// This is an optional check; do not fail modules that do not have it
|
|
||||||
int ret = checkGame_New(g_mod_name.c_str());
|
|
||||||
|
|
||||||
if (ret != AMXX_GAME_OK)
|
|
||||||
{
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case AMXX_GAME_BAD:
|
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") reported that it cannot load on game \"%s\"", m_Filename.c_str(), getVersion(), g_mod_name.c_str());
|
|
||||||
m_Status = MODULE_BADGAME;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an unknown CheckGame code (value: %d)", m_Filename.c_str(), getVersion(), ret);
|
|
||||||
m_Status = MODULE_BADLOAD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Status = MODULE_QUERY;
|
m_Status = MODULE_QUERY;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
m_Status = MODULE_NOQUERY;
|
else
|
||||||
m_Amxx = false;
|
{
|
||||||
|
// old interface not 64 bit compatible
|
||||||
|
#if SMALL_CELL_SIZE == 64
|
||||||
|
m_Status = MODULE_NOT64BIT;
|
||||||
return false;
|
return false;
|
||||||
|
#else
|
||||||
|
// Try old interface
|
||||||
|
QUERYMOD queryFunc_Old = (QUERYMOD)DLPROC(m_Handle,"AMX_Query"); // check what version
|
||||||
|
if (!queryFunc_Old)
|
||||||
|
{
|
||||||
|
m_Status = MODULE_NOQUERY;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*queryFunc_Old)(&m_InfoOld);
|
||||||
|
|
||||||
|
if (!m_InfoOld)
|
||||||
|
{
|
||||||
|
m_Status = MODULE_NOINFO;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_InfoOld->ivers != AMX_INTERFACE_VERSION)
|
||||||
|
{
|
||||||
|
m_Status = MODULE_OLD;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for attach
|
||||||
|
if (!DLPROC(m_Handle, "AMX_Attach"))
|
||||||
|
{
|
||||||
|
m_Status = MODULE_NOATTACH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_InfoOld->serial = (long int)this;
|
||||||
|
m_Status = MODULE_QUERY;
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,12 +318,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;
|
||||||
@ -353,52 +330,17 @@ bool CModule::detachModule()
|
|||||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#ifndef FAKEMETA
|
|
||||||
if (IsMetamod())
|
|
||||||
{
|
{
|
||||||
UnloadMetamodPlugin(m_Handle);
|
DETACHMOD detachFunc_Old = (DETACHMOD)DLPROC(m_Handle, "AMX_Detach");
|
||||||
|
if (detachFunc_Old)
|
||||||
|
(*detachFunc_Old)();
|
||||||
}
|
}
|
||||||
#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)
|
||||||
@ -408,32 +350,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";
|
||||||
case MODULE_BADGAME: return "bad game";
|
default: break;
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -36,21 +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
|
|
||||||
MODULE_BADGAME, // Module cannot load on the current game mod
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amxx_module_info_s
|
struct amxx_module_info_s
|
||||||
@ -59,28 +57,22 @@ struct amxx_module_info_s
|
|||||||
const char *author;
|
const char *author;
|
||||||
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 *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_GAME_OK 0 /* Module can load on this game. */
|
#define AMXX_INTERFACE_VERSION 1
|
||||||
#define AMXX_GAME_BAD 1 /* Module cannot load on this game. */
|
|
||||||
|
|
||||||
#define AMXX_INTERFACE_VERSION 4
|
|
||||||
|
|
||||||
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?
|
||||||
|
module_info_s* m_InfoOld; // module info (old 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
|
||||||
@ -92,37 +84,30 @@ 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
|
|
||||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
|
||||||
#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_Amxx ? (m_InfoNew.author) : (m_InfoOld ? m_InfoOld->author : "unknown"); }
|
||||||
inline const char* getVersion() const { return m_InfoNew.version; }
|
inline const char* getVersion() const { return m_Amxx ? (m_InfoNew.version) : (m_InfoOld ? m_InfoOld->version : "unknown"); }
|
||||||
inline const char* getName() const { return m_InfoNew.name; }
|
inline const char* getName() const { return m_Amxx ? (m_InfoNew.name) : (m_InfoOld ? m_InfoOld->name : "unknown"); }
|
||||||
|
inline module_info_s* getInfo() const { return m_InfoOld; } // old
|
||||||
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_Amxx ? ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)) : ( (m_Status==MODULE_LOADED) && (m_InfoOld->type==RELOAD_MODULE)); }
|
||||||
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; }
|
void CModule::CallPluginsLoaded();
|
||||||
|
|
||||||
void CallPluginsLoaded();
|
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||||
void CallPluginsUnloaded();
|
|
||||||
void CallPluginsUnloading();
|
|
||||||
|
|
||||||
CVector<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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,387 +33,150 @@
|
|||||||
#include "CPlugin.h"
|
#include "CPlugin.h"
|
||||||
#include "CForward.h"
|
#include "CForward.h"
|
||||||
#include "CFile.h"
|
#include "CFile.h"
|
||||||
#include "amx.h"
|
|
||||||
#include "natives.h"
|
|
||||||
#include "debugger.h"
|
|
||||||
#include "libraries.h"
|
|
||||||
|
|
||||||
extern const char *no_function;
|
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) {
|
||||||
|
|
||||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
|
|
||||||
{
|
|
||||||
CPlugin** a = &head;
|
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;
|
||||||
--pCounter;
|
--pCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::Finalize()
|
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||||
{
|
{
|
||||||
if (m_Finalized)
|
File fp( build_pathname("%s",filename) , "r" );
|
||||||
return;
|
|
||||||
|
|
||||||
pNatives = BuildNativeTable();
|
if ( !fp )
|
||||||
CPlugin *a = head;
|
|
||||||
|
|
||||||
while (a)
|
|
||||||
{
|
{
|
||||||
if (a->getStatusCode() == ps_running)
|
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename);
|
||||||
{
|
|
||||||
amx_Register(a->getAMX(), pNatives, -1);
|
|
||||||
a->Finalize();
|
|
||||||
}
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Finalized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
|
||||||
{
|
|
||||||
char file[256];
|
|
||||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
|
|
||||||
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
if (warn)
|
|
||||||
{
|
|
||||||
AMXXLOG_Error("[AMXX] Plugins list not found (file \"%s\")", filename);
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find now folder
|
// Find now folder
|
||||||
char pluginName[256], error[256], debug[256];
|
char pluginName[256], line[256], error[256], debug[256];
|
||||||
int debugFlag = 0;
|
int debugFlag = 0;
|
||||||
const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins");
|
const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins");
|
||||||
|
|
||||||
String line;
|
|
||||||
|
|
||||||
List<String *>::iterator block_iter;
|
while ( fp.getline(line , 255 ) )
|
||||||
|
|
||||||
while (!feof(fp))
|
|
||||||
{
|
{
|
||||||
pluginName[0] = '\0';
|
*pluginName = 0;
|
||||||
|
*debug = 0;
|
||||||
debug[0] = '\0';
|
|
||||||
debugFlag = 0;
|
debugFlag = 0;
|
||||||
|
sscanf(line,"%s %s",pluginName, debug);
|
||||||
|
if (!isalnum(*pluginName)) continue;
|
||||||
|
|
||||||
line.clear();
|
#ifdef JIT
|
||||||
line._fread(fp);
|
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
||||||
/** quick hack */
|
|
||||||
char *ptr = const_cast<char *>(line.c_str());
|
|
||||||
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"))
|
|
||||||
{
|
{
|
||||||
debugFlag = 1;
|
debugFlag = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (pNatives)
|
|
||||||
{
|
|
||||||
delete [] pNatives;
|
|
||||||
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)
|
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) {
|
||||||
{
|
if (!name) return 0;
|
||||||
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: return "running";
|
||||||
if ((failcounter >= 3)
|
case ps_paused: return "paused";
|
||||||
&& (status ))
|
case ps_bad_load: return "bad load";
|
||||||
{
|
case ps_stopped: return "stopped";
|
||||||
errorMsg.assign("This plugin is non-GPL which violates AMX Mod X's license.");
|
case ps_locked: return "locked";
|
||||||
status = ps_bad_load;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const char* CPluginMngr::CPlugin::getStatus() const
|
|
||||||
{
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case ps_running:
|
|
||||||
{
|
|
||||||
if (m_Debug)
|
|
||||||
{
|
|
||||||
return "debug";
|
|
||||||
} else {
|
|
||||||
return "running";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ps_paused: return "paused";
|
|
||||||
case ps_bad_load: return "bad load";
|
|
||||||
case ps_stopped: return "stopped";
|
|
||||||
case ps_locked: return "locked";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "error";
|
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* path = build_pathname("%s/%s",p,n);
|
||||||
char file[256];
|
|
||||||
char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
|
|
||||||
code = 0;
|
code = 0;
|
||||||
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;
|
||||||
|
}
|
||||||
|
CPluginMngr::CPlugin::~CPlugin( ){
|
||||||
|
unload_amxscript( &amx, &code );
|
||||||
|
}
|
||||||
|
|
||||||
if (status == ps_running)
|
void CPluginMngr::CPlugin::pauseFunction( int id ) {
|
||||||
{
|
if (isValid()){
|
||||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE);
|
paused_fun |= (1<<id);
|
||||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE);
|
g_commands.clearBufforedInfo();
|
||||||
|
|
||||||
if (amx.flags & AMX_FLAG_DEBUG)
|
|
||||||
{
|
|
||||||
m_Debug = true;
|
|
||||||
} else {
|
|
||||||
m_Debug = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin::~CPlugin()
|
void CPluginMngr::CPlugin::unpauseFunction( int id ) {
|
||||||
{
|
if (isValid()) {
|
||||||
unload_amxscript(&amx, &code);
|
paused_fun &= ~(1<<id);
|
||||||
}
|
g_commands.clearBufforedInfo();
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
char buffer[128];
|
|
||||||
int old_status = status;
|
|
||||||
|
|
||||||
if (CheckModules(&amx, buffer))
|
|
||||||
{
|
|
||||||
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
if (pHandler->IsNativeFiltering())
|
|
||||||
res = amx_CheckNatives(&amx, native_handler);
|
|
||||||
|
|
||||||
if (!res)
|
|
||||||
{
|
|
||||||
status = ps_bad_load;
|
|
||||||
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
|
||||||
errorMsg.assign(buffer);
|
|
||||||
amx.error = AMX_ERR_NOTFOUND;
|
|
||||||
} else {
|
|
||||||
amx_RegisterToAny(&amx, invalid_native);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status = ps_bad_load;
|
|
||||||
errorMsg.assign(buffer);
|
|
||||||
amx.error = AMX_ERR_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (old_status != status)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::pauseFunction(int id)
|
void CPluginMngr::CPlugin::setStatus( int a ) {
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::unpauseFunction(int id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::setStatus(int a)
|
|
||||||
{
|
|
||||||
status = a;
|
status = a;
|
||||||
g_commands.clearBufforedInfo(); // ugly way
|
g_commands.clearBufforedInfo(); // ugly way
|
||||||
}
|
}
|
||||||
@ -424,8 +187,16 @@ void CPluginMngr::CPlugin::pausePlugin()
|
|||||||
if (isValid())
|
if (isValid())
|
||||||
{
|
{
|
||||||
// call plugin_pause if provided
|
// call plugin_pause if provided
|
||||||
if (m_PauseFwd != -1)
|
int func;
|
||||||
executeForwards(m_PauseFwd);
|
cell retval;
|
||||||
|
if (amx_FindPublic(&amx, "plugin_pause", &func) == AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
if (isExecutable(func))
|
||||||
|
{
|
||||||
|
|
||||||
|
amx_Exec(&amx, &retval, func, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setStatus(ps_paused);
|
setStatus(ps_paused);
|
||||||
}
|
}
|
||||||
@ -434,286 +205,20 @@ 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)
|
int func;
|
||||||
|
cell retval;
|
||||||
|
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
executeForwards(m_UnpauseFwd);
|
if (isExecutable(func))
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
amx_Exec(&amx, &retval, func, 0);
|
||||||
{
|
|
||||||
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,20 @@ 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_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( );
|
||||||
|
|
||||||
CPlugin(int i, const char* p, const char* n, char* e, int d);
|
|
||||||
~CPlugin();
|
|
||||||
|
|
||||||
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();}
|
||||||
@ -92,55 +81,44 @@ public:
|
|||||||
inline int getStatusCode() { return status; }
|
inline int getStatusCode() { return status; }
|
||||||
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 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_bad_load) && (status != ps_locked)); }
|
||||||
inline bool isValid() const { return (status >= ps_paused); }
|
inline bool isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); }
|
||||||
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
|
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||||
inline bool isStopped() const { return (status == ps_stopped); }
|
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
|
||||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
|
||||||
|
|
||||||
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; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPlugin *head;
|
CPlugin *head;
|
||||||
int pCounter;
|
int pCounter;
|
||||||
public:
|
|
||||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
|
||||||
~CPluginMngr() { clear(); InvalidateCache(); }
|
|
||||||
|
|
||||||
bool m_Finalized;
|
|
||||||
AMX_NATIVE_INFO *pNatives;
|
public:
|
||||||
|
CPluginMngr() { head = 0; pCounter = 0; }
|
||||||
|
~CPluginMngr() { clear(); }
|
||||||
|
|
||||||
// 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 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 +128,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
|
||||||
|
|
||||||
|
@ -32,9 +32,6 @@
|
|||||||
#ifndef _INCLUDE_CSTRING_H
|
#ifndef _INCLUDE_CSTRING_H
|
||||||
#define _INCLUDE_CSTRING_H
|
#define _INCLUDE_CSTRING_H
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//by David "BAILOPAN" Anderson
|
//by David "BAILOPAN" Anderson
|
||||||
class String
|
class String
|
||||||
{
|
{
|
||||||
@ -42,8 +39,10 @@ public:
|
|||||||
String()
|
String()
|
||||||
{
|
{
|
||||||
v = NULL;
|
v = NULL;
|
||||||
a_size = 0;
|
mSize = 0;
|
||||||
//assign("");
|
cSize = 0;
|
||||||
|
Grow(2);
|
||||||
|
assign("");
|
||||||
}
|
}
|
||||||
|
|
||||||
~String()
|
~String()
|
||||||
@ -55,45 +54,41 @@ public:
|
|||||||
String(const char *src)
|
String(const char *src)
|
||||||
{
|
{
|
||||||
v = NULL;
|
v = NULL;
|
||||||
a_size = 0;
|
mSize = 0;
|
||||||
assign(src);
|
cSize = 0; assign(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * _fread(FILE *fp)
|
String(String &src)
|
||||||
{
|
|
||||||
Grow(512, false);
|
|
||||||
char *ret = fgets(v, 511, fp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
String(const String &src)
|
|
||||||
{
|
{
|
||||||
v = NULL;
|
v = NULL;
|
||||||
a_size = 0;
|
mSize = 0;
|
||||||
|
cSize = 0;
|
||||||
assign(src.c_str());
|
assign(src.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *c_str() { return v?v:""; }
|
const char *c_str() { return v?v:""; }
|
||||||
|
|
||||||
const char *c_str() const { return v?v:""; }
|
const char *c_str() const { return v?v:""; }
|
||||||
|
|
||||||
void append(const char *t)
|
void append(const char *t)
|
||||||
{
|
{
|
||||||
Grow(size() + strlen(t) + 1);
|
Grow(cSize + strlen(t) + 1);
|
||||||
strcat(v, t);
|
strcat(v, t);
|
||||||
|
cSize = strlen(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(const char c)
|
void append(const char c)
|
||||||
{
|
{
|
||||||
size_t len = size();
|
Grow(cSize + 2);
|
||||||
Grow(len + 2);
|
v[cSize] = c;
|
||||||
v[len] = c;
|
v[++cSize] = 0;
|
||||||
v[len + 1] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void append(String &d)
|
void append(String &d)
|
||||||
{
|
{
|
||||||
append(d.c_str());
|
const char *t = d.c_str();
|
||||||
|
Grow(cSize + strlen(t));
|
||||||
|
strcat(v, t);
|
||||||
|
cSize = strlen(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(const String &src)
|
void assign(const String &src)
|
||||||
@ -105,58 +100,79 @@ public:
|
|||||||
{
|
{
|
||||||
if (!d)
|
if (!d)
|
||||||
{
|
{
|
||||||
clear();
|
Grow(1);
|
||||||
|
cSize = 0;
|
||||||
|
strcpy(v, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Grow(strlen(d));
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
strcpy(v, d);
|
||||||
|
cSize = strlen(v);
|
||||||
} else {
|
} else {
|
||||||
size_t len = strlen(d);
|
cSize = 0;
|
||||||
Grow(len + 1, false);
|
|
||||||
memcpy(v, d, len);
|
|
||||||
v[len] = '\0';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (v)
|
if (v)
|
||||||
v[0] = '\0';
|
{
|
||||||
|
v[0] = 0;
|
||||||
|
cSize = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare (const char *d) const
|
int compare (const char *d)
|
||||||
{
|
{
|
||||||
if (!v)
|
if (v) {
|
||||||
return strcmp("", d);
|
if (d) {
|
||||||
else
|
return strcmp(v, d);
|
||||||
return strcmp(v, d);
|
} else {
|
||||||
|
return strlen(v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (d) {
|
||||||
|
return strlen(d);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Added this for amxx inclusion
|
//Added this for amxx inclusion
|
||||||
bool empty() const
|
bool empty()
|
||||||
{
|
{
|
||||||
if (!v)
|
if (!v || !cSize)
|
||||||
return true;
|
|
||||||
|
|
||||||
if (v[0] == '\0')
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const
|
int size()
|
||||||
{
|
{
|
||||||
if (v)
|
if (!v)
|
||||||
return strlen(v);
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
|
return cSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * _fread(FILE *fp)
|
||||||
|
{
|
||||||
|
Grow(512);
|
||||||
|
char * ret = fgets(v, 511, fp);
|
||||||
|
cSize = strlen(v);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int find(const char c, int index = 0)
|
int find(const char c, int index = 0)
|
||||||
{
|
{
|
||||||
int len = static_cast<int>(size());
|
if (!v)
|
||||||
if (len < 1)
|
|
||||||
return npos;
|
return npos;
|
||||||
if (index >= len || index < 0)
|
if (index >= (int)cSize || index < 0)
|
||||||
return npos;
|
return npos;
|
||||||
int i = 0;
|
unsigned int i = 0;
|
||||||
for (i=index; i<len; i++)
|
for (i=index; i<cSize; i++)
|
||||||
{
|
{
|
||||||
if (v[i] == c)
|
if (v[i] == c)
|
||||||
{
|
{
|
||||||
@ -171,7 +187,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (c == '\f' || c == '\n' ||
|
if (c == '\f' || c == '\n' ||
|
||||||
c == '\t' || c == '\r' ||
|
c == '\t' || c == '\r' ||
|
||||||
c == '\v' || c == ' ')
|
c == 'v' || c == ' ')
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -179,40 +195,14 @@ 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()
|
||||||
{
|
{
|
||||||
if (!v)
|
if (!v)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int j = 0;
|
unsigned int j = 0;
|
||||||
size_t len = strlen(v);
|
|
||||||
|
|
||||||
if (len == 1)
|
if (cSize == 1)
|
||||||
{
|
{
|
||||||
if (is_space(v[i]))
|
if (is_space(v[i]))
|
||||||
{
|
{
|
||||||
@ -225,9 +215,9 @@ public:
|
|||||||
|
|
||||||
if (is_space(c0))
|
if (is_space(c0))
|
||||||
{
|
{
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<cSize; i++)
|
||||||
{
|
{
|
||||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
|
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==cSize-1)))
|
||||||
{
|
{
|
||||||
erase(0, i);
|
erase(0, i);
|
||||||
break;
|
break;
|
||||||
@ -235,16 +225,16 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(v);
|
cSize = strlen(v);
|
||||||
|
|
||||||
if (len < 1)
|
if (cSize < 1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_space(v[len-1]))
|
if (is_space(v[cSize-1]))
|
||||||
{
|
{
|
||||||
for (i=len-1; i>=0; i--)
|
for (i=cSize-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
if (!is_space(v[i])
|
if (!is_space(v[i])
|
||||||
|| (is_space(v[i]) && i==0))
|
|| (is_space(v[i]) && i==0))
|
||||||
@ -256,7 +246,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 1)
|
if (cSize == 1)
|
||||||
{
|
{
|
||||||
if (is_space(v[0]))
|
if (is_space(v[0]))
|
||||||
{
|
{
|
||||||
@ -266,22 +256,21 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void erase(unsigned int start, int num = npos)
|
String & erase(unsigned int start, int num = npos)
|
||||||
{
|
{
|
||||||
if (!v)
|
if (!v)
|
||||||
return;
|
return (*this);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
size_t len = size();
|
|
||||||
//check for bounds
|
//check for bounds
|
||||||
if (num == npos || start+num > len-start)
|
if (num == npos || start+num > cSize-num+1)
|
||||||
num = len - start;
|
num = cSize - start;
|
||||||
//do the erasing
|
//do the erasing
|
||||||
bool copyflag = false;
|
bool copyflag = false;
|
||||||
for (i=0; i<len; i++)
|
for (i=0; i<cSize; i++)
|
||||||
{
|
{
|
||||||
if (i>=start && i<start+num)
|
if (i>=start && i<start+num)
|
||||||
{
|
{
|
||||||
if (i+num < len)
|
if (i+num < cSize)
|
||||||
{
|
{
|
||||||
v[i] = v[i+num];
|
v[i] = v[i+num];
|
||||||
} else {
|
} else {
|
||||||
@ -289,7 +278,7 @@ public:
|
|||||||
}
|
}
|
||||||
copyflag = true;
|
copyflag = true;
|
||||||
} else if (copyflag) {
|
} else if (copyflag) {
|
||||||
if (i+num < len)
|
if (i+num < cSize)
|
||||||
{
|
{
|
||||||
v[i] = v[i+num];
|
v[i] = v[i+num];
|
||||||
} else {
|
} else {
|
||||||
@ -297,39 +286,38 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
len -= num;
|
cSize -= num;
|
||||||
v[len] = 0;
|
v[cSize] = 0;
|
||||||
|
|
||||||
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
String substr(unsigned int index, int num = npos)
|
String substr(unsigned int index, int num = npos)
|
||||||
{
|
{
|
||||||
if (!v)
|
|
||||||
{
|
|
||||||
String b("");
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
String ns;
|
String ns;
|
||||||
|
|
||||||
size_t len = size();
|
if (index >= cSize || !v)
|
||||||
|
|
||||||
if (index >= len || !v)
|
|
||||||
return ns;
|
return ns;
|
||||||
|
|
||||||
if (num == npos)
|
if (num == npos)
|
||||||
{
|
{
|
||||||
num = len - index;
|
num = cSize - index;
|
||||||
} else if (index+num >= len) {
|
} else if (index+num >= cSize) {
|
||||||
num = len - index;
|
num = cSize - index;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0, j=0;
|
||||||
unsigned int nslen = num + 2;
|
char *s = new char[cSize+1];
|
||||||
|
|
||||||
ns.Grow(nslen);
|
|
||||||
|
|
||||||
for (i=index; i<index+num; i++)
|
for (i=index; i<index+num; i++)
|
||||||
ns.append(v[i]);
|
{
|
||||||
|
s[j++] = v[i];
|
||||||
|
}
|
||||||
|
s[j] = 0;
|
||||||
|
|
||||||
|
ns.assign(s);
|
||||||
|
|
||||||
|
delete [] s;
|
||||||
|
|
||||||
return ns;
|
return ns;
|
||||||
}
|
}
|
||||||
@ -339,11 +327,10 @@ public:
|
|||||||
if (!v)
|
if (!v)
|
||||||
return;
|
return;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
size_t len = strlen(v);
|
for (i=0; i<cSize; i++)
|
||||||
for (i=0; i<len; i++)
|
|
||||||
{
|
{
|
||||||
if (v[i] >= 65 && v[i] <= 90)
|
if (v[i] >= 65 && v[i] <= 90)
|
||||||
v[i] &= ~(1<<5);
|
v[i] |= 32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,7 +349,7 @@ public:
|
|||||||
|
|
||||||
char operator [] (unsigned int index)
|
char operator [] (unsigned int index)
|
||||||
{
|
{
|
||||||
if (index > size() || !v)
|
if (index > cSize)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@ -372,7 +359,7 @@ public:
|
|||||||
|
|
||||||
int at(int a)
|
int at(int a)
|
||||||
{
|
{
|
||||||
if (a < 0 || a >= (int)size() || !v)
|
if (a < 0 || a >= (int)cSize)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return v[a];
|
return v[a];
|
||||||
@ -380,7 +367,7 @@ public:
|
|||||||
|
|
||||||
bool at(int at, char c)
|
bool at(int at, char c)
|
||||||
{
|
{
|
||||||
if (at < 0 || at >= (int)size() || !v)
|
if (at < 0 || at >= (int)cSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
v[at] = c;
|
v[at] = c;
|
||||||
@ -389,23 +376,27 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Grow(unsigned int d, bool copy=true)
|
void Grow(unsigned int d)
|
||||||
{
|
{
|
||||||
if (d <= a_size)
|
if (d<1)
|
||||||
return;
|
return;
|
||||||
char *n = new char[d + 1];
|
if (d > mSize)
|
||||||
if (copy && v)
|
{
|
||||||
strcpy(n, v);
|
mSize = d + 16; // allocate a buffer
|
||||||
if (v)
|
char *t = new char[d+1];
|
||||||
delete [] v;
|
if (v) {
|
||||||
else
|
strcpy(t, v);
|
||||||
strcpy(n, "");
|
t[cSize] = 0;
|
||||||
v = n;
|
delete [] v;
|
||||||
a_size = d + 1;
|
}
|
||||||
|
v = t;
|
||||||
|
mSize = d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *v;
|
char *v;
|
||||||
unsigned int a_size;
|
unsigned int mSize;
|
||||||
|
unsigned int cSize;
|
||||||
public:
|
public:
|
||||||
static const int npos = -1;
|
static const int npos = -1;
|
||||||
};
|
};
|
||||||
|
@ -33,31 +33,29 @@
|
|||||||
#include "CTask.h"
|
#include "CTask.h"
|
||||||
|
|
||||||
/*********************** CTask ***********************/
|
/*********************** CTask ***********************/
|
||||||
|
int CTaskMngr::CTask::getTaskId() const
|
||||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
{
|
||||||
|
return m_iId;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
|
||||||
m_bFree = false;
|
m_bFree = false;
|
||||||
|
|
||||||
m_pPlugin = pPlugin;
|
m_pPlugin = pPlugin;
|
||||||
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;
|
||||||
|
|
||||||
@ -76,29 +74,11 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
|||||||
void CTaskMngr::CTask::clear()
|
void CTaskMngr::CTask::clear()
|
||||||
{
|
{
|
||||||
m_bFree = true;
|
m_bFree = true;
|
||||||
|
|
||||||
if (m_iFunc >= 0)
|
|
||||||
{
|
|
||||||
unregisterSPForward(m_iFunc);
|
|
||||||
m_iFunc = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pParams)
|
if (m_pParams)
|
||||||
{
|
{
|
||||||
delete [] m_pParams;
|
delete [] m_pParams;
|
||||||
m_pParams = NULL;
|
m_pParams = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pPlugin = NULL;
|
|
||||||
m_iId = 0;
|
|
||||||
m_fBase = 0.0f;
|
|
||||||
|
|
||||||
m_iRepeat = 0;
|
|
||||||
m_bLoop = false;
|
|
||||||
m_bAfterStart = false;
|
|
||||||
m_bBeforeEnd = false;
|
|
||||||
|
|
||||||
m_fNextExecTime = 0.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTaskMngr::CTask::isFree() const
|
bool CTaskMngr::CTask::isFree() const
|
||||||
@ -118,9 +98,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,66 +110,35 @@ 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())
|
|
||||||
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
|
||||||
|
{
|
||||||
|
unregisterSPForward(m_iFunc);
|
||||||
|
m_iFunc = 0;
|
||||||
|
m_bFree = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::CTask::CTask()
|
CTaskMngr::CTask::CTask()
|
||||||
{
|
{
|
||||||
m_bFree = true;
|
m_bFree = true;
|
||||||
|
|
||||||
m_pPlugin = NULL;
|
|
||||||
m_iFunc = -1;
|
|
||||||
m_iId = 0;
|
|
||||||
m_fBase = 0.0f;
|
|
||||||
|
|
||||||
m_iRepeat = 0;
|
|
||||||
m_bLoop = false;
|
|
||||||
m_bAfterStart = false;
|
|
||||||
m_bBeforeEnd = false;
|
|
||||||
m_bInExecute = false;
|
|
||||||
|
|
||||||
m_fNextExecTime = 0.0f;
|
|
||||||
|
|
||||||
m_iParamLen = 0;
|
|
||||||
m_pParams = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::CTask::~CTask()
|
CTaskMngr::CTask::~CTask()
|
||||||
@ -200,7 +147,6 @@ CTaskMngr::CTask::~CTask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*********************** CTaskMngr ***********************/
|
/*********************** CTaskMngr ***********************/
|
||||||
|
|
||||||
CTaskMngr::CTaskMngr()
|
CTaskMngr::CTaskMngr()
|
||||||
{
|
{
|
||||||
m_pTmr_CurrentTime = NULL;
|
m_pTmr_CurrentTime = NULL;
|
||||||
@ -208,11 +154,6 @@ CTaskMngr::CTaskMngr()
|
|||||||
m_pTmr_TimeLeft = NULL;
|
m_pTmr_TimeLeft = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::~CTaskMngr()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
||||||
{
|
{
|
||||||
m_pTmr_CurrentTime = pCurrentTime;
|
m_pTmr_CurrentTime = pCurrentTime;
|
||||||
@ -220,22 +161,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 +185,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 +199,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,36 +89,33 @@ 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;
|
||||||
public:
|
public:
|
||||||
CTaskMngr();
|
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;
|
||||||
|
Obj *next;
|
||||||
|
Obj( const char* k, const char* v);
|
||||||
|
} *head;
|
||||||
|
|
||||||
int number;
|
String path;
|
||||||
Obj *next;
|
|
||||||
Obj(const char* k, const char* v);
|
|
||||||
} *head;
|
|
||||||
|
|
||||||
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 remove( const char* k );
|
||||||
|
const char* get( const char* n );
|
||||||
|
int get_number( const char* n );
|
||||||
|
void setSource( const char* n );
|
||||||
|
bool loadVault( );
|
||||||
|
bool saveVault( );
|
||||||
|
void clear();
|
||||||
|
|
||||||
void put(const char* k, const char* v);
|
|
||||||
void remove(const char* k);
|
|
||||||
|
|
||||||
const char* get(const char* n);
|
class iterator {
|
||||||
int get_number(const char* n);
|
Obj * a;
|
||||||
void setSource(const char* n);
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
bool loadVault();
|
inline iterator begin() const { return iterator(head); }
|
||||||
bool saveVault();
|
inline iterator end() const { return iterator(0); }
|
||||||
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
Obj * a;
|
|
||||||
public:
|
|
||||||
iterator(Obj* aa) : a(aa) {}
|
|
||||||
iterator& operator++() { if (a) a = a->next; return *this; }
|
|
||||||
bool operator==(const iterator& b) const { return a == b.a; }
|
|
||||||
bool operator!=(const iterator& b) const { return !operator==(b); }
|
|
||||||
String& key() const { return a->key; }
|
|
||||||
String& value() const { return a->value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
inline iterator begin() const { return iterator(head); }
|
|
||||||
inline iterator end() const { return iterator(0); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //VAULT_CUSTOM_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,27 +37,18 @@
|
|||||||
// Vector
|
// Vector
|
||||||
template <class T> class CVector
|
template <class T> class CVector
|
||||||
{
|
{
|
||||||
bool Grow(size_t amount)
|
bool Grow()
|
||||||
{
|
{
|
||||||
// automatic grow
|
// automatic grow
|
||||||
size_t newSize = m_Size * 2;
|
size_t newSize = m_Size * 2;
|
||||||
|
|
||||||
if (newSize == 0)
|
if (newSize == 0)
|
||||||
{
|
newSize = 8; // a good init value
|
||||||
newSize = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (m_CurrentUsedSize + amount > newSize)
|
|
||||||
{
|
|
||||||
newSize *= 2;
|
|
||||||
}
|
|
||||||
T *newData = new T[newSize];
|
T *newData = new T[newSize];
|
||||||
if (!newData)
|
if (!newData)
|
||||||
return false;
|
return false;
|
||||||
if (m_Data)
|
if (m_Data)
|
||||||
{
|
{
|
||||||
for (size_t i=0; i<m_CurrentUsedSize; i++)
|
memcpy(newData, m_Data, m_Size * sizeof(T));
|
||||||
newData[i] = m_Data[i];
|
|
||||||
delete [] m_Data;
|
delete [] m_Data;
|
||||||
}
|
}
|
||||||
m_Data = newData;
|
m_Data = newData;
|
||||||
@ -65,16 +56,12 @@ template <class T> class CVector
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrowIfNeeded(size_t amount)
|
bool GrowIfNeeded()
|
||||||
{
|
{
|
||||||
if (m_CurrentUsedSize + amount >= m_Size)
|
if (m_CurrentUsedSize >= m_Size)
|
||||||
{
|
return Grow();
|
||||||
return Grow(amount);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChangeSize(size_t size)
|
bool ChangeSize(size_t size)
|
||||||
@ -82,58 +69,30 @@ 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;
|
memcpy(newData, m_Data, (m_Size < size) ? (m_Size * sizeof(T)) : (size * sizeof(T)));
|
||||||
for (size_t i=0; i<end; 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
|
||||||
{
|
{
|
||||||
@ -227,7 +186,7 @@ public:
|
|||||||
|
|
||||||
iterator & operator-=(size_t offset)
|
iterator & operator-=(size_t offset)
|
||||||
{
|
{
|
||||||
m_Ptr -= offset;
|
m_Ptr += offset;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +200,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,11 +251,10 @@ public:
|
|||||||
CVector<T>(const CVector<T> & other)
|
CVector<T>(const CVector<T> & other)
|
||||||
{
|
{
|
||||||
// copy data
|
// copy data
|
||||||
m_Data = new T [other.m_CurrentUsedSize];
|
m_Data = new T [other.m_Size];
|
||||||
m_Size = other.m_CurrentUsedSize;
|
m_Size = other.m_Size;
|
||||||
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||||||
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
|
memcpy(m_Data, other.m_Data, m_CurrentUsedSize * sizeof(T));
|
||||||
m_Data[i] = other.m_Data[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~CVector<T>()
|
~CVector<T>()
|
||||||
@ -315,12 +273,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);
|
||||||
}
|
}
|
||||||
@ -334,20 +292,19 @@ 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)
|
||||||
{
|
{
|
||||||
if (!GrowIfNeeded(1))
|
++m_CurrentUsedSize;
|
||||||
|
if (!GrowIfNeeded())
|
||||||
{
|
{
|
||||||
|
--m_CurrentUsedSize;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Data[m_CurrentUsedSize++] = elem;
|
m_Data[m_CurrentUsedSize - 1] = elem;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,15 +313,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,64 +393,50 @@ 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;
|
||||||
|
if (!GrowIfNeeded())
|
||||||
if (!GrowIfNeeded(1))
|
|
||||||
{
|
{
|
||||||
|
--m_CurrentUsedSize;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
++m_CurrentUsedSize;
|
memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data));
|
||||||
|
memcpy(where.base(), &value, sizeof(T));
|
||||||
where = begin() + ofs;
|
return true;
|
||||||
|
|
||||||
// Move subsequent entries
|
|
||||||
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.
File diff suppressed because it is too large
Load Diff
BIN
amxmodx/JIT/jits.o
Executable file
BIN
amxmodx/JIT/jits.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/jits.obj
Executable file
BIN
amxmodx/JIT/jits.obj
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
193
amxmodx/Makefile
193
amxmodx/Makefile
@ -1,120 +1,123 @@
|
|||||||
#(C)2004-2005 AMX Mod X Development Team
|
MODNAME = amxx_mm
|
||||||
# Makefile written by David "BAILOPAN" Anderson
|
SRCFILES = meta_api.cpp CFile.cpp CString.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 srvcmd.cpp strptime.cpp\
|
||||||
|
CForward.cpp CPlugin.cpp CModule.cpp CMenu.cpp emsg.cpp util.cpp \
|
||||||
|
amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp mmgr/mmgr.cpp \
|
||||||
|
amxxfile.cpp CLang.cpp md5.cpp amx.cpp
|
||||||
|
#use this for amd64, remove the above amx.cpp, and rename amx.cpp to amx.c
|
||||||
|
#CSRCFILES = amx.c minilzo/minilzo.c
|
||||||
|
CSRCFILES = minilzo/minilzo.c
|
||||||
|
|
||||||
HLSDK = ../../hlsdk
|
EXTRA_LIBS_LINUX =
|
||||||
MM_ROOT = ../../metamod/metamod
|
EXTRA_LIBS_WIN32 =
|
||||||
|
EXTRA_LIBDIRS_LINUX = -Lextra/lib_linux
|
||||||
|
EXTRA_LIBDIRS_WIN32 = -Lextra/lib_win32
|
||||||
|
|
||||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
EXTRA_INCLUDEDIRS = -Iextra/include
|
||||||
|
|
||||||
OPT_FLAGS = -O2 -fno-strict-aliasing -funroll-loops -s -fomit-frame-pointer -pipe -DNDEBUG
|
EXTRA_FLAGS = -Dstrcmpi=strcasecmp
|
||||||
DEBUG_FLAGS = -g -ggdb3
|
|
||||||
CPP = gcc-4.1
|
|
||||||
NAME = amxmodx
|
|
||||||
|
|
||||||
BIN_SUFFIX_32 = mm_i386.so
|
SDKTOP=../hlsdk
|
||||||
BIN_SUFFIX_64 = mm_amd64.so
|
METADIR=../metamod/metamod
|
||||||
|
|
||||||
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 \
|
|
||||||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
|
||||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
|
||||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
|
||||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
|
||||||
amxmod_compat.cpp nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
|
|
||||||
trie_natives.cpp
|
|
||||||
|
|
||||||
LINK = -lgcc -static-libgcc
|
SDKSRC=$(SDKTOP)/SourceCode
|
||||||
|
OBJDIR_LINUX=obj.linux
|
||||||
|
OBJDIR_WIN32=obj.win32
|
||||||
|
SRCDIR=.
|
||||||
|
|
||||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
ifdef windir
|
||||||
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
OS=WIN32
|
||||||
|
|
||||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
|
||||||
|
|
||||||
ifeq "$(GCC_VERSION)" "4"
|
|
||||||
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq "$(DEBUG)" "true"
|
|
||||||
BIN_DIR = Debug
|
|
||||||
CFLAGS = $(DEBUG_FLAGS)
|
|
||||||
else
|
else
|
||||||
BIN_DIR = Release
|
OS=LINUX
|
||||||
CFLAGS = $(OPT_FLAGS)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(BINLOG)" "true"
|
CC_LINUX=gcc
|
||||||
NAME := $(NAME)_bl
|
ifeq "$(OS)" "WIN32"
|
||||||
BIN_DIR := $(BIN_DIR)BinLog
|
CC_WIN32=gcc
|
||||||
OBJECTS += binlog.cpp
|
LD_WINDLL=dllwrap
|
||||||
CFLAGS += -DBINLOG_ENABLED
|
DEFAULT=win32
|
||||||
endif
|
CLEAN=clean_win32
|
||||||
|
|
||||||
CFLAGS += -DLINUX -DAMX_NOPROPLIST -Wall -Werror -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
|
|
||||||
|
|
||||||
ifeq "$(AMD64)" "true"
|
|
||||||
BINARY = $(NAME)_$(BIN_SUFFIX_64)
|
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64
|
|
||||||
LINK += -lz64
|
|
||||||
OBJECTS += JIT/natives-amd64.o
|
|
||||||
else
|
else
|
||||||
BINARY = $(NAME)_$(BIN_SUFFIX_32)
|
CC_WIN32=/usr/local/cross-tools/i386-mingw32msvc/bin/gcc
|
||||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
LD_WINDLL=/usr/local/cross-tools/bin/i386-mingw32msvc-dllwrap
|
||||||
OBJECTS += JIT/helpers-x86.o
|
DEFAULT=linux win32
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
CLEAN=clean_both
|
||||||
LINK += -lz
|
|
||||||
OPT_FLAGS += -march=i586
|
|
||||||
CFLAGS += -m32
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
|
||||||
|
|
||||||
$(BIN_DIR)/%.o: %.cpp
|
#use this for AMD64
|
||||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
#LIBFILE_LINUX = $(MODNAME)_amd64.so
|
||||||
|
LIBFILE_LINUX = $(MODNAME)_i386.so
|
||||||
|
LIBFILE_WIN32 = $(MODNAME).dll
|
||||||
|
TARGET_LINUX = $(OBJDIR_LINUX)/$(LIBFILE_LINUX)
|
||||||
|
TARGET_WIN32 = $(OBJDIR_WIN32)/$(LIBFILE_WIN32)
|
||||||
|
|
||||||
all:
|
FILES_ALL = *.cpp *.h [A-Z]* *.rc
|
||||||
mkdir -p $(BIN_DIR)
|
ifeq "$(OS)" "LINUX"
|
||||||
$(MAKE) amxmodx
|
ASRCFILES := $(shell ls -t $(SRCFILES))
|
||||||
|
else
|
||||||
|
ASRCFILES := $(shell dir /b)
|
||||||
|
endif
|
||||||
|
OBJ_LINUX := $(SRCFILES:%.cpp=$(OBJDIR_LINUX)/%.o)
|
||||||
|
OBJC_LINUX := $(CSRCFILES:%.c=$(OBJDIR_LINUX)/%.o)
|
||||||
|
OBJ_WIN32 := $(SRCFILES:%.cpp=$(OBJDIR_WIN32)/%.o)
|
||||||
|
OBJC_WIN32 := $(CSRCFILES:%.c=$(OBJDIR_WIN32)/%.o)
|
||||||
|
|
||||||
amd64:
|
#use this for amd64
|
||||||
rm -f zlib/libz.a
|
#CCOPT = -m64 -g -ggdb3 -DHAVE_I64 -DSMALL_CELL_SIZE=64
|
||||||
$(MAKE) all AMD64=true
|
CCOPT = -march=i386 -s -DNDEBUG -O2 -fomit-frame-pointer -fno-exceptions -fno-rtti -ffast math
|
||||||
|
|
||||||
amd64_debug:
|
INCLUDEDIRS=-I../curl/include -I$(SRCDIR) -I$(METADIR) -I$(SDKSRC)/engine -I$(SDKSRC)/common -I$(SDKSRC)/pm_shared -I$(SDKSRC)/dlls -I$(SDKSRC) $(EXTRA_INCLUDEDIRS)
|
||||||
rm -f zlib/libz.a
|
CFLAGS=-Wall -Wno-unknown-pragmas
|
||||||
$(MAKE) all AMD64=true DEBUG=true
|
ODEF = -DOPT_TYPE=\"optimized\"
|
||||||
|
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
|
||||||
|
|
||||||
amd64_binlog:
|
DO_CC_LINUX=$(CC_LINUX) $(CFLAGS) -fPIC $(INCLUDEDIRS) -o $@ -c $<
|
||||||
rm -f zlib/libz.a
|
DO_CC_WIN32=$(CC_WIN32) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $<
|
||||||
$(MAKE) all AMD64=true BINLOG=true
|
LINK_LINUX=$(CC_LINUX) $(CFLAGS) -shared -ldl -lm $(OBJ_LINUX) $(OBJC_LINUX) $(EXTRA_LIBDIRS_LINUX) $(EXTRA_LIBS_LINUX) -o $@
|
||||||
|
LINK_WIN32=$(LD_WINDLL) -mwindows --def $(MODNAME).def --add-stdcall-alias $(OBJ_WIN32) $(OBJC_WIN32) $(EXTRA_LIBDIRS_WIN32) $(EXTRA_LIBS_WIN32) -o $@
|
||||||
|
|
||||||
amd64_binlog_debug:
|
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c
|
||||||
rm -f zlib/libz.a
|
$(DO_CC_LINUX)
|
||||||
$(MAKE) all AMD64=true BINLOG=true DEBUG=true
|
|
||||||
|
|
||||||
binlog:
|
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp
|
||||||
$(MAKE) all BINLOG=true
|
$(DO_CC_LINUX)
|
||||||
|
|
||||||
binlog_debug:
|
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c
|
||||||
$(MAKE) all BINLOG=true DEBUG=true
|
$(DO_CC_WIN32)
|
||||||
|
|
||||||
amxmodx: $(OBJ_LINUX)
|
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.cpp
|
||||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
$(DO_CC_WIN32)
|
||||||
|
|
||||||
debug:
|
default: $(DEFAULT)
|
||||||
$(MAKE) all DEBUG=true
|
|
||||||
|
$(TARGET_LINUX): $(OBJDIR_LINUX) $(OBJ_LINUX) $(OBJC_LINUX)
|
||||||
|
$(LINK_LINUX)
|
||||||
|
|
||||||
|
$(TARGET_WIN32): $(OBJDIR_WIN32) $(OBJ_WIN32) $(OBJC_WIN32)
|
||||||
|
$(LINK_WIN32)
|
||||||
|
|
||||||
|
$(OBJDIR_LINUX):
|
||||||
|
mkdir $@
|
||||||
|
mkdir $@/mmgr
|
||||||
|
|
||||||
|
$(OBJDIR_WIN32):
|
||||||
|
mkdir $@
|
||||||
|
mkdir $@/mmgr
|
||||||
|
|
||||||
|
win32: $(TARGET_WIN32)
|
||||||
|
|
||||||
|
linux: $(TARGET_LINUX)
|
||||||
|
|
||||||
|
clean: $(CLEAN)
|
||||||
|
|
||||||
|
clean_both:
|
||||||
|
-rm -f $(OBJDIR_LINUX)/*
|
||||||
|
-rm -f $(OBJDIR_WIN32)/*
|
||||||
|
|
||||||
|
clean_win32:
|
||||||
|
del /q $(OBJDIR_WIN32)
|
||||||
|
|
||||||
default: all
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf Release/*.o
|
|
||||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX_32)
|
|
||||||
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/$(NAME)_$(BIN_SUFFIX_32)
|
|
||||||
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)
|
|
||||||
|
256
amxmodx/Makefile.pl
Executable file
256
amxmodx/Makefile.pl
Executable file
@ -0,0 +1,256 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
#(C)2004 AMX Mod X Development Team
|
||||||
|
# by David "BAILOPAN" Anderson
|
||||||
|
|
||||||
|
# output will occur in bin.x.proc
|
||||||
|
# where x is debug or opt and proc is ix86 or amd64
|
||||||
|
# You must use this script from the amxmodx src dir
|
||||||
|
|
||||||
|
#options =
|
||||||
|
# jit - use the JIT
|
||||||
|
# debug - enable gdb debugging
|
||||||
|
# amd64 - compile for AMD64 (impiles no jit)
|
||||||
|
# proc=ix86 - assumed not amd64
|
||||||
|
# clean - clean the specifications above
|
||||||
|
# asm - for ASM implementation
|
||||||
|
# !! TODO - add memory mananger support
|
||||||
|
# lineop - for JIT only, uses slow version
|
||||||
|
|
||||||
|
$PROJECT = "amxmodx_mm";
|
||||||
|
$sdk = "../hlsdk/SourceCode";
|
||||||
|
$mm = "../metamod/metamod";
|
||||||
|
$gccf = "gcc";
|
||||||
|
$ccf = "cc";
|
||||||
|
$amd64_lstdc = "-lstdc++";
|
||||||
|
|
||||||
|
@CPP_SOURCE_FILES = ("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", "srvcmd.cpp", "strptime.cpp", "amxcore.cpp", "amxtime.cpp", "power.cpp", "amxxlog.cpp", "fakemeta.cpp", "amxxfile.cpp", "CLang.cpp", "md5.cpp", "emsg.cpp", "CForward.cpp", "CPlugin.cpp", "CModule.cpp", "CMenu.cpp", "util.cpp");
|
||||||
|
|
||||||
|
@C_SOURCE_FILES = ();
|
||||||
|
my %OPTIONS, %OPT;
|
||||||
|
|
||||||
|
$OPT{"debug"} = "-g -ggdb";
|
||||||
|
$OPT{"opt"} = "-O2 -ffast-math -funroll-loops -fomit-frame-pointer -s -DNDEBUG -Wall -Wno-unknown-pragmas -DOPT_TYPE=\"optimized\" -fno-exceptions -fno-rtti";
|
||||||
|
|
||||||
|
$OPTIONS{"include"} = "-I$sdk -I. -I$mm -I$sdk/engine -I$sdk/common -I$sdk/pm_shared -I$sdk/dlls";
|
||||||
|
|
||||||
|
while ($cmd = shift)
|
||||||
|
{
|
||||||
|
if ($cmd =~ /asm/)
|
||||||
|
{
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
die "You cannot compile the ASM core with AMD64 yet.\n";
|
||||||
|
} else {
|
||||||
|
$OPTIONS{"asm"} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($cmd =~ /jit/)
|
||||||
|
{
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
die "You cannot compile the JIT and AMD64 yet.\n";
|
||||||
|
} else {
|
||||||
|
$OPTIONS{"jit"} = 1;
|
||||||
|
}
|
||||||
|
} elsif ($cmd =~ /amd64/) {
|
||||||
|
if ($OPTIONS{"jit"} || $OPTIONS{"asm"})
|
||||||
|
{
|
||||||
|
die "You cannot compile the JIT or ASM and AMD64 yet.\n";
|
||||||
|
} else {
|
||||||
|
$OPTIONS{"amd64"} = 1;
|
||||||
|
}
|
||||||
|
} elsif ($cmd =~ /debug/) {
|
||||||
|
$OPTIONS{"debug"} = 1;
|
||||||
|
} elsif ($cmd =~ /proc=i(\d)86/) {
|
||||||
|
$proc = $1;
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
die "You cannot compile for i".$proc."86 and AMD64.\n";
|
||||||
|
} else {
|
||||||
|
$OPTIONS{"proc"} = "i".$proc."86";
|
||||||
|
}
|
||||||
|
} elsif ($cmd =~ /clean/) {
|
||||||
|
$OPTIONS{"clean"} = 1;
|
||||||
|
} elsif ($cmd =~ /lineop/) {
|
||||||
|
$OPTIONS{"lineop"} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$gcc = `$gccf --version`;
|
||||||
|
if ($gcc =~ /2\.9/)
|
||||||
|
{
|
||||||
|
#if ($OPTIONS{"jit"})
|
||||||
|
#{
|
||||||
|
# push(@CPP_SOURCE_FILES, "amx.cpp");
|
||||||
|
# $OPT{"opt"} .= " -malign-loops=2 -malign-jumps=2 -malign-functions=2";
|
||||||
|
# } else {
|
||||||
|
`ln -s amx.cpp amx.c`;
|
||||||
|
push(@C_SOURCE_FILES, "amx.c");
|
||||||
|
# }
|
||||||
|
} else {
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
`ln -s amx.cpp amx.c`;
|
||||||
|
push(@C_SOURCE_FILES, "amx.c");
|
||||||
|
} else {
|
||||||
|
push(@CPP_SOURCE_FILES, "amx.cpp");
|
||||||
|
}
|
||||||
|
$OPT{"opt"} .= " -falign-loops=2 -falign-jumps=2 -falign-functions=2";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"debug"})
|
||||||
|
{
|
||||||
|
$cflags = $OPT{"debug"};
|
||||||
|
} else {
|
||||||
|
if (!$OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
$proc = $OPTIONS{"proc"};
|
||||||
|
if (!$proc)
|
||||||
|
{
|
||||||
|
$proc = 3;
|
||||||
|
}
|
||||||
|
$cflags = "-march=i".$proc."86 ".$OPT{"opt"};
|
||||||
|
} else {
|
||||||
|
$cflags = $OPT{"opt"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
$cflags = " -m64 -DSMALL_CELL_SIZE=64 -DHAVE_I64 $cflags";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"jit"})
|
||||||
|
{
|
||||||
|
$cflags .= " -DJIT";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"asm"})
|
||||||
|
{
|
||||||
|
$cflags .= " -DASM32";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"debug"})
|
||||||
|
{
|
||||||
|
$outdir = "bin.debug";
|
||||||
|
} else {
|
||||||
|
$outdir = "bin.opt";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
$outdir .= ".amd64";
|
||||||
|
$bin = $PROJECT."_amd64.so";
|
||||||
|
} else {
|
||||||
|
$proc = $OPTIONS{"proc"};
|
||||||
|
if ($proc)
|
||||||
|
{
|
||||||
|
$outdir .= ".i".$proc."86";
|
||||||
|
$bin = $PROJECT."_i".$proc."86.so";
|
||||||
|
} else {
|
||||||
|
$outdir .= ".i386";
|
||||||
|
$bin = $PROJECT."_i386.so";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($OPTIONS{"clean"})
|
||||||
|
{
|
||||||
|
`rm $outdir/*.o`;
|
||||||
|
`rm $outdir/$bin`;
|
||||||
|
die("Project cleaned.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#create the dirs
|
||||||
|
#build link list
|
||||||
|
my @LINK;
|
||||||
|
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||||
|
{
|
||||||
|
$file = $CPP_SOURCE_FILES[$i];
|
||||||
|
$file =~ s/\.cpp/\.o/;
|
||||||
|
push(@LINK, $outdir."/".$file);
|
||||||
|
}
|
||||||
|
for ($i=0; $i<=$#C_SOURCE_FILES; $i++)
|
||||||
|
{
|
||||||
|
$file = $C_SOURCE_FILES[$i];
|
||||||
|
$file =~ s/\.c/\.o/;
|
||||||
|
push(@LINK, $outdir."/".$file);
|
||||||
|
}
|
||||||
|
if ($OPTIONS{"jit"})
|
||||||
|
{
|
||||||
|
if ($OPTIONS{"lineop"}) {
|
||||||
|
push(@LINK, "JIT/jits-lineop.o");
|
||||||
|
} else {
|
||||||
|
push(@LINK, "JIT/jits.o");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
push(@LINK, "zlib/libz64.a");
|
||||||
|
push(@LINK, $amd64_lstdc);
|
||||||
|
} else {
|
||||||
|
push(@LINK, "zlib/libz.a");
|
||||||
|
}
|
||||||
|
if ($OPTIONS{"asm"})
|
||||||
|
{
|
||||||
|
push(@LINK, "amxexecn.o");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(-d $outdir))
|
||||||
|
{
|
||||||
|
mkdir($outdir);
|
||||||
|
}
|
||||||
|
if (!(-d "$outdir/JIT"))
|
||||||
|
{
|
||||||
|
mkdir("$outdir/JIT");
|
||||||
|
}
|
||||||
|
|
||||||
|
$inc = $OPTIONS{"include"};
|
||||||
|
|
||||||
|
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||||
|
{
|
||||||
|
$file = $CPP_SOURCE_FILES[$i];
|
||||||
|
$ofile = $file;
|
||||||
|
$ofile =~ s/\.cpp/\.o/;
|
||||||
|
$ofile = "$outdir/$ofile";
|
||||||
|
$gcc = "$gccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||||
|
if (-e $ofile)
|
||||||
|
{
|
||||||
|
$file_time = (stat($file))[9];
|
||||||
|
$ofile_time = (stat($ofile))[9];
|
||||||
|
if ($file_time > $ofile_time)
|
||||||
|
{
|
||||||
|
`rm $ofile`;
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
|
||||||
|
{
|
||||||
|
$file = $C_SOURCE_FILES[$i];
|
||||||
|
$ofile = $file;
|
||||||
|
$ofile =~ s/\.c/\.o/;
|
||||||
|
$ofile = "$outdir/$ofile";
|
||||||
|
$gcc = "$ccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||||
|
if (-e $ofile)
|
||||||
|
{
|
||||||
|
$file_time = (stat($file))[9];
|
||||||
|
$ofile_time = (stat($ofile))[9];
|
||||||
|
if ($file_time > $ofile_time)
|
||||||
|
{
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$gcc = "$gccf $cflags -shared -ldl -lm @LINK -o $outdir/$bin";
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
1994
amxmodx/amx.cpp
1994
amxmodx/amx.cpp
File diff suppressed because it is too large
Load Diff
296
amxmodx/amx.h
296
amxmodx/amx.h
@ -1,6 +1,6 @@
|
|||||||
/* Pawn Abstract Machine (for the Pawn language)
|
/* Abstract Machine for the Small compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty.
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
* In no event will the authors be held liable for any damages arising from
|
* In no event will the authors be held liable for any damages arising from
|
||||||
@ -21,81 +21,53 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined FREEBSD && !defined __FreeBSD__
|
#if defined __linux__
|
||||||
#define __FreeBSD__
|
|
||||||
#endif
|
|
||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AMX_H_INCLUDED
|
#ifndef AMX_H_INCLUDED
|
||||||
#define AMX_H_INCLUDED
|
#define AMX_H_INCLUDED
|
||||||
|
|
||||||
#if defined HAVE_STDINT_H
|
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else
|
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||||
#if defined HAVE_INTTYPES_H
|
* here, these types are probably undefined.
|
||||||
#include <inttypes.h>
|
*/
|
||||||
|
#if defined __FreeBSD__
|
||||||
|
#include <inttypes.h>
|
||||||
|
#else
|
||||||
|
typedef short int int16_t;
|
||||||
|
typedef unsigned short int uint16_t;
|
||||||
|
#if defined SN_TARGET_PS2
|
||||||
|
typedef int int32_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
typedef long int int32_t;
|
||||||
|
typedef unsigned long int uint32_t;
|
||||||
#endif
|
#endif
|
||||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
typedef __int64 int64_t;
|
||||||
* here, these types are probably undefined.
|
typedef unsigned __int64 uint64_t;
|
||||||
*/
|
#define HAVE_I64
|
||||||
#if defined __MACH__
|
#elif defined __GNUC__
|
||||||
#include <ppc/types.h>
|
typedef long long int64_t;
|
||||||
typedef unsigned short int uint16_t;
|
typedef unsigned long long uint64_t;
|
||||||
typedef unsigned long int uint32_t;
|
#define HAVE_I64
|
||||||
#elif defined __FreeBSD__
|
|
||||||
#include <inttypes.h>
|
|
||||||
#else
|
|
||||||
typedef short int int16_t;
|
|
||||||
typedef unsigned short int uint16_t;
|
|
||||||
#if defined SN_TARGET_PS2
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
#else
|
|
||||||
typedef long int int32_t;
|
|
||||||
typedef unsigned long int uint32_t;
|
|
||||||
#endif
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
#define HAVE_I64
|
|
||||||
#elif defined __GNUC__
|
|
||||||
typedef long long int64_t;
|
|
||||||
typedef unsigned long long uint64_t;
|
|
||||||
#define HAVE_I64
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
|
||||||
#if !defined __64BIT__
|
|
||||||
#define __64BIT__
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined arraysize
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
#if !defined alloca
|
||||||
|
#define alloca(n) _alloca(n)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined PAWN_DLL
|
|
||||||
#if !defined AMX_NATIVE_CALL
|
|
||||||
#define AMX_NATIVE_CALL __stdcall
|
|
||||||
#endif
|
|
||||||
#if !defined AMXAPI
|
|
||||||
#define AMXAPI __stdcall
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* calling convention for native functions */
|
/* calling convention for native functions */
|
||||||
#if !defined AMX_NATIVE_CALL
|
#if !defined AMX_NATIVE_CALL
|
||||||
#define AMX_NATIVE_CALL
|
#define AMX_NATIVE_CALL
|
||||||
@ -106,8 +78,6 @@ extern "C" {
|
|||||||
#define AMXAPI __stdcall
|
#define AMXAPI __stdcall
|
||||||
#elif defined CDECL
|
#elif defined CDECL
|
||||||
#define AMXAPI __cdecl
|
#define AMXAPI __cdecl
|
||||||
#elif defined GCC_HASCLASSVISIBILITY
|
|
||||||
#define AMXAPI __attribute__ ((visibility("default")))
|
|
||||||
#else
|
#else
|
||||||
#define AMXAPI
|
#define AMXAPI
|
||||||
#endif
|
#endif
|
||||||
@ -125,39 +95,45 @@ extern "C" {
|
|||||||
* 5 (tagnames table) 4
|
* 5 (tagnames table) 4
|
||||||
* 6 (reformatted header) 6
|
* 6 (reformatted header) 6
|
||||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
||||||
* 8 (opcode STMT, renewed debug interface) 8
|
|
||||||
*/
|
*/
|
||||||
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
|
#define CUR_FILE_VERSION 7 /* current file version; also the current AMX version */
|
||||||
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||||
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
|
#define MIN_AMX_VERSION 7 /* minimum AMX version needed to support the current file format */
|
||||||
|
|
||||||
#if !defined PAWN_CELL_SIZE
|
#if defined BIT16
|
||||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
#define SMALL_CELL_SIZE 16 /* for backward compatibility */
|
||||||
#endif
|
#endif
|
||||||
#if PAWN_CELL_SIZE==16
|
#if !defined SMALL_CELL_SIZE
|
||||||
|
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||||
|
#endif
|
||||||
|
#if SMALL_CELL_SIZE==16
|
||||||
typedef uint16_t ucell;
|
typedef uint16_t ucell;
|
||||||
typedef int16_t cell;
|
typedef int16_t cell;
|
||||||
#elif PAWN_CELL_SIZE==32
|
#elif SMALL_CELL_SIZE==32
|
||||||
typedef uint32_t ucell;
|
typedef uint32_t ucell;
|
||||||
typedef int32_t cell;
|
typedef int32_t cell;
|
||||||
#define REAL float
|
#elif SMALL_CELL_SIZE==64
|
||||||
#elif PAWN_CELL_SIZE==64
|
|
||||||
typedef uint64_t ucell;
|
typedef uint64_t ucell;
|
||||||
typedef int64_t cell;
|
typedef int64_t cell;
|
||||||
#define REAL double
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
#error Unsupported cell size (SMALL_CELL_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
#if SMALL_CELL_SIZE==32
|
||||||
#define UNLIMITED (~1u >> 1)
|
#define REAL float
|
||||||
|
#elif SMALL_CELL_SIZE==64
|
||||||
|
#define REAL double
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
||||||
|
|
||||||
struct tagAMX;
|
struct tagAMX;
|
||||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
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,20 +142,12 @@ 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
|
||||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||||
*/
|
*/
|
||||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||||
#define AMX_NO_ALIGN
|
#define AMX_NO_ALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -190,10 +158,8 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
#if !defined AMX_NO_ALIGN
|
||||||
#if defined LINUX || defined __FreeBSD__
|
#if defined __linux__
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
#elif defined MACOS && defined __MWERKS__
|
|
||||||
#pragma options align=mac68k
|
|
||||||
#else
|
#else
|
||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||||
@ -203,30 +169,25 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct tagAMX_NATIVE_INFO {
|
typedef struct {
|
||||||
const char _FAR *name PACKED;
|
const char _FAR *name PACKED;
|
||||||
AMX_NATIVE func PACKED;
|
AMX_NATIVE func PACKED;
|
||||||
} PACKED AMX_NATIVE_INFO;
|
} AMX_NATIVE_INFO;
|
||||||
|
|
||||||
#define AMX_USERNUM 4
|
#define AMX_USERNUM 4
|
||||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
ucell address PACKED;
|
ucell address PACKED;
|
||||||
char name[sEXPMAX+1];
|
const char name[sEXPMAX+1] PACKED;
|
||||||
} PACKED AMX_FUNCSTUB;
|
} AMX_FUNCSTUB;
|
||||||
|
|
||||||
typedef struct tagFUNCSTUBNT {
|
|
||||||
ucell address PACKED;
|
|
||||||
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
|
|
||||||
} PACKED AMX_FUNCSTUBNT;
|
|
||||||
|
|
||||||
/* The AMX structure is the internal structure for many functions. Not all
|
/* The AMX structure is the internal structure for many functions. Not all
|
||||||
* fields are valid at all times; many fields are cached in local variables.
|
* fields are valid at all times; many fields are cached in local variables.
|
||||||
*/
|
*/
|
||||||
typedef struct tagAMX {
|
typedef struct tagAMX {
|
||||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
|
||||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||||
AMX_CALLBACK callback PACKED;
|
AMX_CALLBACK callback PACKED;
|
||||||
AMX_DEBUG debug PACKED; /* debug callback */
|
AMX_DEBUG debug PACKED; /* debug callback */
|
||||||
@ -238,26 +199,28 @@ typedef struct tagAMX {
|
|||||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||||
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() */
|
||||||
|
/* for assertions and debug hook */
|
||||||
|
cell curline PACKED;
|
||||||
|
cell curfile PACKED;
|
||||||
|
int dbgcode PACKED;
|
||||||
|
cell dbgaddr PACKED;
|
||||||
|
cell dbgparam PACKED;
|
||||||
|
char _FAR *dbgname PACKED;
|
||||||
/* 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
|
|
||||||
//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;
|
||||||
/* passing parameters requires a "count" field */
|
|
||||||
int paramcount;
|
|
||||||
/* the sleep opcode needs to store the full AMX status */
|
/* the sleep opcode needs to store the full AMX status */
|
||||||
cell pri PACKED;
|
cell pri PACKED;
|
||||||
cell alt PACKED;
|
cell alt PACKED;
|
||||||
cell reset_stk PACKED;
|
cell reset_stk PACKED;
|
||||||
cell reset_hea PACKED;
|
cell reset_hea PACKED;
|
||||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
||||||
/* support variables for the JIT */
|
/* support variables for the JIT */
|
||||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||||
} PACKED AMX;
|
} AMX;
|
||||||
|
|
||||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||||
* structure is used internaly.
|
* structure is used internaly.
|
||||||
@ -265,8 +228,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 */
|
||||||
@ -279,11 +242,9 @@ typedef struct tagAMX_HEADER {
|
|||||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||||
int32_t pubvars PACKED; /* the "public variables" table */
|
int32_t pubvars PACKED; /* the "public variables" table */
|
||||||
int32_t tags PACKED; /* the "public tagnames" table */
|
int32_t tags PACKED; /* the "public tagnames" table */
|
||||||
int32_t nametable PACKED; /* name table */
|
int32_t nametable PACKED; /* name table, file version 7 only */
|
||||||
} PACKED AMX_HEADER;
|
} AMX_HEADER PACKED;
|
||||||
|
#define AMX_MAGIC 0xf1e0
|
||||||
//This is always the same for us
|
|
||||||
#define AMX_MAGIC 0xf1e0
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMX_ERR_NONE,
|
AMX_ERR_NONE,
|
||||||
@ -300,8 +261,6 @@ enum {
|
|||||||
AMX_ERR_NATIVE, /* native function failed */
|
AMX_ERR_NATIVE, /* native function failed */
|
||||||
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_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 */
|
||||||
@ -314,19 +273,28 @@ enum {
|
|||||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||||
AMX_ERR_PARAMS, /* parameter error */
|
AMX_ERR_PARAMS, /* parameter error */
|
||||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
DBG_INIT, /* query/initialize */
|
||||||
|
DBG_FILE, /* file number in curfile, filename in name */
|
||||||
|
DBG_LINE, /* line number in curline, file number in curfile */
|
||||||
|
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
|
||||||
|
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
|
||||||
|
DBG_CALL, /* function call, address jumped to in dbgaddr */
|
||||||
|
DBG_RETURN, /* function returns */
|
||||||
|
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
|
||||||
|
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
|
||||||
|
DBG_SYMTAG, /* tag of the most recent symbol (if non-zero), tag in dbgparam */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||||
#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_BIGENDIAN 0x08 /* big endian encoding */
|
||||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */
|
||||||
#define AMX_FLAG_OLDFILE 0x20 /* Old AMX Mod plugin */
|
#define AMX_FLAG_LINEOPS 0x20 /* line ops are parsed by the JIT [loadtime only flag] */
|
||||||
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
|
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */
|
||||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
|
||||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
|
||||||
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
|
||||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||||
|
|
||||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
||||||
@ -334,29 +302,16 @@ enum {
|
|||||||
|
|
||||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||||
|
|
||||||
#if !defined AMX_COMPACTMARGIN
|
#define AMX_EXPANDMARGIN 64
|
||||||
#define AMX_COMPACTMARGIN 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UD_FINDPLUGIN 3
|
|
||||||
#define UD_DEBUGGER 2
|
|
||||||
#define UD_OPCODELIST 1
|
|
||||||
#define UD_HANDLER 0
|
|
||||||
#define UT_NATIVE 3
|
|
||||||
#define UT_OPTIMIZER 2
|
|
||||||
#define UT_BROWSEHOOK 1
|
|
||||||
#define UT_BINLOGS 0
|
|
||||||
|
|
||||||
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
|
|
||||||
|
|
||||||
/* 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_
|
||||||
* changing the bit pattern
|
* changing the bit pattern
|
||||||
*/
|
*/
|
||||||
#if PAWN_CELL_SIZE==32
|
#if SMALL_CELL_SIZE==32
|
||||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||||
#elif PAWN_CELL_SIZE==64
|
#elif SMALL_CELL_SIZE==64
|
||||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||||
#else
|
#else
|
||||||
@ -370,7 +325,7 @@ typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
|
|||||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||||
if (amx_length_ > 0 && \
|
if (amx_length_ > 0 && \
|
||||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1); \
|
||||||
else (result) = NULL; \
|
else (result) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -379,12 +334,22 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
|||||||
#if defined _I64_MAX || defined HAVE_I64
|
#if defined _I64_MAX || defined HAVE_I64
|
||||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SMALL_CELL_SIZE==32
|
||||||
|
#define amx_AlignCell amx_Align32
|
||||||
|
#elif SMALL_CELL_SIZE==64
|
||||||
|
#define amx_AlignCell amx_Align64
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size
|
||||||
|
#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_Debug(AMX *amx); /* default debug procedure, does nothing */
|
||||||
|
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
|
||||||
|
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
|
||||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||||
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||||
@ -394,72 +359,39 @@ int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
|||||||
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||||
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||||
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar);
|
||||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name,AMX_NATIVE func);
|
||||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||||
int AMXAPI amx_Push(AMX *amx, cell value);
|
|
||||||
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
|
||||||
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, 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);
|
||||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar);
|
||||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||||
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
int AMXAPI amx_StrLen(cell *cstring, int *length);
|
||||||
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
|
||||||
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||||
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
|
||||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||||
int AMXAPI amx_GetLibraries(AMX *amx);
|
int AMXAPI amx_UTF8Check(const char *string);
|
||||||
const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
|
void amx_NullNativeTable(AMX *amx);
|
||||||
int AMXAPI amx_SetStringOld(cell *dest,const char *source,int pack,int use_wchar);
|
|
||||||
int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
|
||||||
|
|
||||||
#if PAWN_CELL_SIZE==16
|
|
||||||
#define amx_AlignCell(v) amx_Align16(v)
|
|
||||||
#elif PAWN_CELL_SIZE==32
|
|
||||||
#define amx_AlignCell(v) amx_Align32(v)
|
|
||||||
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
|
||||||
#define amx_AlignCell(v) amx_Align64(v)
|
|
||||||
#else
|
|
||||||
#error Unsupported cell size
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define amx_RegisterFunc(amx, name, func) \
|
|
||||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
#if !defined AMX_NO_ALIGN
|
||||||
#if defined LINUX || defined __FreeBSD__
|
#if defined __linux__
|
||||||
#pragma pack() /* reset default packing */
|
#pragma pack() /* reset default packing */
|
||||||
#elif defined MACOS && defined __MWERKS__
|
|
||||||
#pragma options align=reset
|
|
||||||
#else
|
#else
|
||||||
#pragma pack(pop) /* reset previous packing */
|
#pragma pack(pop) /* reset previous packing */
|
||||||
#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
|
||||||
|
11
amxmodx/amx_mm.def
Executable file
11
amxmodx/amx_mm.def
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
; /usr/local/cross-tools/bin/i386-mingw32msvc-dlltool --base-file /tmp/cc4kB6s0.base --output-exp amx_mm.exp --dllname amx_mm.dll --output-def amx_mm.def --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def /tmp/ccyI7I7K.def
|
||||||
|
EXPORTS
|
||||||
|
GetEngineFunctions @ 1 ;
|
||||||
|
GetEngineFunctions_Post @ 2 ;
|
||||||
|
GetEntityAPI2 @ 3 ;
|
||||||
|
GetEntityAPI2_Post @ 4 ;
|
||||||
|
GiveFnptrsToDll = GiveFnptrsToDll@8 @ 5 ;
|
||||||
|
GiveFnptrsToDll@8 @ 6 ;
|
||||||
|
Meta_Attach @ 7 ;
|
||||||
|
Meta_Detach @ 8 ;
|
||||||
|
Meta_Query @ 9 ;
|
@ -1,6 +1,6 @@
|
|||||||
/* Core module for the Pawn AMX
|
/* Core module for the Small AMX
|
||||||
*
|
*
|
||||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
* Copyright (c) ITB CompuPhase, 1997-2004
|
||||||
*
|
*
|
||||||
* This software is provided "as-is", without any express or implied warranty.
|
* This software is provided "as-is", without any express or implied warranty.
|
||||||
* In no event will the authors be held liable for any damages arising from
|
* In no event will the authors be held liable for any damages arising from
|
||||||
@ -34,7 +34,14 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||||
|
#ifdef MEMORY_TEST
|
||||||
|
#include "mmgr/mmgr.h"
|
||||||
|
#endif // MEMORY_TEST
|
||||||
|
|
||||||
#include "amx.h"
|
#include "amx.h"
|
||||||
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
@ -53,13 +60,14 @@
|
|||||||
# define _tcscpy strcpy
|
# define _tcscpy strcpy
|
||||||
# define _tcsdup strdup
|
# define _tcsdup strdup
|
||||||
# define _tcslen strlen
|
# define _tcslen strlen
|
||||||
|
# define _stprintf sprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CHARBITS (8*sizeof(char))
|
#define CHARBITS (8*sizeof(char))
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
#if !defined AMX_NOPROPLIST
|
#if !defined NOPROPLIST
|
||||||
typedef struct _property_list {
|
typedef struct _property_list {
|
||||||
struct _property_list *next;
|
struct _property_list *next;
|
||||||
cell id;
|
cell id;
|
||||||
@ -68,7 +76,7 @@ typedef struct _property_list {
|
|||||||
//??? safe AMX (owner of the property)
|
//??? safe AMX (owner of the property)
|
||||||
} proplist;
|
} proplist;
|
||||||
|
|
||||||
static proplist proproot = { NULL, 0, NULL, 0 };
|
static proplist proproot = { NULL };
|
||||||
|
|
||||||
static proplist *list_additem(proplist *root)
|
static proplist *list_additem(proplist *root)
|
||||||
{
|
{
|
||||||
@ -134,13 +142,15 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
AMX_HEADER *hdr;
|
AMX_HEADER *hdr;
|
||||||
uchar *data;
|
uchar *data;
|
||||||
cell bytes;
|
cell bytes;
|
||||||
|
|
||||||
(void)params;
|
|
||||||
hdr=(AMX_HEADER *)amx->base;
|
hdr=(AMX_HEADER *)amx->base;
|
||||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||||
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
||||||
@ -180,16 +190,18 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
|||||||
/* adjust the address in "value" in case of an array access */
|
/* adjust the address in "value" in case of an array access */
|
||||||
value+=params[2]*sizeof(cell);
|
value+=params[2]*sizeof(cell);
|
||||||
/* verify the address */
|
/* verify the address */
|
||||||
if (value<0 || value>=amx->hea && value<amx->stk)
|
if (value<0 || (value>=amx->hea && value<amx->stk))
|
||||||
return 0;
|
return 0;
|
||||||
/* set the value indirectly */
|
/* set the value indirectly */
|
||||||
* (cell *)(data+(int)value) = params[3];
|
* (cell *)(data+(int)value) = params[3];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
(void)params;
|
|
||||||
return amx->stk - amx->hea;
|
return amx->stk - amx->hea;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,22 +220,142 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
amx_GetString(name,cstr,0,UNLIMITED);
|
amx_GetString(name,cstr,0);
|
||||||
err=amx_FindPublic(amx,name,&index);
|
err=amx_FindPublic(amx,name,&index);
|
||||||
if (err!=AMX_ERR_NONE)
|
if (err!=AMX_ERR_NONE)
|
||||||
index=-1; /* this is not considered a fatal error */
|
index=-1; /* this is not considered a fatal error */
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int amx_StrPack(cell *dest,cell *source)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
amx_StrLen(source,&len);
|
||||||
|
if ((ucell)*source>UNPACKEDMAX) {
|
||||||
|
/* source string is already packed */
|
||||||
|
while (len >= 0) {
|
||||||
|
*dest++ = *source++;
|
||||||
|
len-=sizeof(cell);
|
||||||
|
} /* while */
|
||||||
|
} else {
|
||||||
|
/* pack string, from bottom up */
|
||||||
|
cell c;
|
||||||
|
int i;
|
||||||
|
for (c=0,i=0; i<len; i++) {
|
||||||
|
assert((*source & ~0xffL)==0);
|
||||||
|
c=(c<<CHARBITS) | *source++;
|
||||||
|
if (i%sizeof(cell) == sizeof(cell)-1) {
|
||||||
|
*dest++=c;
|
||||||
|
c=0;
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
if (i%sizeof(cell) != 0) /* store remaining packed characters */
|
||||||
|
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
|
||||||
|
else
|
||||||
|
*dest=0; /* store full cell of zeros */
|
||||||
|
} /* if */
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amx_StrUnpack(cell *dest,cell *source)
|
||||||
|
{
|
||||||
|
if ((ucell)*source>UNPACKEDMAX) {
|
||||||
|
/* unpack string, from top down (so string can be unpacked in place) */
|
||||||
|
cell c;
|
||||||
|
int i,len;
|
||||||
|
amx_StrLen(source,&len);
|
||||||
|
dest[len]=0;
|
||||||
|
for (i=len-1; i>=0; i--) {
|
||||||
|
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
|
||||||
|
dest[i]=c & UCHAR_MAX;
|
||||||
|
} /* for */
|
||||||
|
} else {
|
||||||
|
/* source string is already unpacked */
|
||||||
|
while ((*dest++ = *source++) != 0)
|
||||||
|
/* nothing */;
|
||||||
|
} /* if */
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int verify_addr(AMX *amx,cell addr)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
cell *cdest;
|
||||||
|
|
||||||
|
err=amx_GetAddr(amx,addr,&cdest);
|
||||||
|
if (err!=AMX_ERR_NONE)
|
||||||
|
amx_RaiseError(amx,err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
|
||||||
|
{
|
||||||
|
cell *cptr;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
|
||||||
|
amx_StrLen(cptr,&len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
|
||||||
|
{
|
||||||
|
cell *cdest,*csrc;
|
||||||
|
int len,needed,err;
|
||||||
|
size_t lastaddr;
|
||||||
|
|
||||||
|
/* calculate number of cells needed for (packed) destination */
|
||||||
|
amx_GetAddr(amx,params[2],&csrc);
|
||||||
|
amx_StrLen(csrc,&len);
|
||||||
|
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
|
||||||
|
assert(needed>0);
|
||||||
|
lastaddr=(size_t)(params[1]+sizeof(cell)*needed-1);
|
||||||
|
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
amx_GetAddr(amx,params[1],&cdest);
|
||||||
|
err=amx_StrPack(cdest,csrc);
|
||||||
|
if (err!=AMX_ERR_NONE)
|
||||||
|
return amx_RaiseError(amx,err);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
|
||||||
|
{
|
||||||
|
cell *cdest,*csrc;
|
||||||
|
int len,err;
|
||||||
|
size_t lastaddr;
|
||||||
|
|
||||||
|
/* calculate number of cells needed for (packed) destination */
|
||||||
|
amx_GetAddr(amx,params[2],&csrc);
|
||||||
|
amx_StrLen(csrc,&len);
|
||||||
|
assert(len>=0);
|
||||||
|
lastaddr=(size_t)(params[1]+sizeof(cell)*(len+1)-1);
|
||||||
|
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
amx_GetAddr(amx,params[1],&cdest);
|
||||||
|
err=amx_StrUnpack(cdest,csrc);
|
||||||
|
if (err!=AMX_ERR_NONE)
|
||||||
|
return amx_RaiseError(amx,err);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
cell c;
|
cell c;
|
||||||
#if PAWN_CELL_SIZE==16
|
#if SMALL_CELL_SIZE==16
|
||||||
uchar b[2];
|
uchar b[2];
|
||||||
#elif PAWN_CELL_SIZE==32
|
#elif SMALL_CELL_SIZE==32
|
||||||
uchar b[4];
|
uchar b[4];
|
||||||
#elif PAWN_CELL_SIZE==64
|
#elif SMALL_CELL_SIZE==64
|
||||||
uchar b[8];
|
uchar b[8];
|
||||||
#else
|
#else
|
||||||
#error Unsupported cell size
|
#error Unsupported cell size
|
||||||
@ -231,21 +363,20 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
|||||||
} value;
|
} value;
|
||||||
uchar t;
|
uchar t;
|
||||||
|
|
||||||
(void)amx;
|
|
||||||
assert((size_t)params[0]==sizeof(cell));
|
assert((size_t)params[0]==sizeof(cell));
|
||||||
value.c = params[1];
|
value.c = params[1];
|
||||||
#if PAWN_CELL_SIZE==16
|
#if SMALL_CELL_SIZE==16
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[1];
|
value.b[0] = value.b[1];
|
||||||
value.b[1] = t;
|
value.b[1] = t;
|
||||||
#elif PAWN_CELL_SIZE==32
|
#elif SMALL_CELL_SIZE==32
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[3];
|
value.b[0] = value.b[3];
|
||||||
value.b[3] = t;
|
value.b[3] = t;
|
||||||
t = value.b[1];
|
t = value.b[1];
|
||||||
value.b[1] = value.b[2];
|
value.b[1] = value.b[2];
|
||||||
value.b[2] = t;
|
value.b[2] = t;
|
||||||
#elif PAWN_CELL_SIZE==64
|
#elif SMALL_CELL_SIZE==64
|
||||||
t = value.b[0];
|
t = value.b[0];
|
||||||
value.b[0] = value.b[7];
|
value.b[0] = value.b[7];
|
||||||
value.b[7] = t;
|
value.b[7] = t;
|
||||||
@ -264,9 +395,11 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
|||||||
return value.c;
|
return value.c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
(void)amx;
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
return (cell)CharLower((LPTSTR)params[1]);
|
return (cell)CharLower((LPTSTR)params[1]);
|
||||||
#elif defined _Windows
|
#elif defined _Windows
|
||||||
@ -276,9 +409,11 @@ static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
(void)amx;
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||||
return (cell)CharUpper((LPTSTR)params[1]);
|
return (cell)CharUpper((LPTSTR)params[1]);
|
||||||
#elif defined _Windows
|
#elif defined _Windows
|
||||||
@ -288,15 +423,19 @@ static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
(void)amx;
|
|
||||||
return params[1] <= params[2] ? params[1] : params[2];
|
return params[1] <= params[2] ? params[1] : params[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
(void)amx;
|
|
||||||
return params[1] >= params[2] ? params[1] : params[2];
|
return params[1] >= params[2] ? params[1] : params[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +451,7 @@ static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined AMX_NOPROPLIST
|
#if !defined NOPROPLIST
|
||||||
static char *MakePackedString(cell *cptr)
|
static char *MakePackedString(cell *cptr)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -320,21 +459,10 @@ static char *MakePackedString(cell *cptr)
|
|||||||
|
|
||||||
amx_StrLen(cptr,&len);
|
amx_StrLen(cptr,&len);
|
||||||
dest=(char *)malloc(len+sizeof(cell));
|
dest=(char *)malloc(len+sizeof(cell));
|
||||||
amx_GetString(dest,cptr,0,UNLIMITED);
|
amx_GetString(dest,cptr,0);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_addr(AMX *amx,cell addr)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
cell *cdest;
|
|
||||||
|
|
||||||
err=amx_GetAddr(amx,addr,&cdest);
|
|
||||||
if (err!=AMX_ERR_NONE)
|
|
||||||
amx_RaiseError(amx,err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
cell *cstr;
|
cell *cstr;
|
||||||
@ -352,7 +480,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
amx_GetAddr(amx,params[4],&cstr);
|
amx_GetAddr(amx,params[4],&cstr);
|
||||||
amx_SetString(cstr,item->name,1,0,UNLIMITED);
|
amx_SetString(cstr,item->name,1,0);
|
||||||
} /* if */
|
} /* if */
|
||||||
free(name);
|
free(name);
|
||||||
return (item!=NULL) ? item->value : 0;
|
return (item!=NULL) ? item->value : 0;
|
||||||
@ -417,14 +545,12 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined AMX_NORANDOM
|
|
||||||
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
||||||
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
||||||
* generator" that has been extended to 31-bits (the standard C version returns
|
* generator" that has been extended to 31-bits (the standard C version returns
|
||||||
* only 15-bits).
|
* only 15-bits).
|
||||||
*/
|
*/
|
||||||
#define INITIAL_SEED 0xcaa938dbL
|
static unsigned long IL_StandardRandom_seed = 0L;
|
||||||
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
|
|
||||||
#define IL_RMULT 1103515245L
|
#define IL_RMULT 1103515245L
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
#pragma argsused
|
#pragma argsused
|
||||||
@ -436,7 +562,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
|||||||
|
|
||||||
/* one-time initialization (or, mostly one-time) */
|
/* one-time initialization (or, mostly one-time) */
|
||||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
||||||
if (IL_StandardRandom_seed == INITIAL_SEED)
|
if (IL_StandardRandom_seed == 0L)
|
||||||
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -453,7 +579,6 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
|||||||
result %= params[1];
|
result %= params[1];
|
||||||
return (cell)result;
|
return (cell)result;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO core_Natives[] = {
|
AMX_NATIVE_INFO core_Natives[] = {
|
||||||
@ -462,13 +587,22 @@ AMX_NATIVE_INFO core_Natives[] = {
|
|||||||
{ "setarg", setarg },
|
{ "setarg", setarg },
|
||||||
{ "heapspace", heapspace },
|
{ "heapspace", heapspace },
|
||||||
{ "funcidx", funcidx },
|
{ "funcidx", funcidx },
|
||||||
|
{ "strlen", core_strlen },
|
||||||
|
{ "strpack", strpack },
|
||||||
|
{ "strunpack", strunpack },
|
||||||
{ "swapchars", swapchars },
|
{ "swapchars", swapchars },
|
||||||
{ "tolower", core_tolower },
|
{ "tolower", core_tolower },
|
||||||
{ "toupper", core_toupper },
|
{ "toupper", core_toupper },
|
||||||
|
{ "random", core_random },
|
||||||
{ "min", core_min },
|
{ "min", core_min },
|
||||||
{ "max", core_max },
|
{ "max", core_max },
|
||||||
{ "clamp", core_clamp },
|
{ "clamp", core_clamp },
|
||||||
{ "random", core_random },
|
#if !defined NOPROPLIST
|
||||||
|
{ "getproperty", getproperty },
|
||||||
|
{ "setproperty", setproperty },
|
||||||
|
{ "deleteproperty",delproperty },
|
||||||
|
{ "existproperty", existproperty },
|
||||||
|
#endif
|
||||||
{ NULL, NULL } /* terminator */
|
{ NULL, NULL } /* terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -477,10 +611,12 @@ int AMXEXPORT amx_CoreInit(AMX *amx)
|
|||||||
return amx_Register(amx, core_Natives, -1);
|
return amx_Register(amx, core_Natives, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
|
#pragma argsused
|
||||||
|
#endif
|
||||||
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
||||||
{
|
{
|
||||||
(void)amx;
|
#if !defined NOPROPLIST
|
||||||
#if !defined AMX_NOPROPLIST
|
|
||||||
//??? delete only the properties owned by the AMX
|
//??? delete only the properties owned by the AMX
|
||||||
while (proproot.next!=NULL)
|
while (proproot.next!=NULL)
|
||||||
list_delete(&proproot,proproot.next);
|
list_delete(&proproot,proproot.next);
|
||||||
|
@ -1,498 +0,0 @@
|
|||||||
/* Pawn debugger interface
|
|
||||||
*
|
|
||||||
* Support functions for debugger applications
|
|
||||||
*
|
|
||||||
* Copyright (c) ITB CompuPhase, 2005
|
|
||||||
*
|
|
||||||
* This software is provided "as-is", without any express or implied warranty.
|
|
||||||
* In no event will the authors be held liable for any damages arising from
|
|
||||||
* the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "osdefs.h" /* for _MAX_PATH */
|
|
||||||
#include "amx.h"
|
|
||||||
#include "amxdbg.h"
|
|
||||||
|
|
||||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
#include "mmgr/mmgr.h"
|
|
||||||
#endif // MEMORY_TEST
|
|
||||||
|
|
||||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg)
|
|
||||||
{
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
if (amxdbg->hdr != NULL)
|
|
||||||
free(amxdbg->hdr);
|
|
||||||
if (amxdbg->filetbl != NULL)
|
|
||||||
free(amxdbg->filetbl);
|
|
||||||
if (amxdbg->symboltbl != NULL)
|
|
||||||
free(amxdbg->symboltbl);
|
|
||||||
if (amxdbg->tagtbl != NULL)
|
|
||||||
free(amxdbg->tagtbl);
|
|
||||||
if (amxdbg->automatontbl != NULL)
|
|
||||||
free(amxdbg->automatontbl);
|
|
||||||
if (amxdbg->statetbl != NULL)
|
|
||||||
free(amxdbg->statetbl);
|
|
||||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void memread(void *dest, char **src, size_t size)
|
|
||||||
{
|
|
||||||
void *ptr = *src;
|
|
||||||
memcpy(dest, ptr, size);
|
|
||||||
*src += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ClipFileName(const char *inp)
|
|
||||||
{
|
|
||||||
static char buffer[256];
|
|
||||||
size_t len = strlen(inp);
|
|
||||||
const char *ptr = inp;
|
|
||||||
|
|
||||||
for (size_t i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
if ((inp[i] == '\\' || inp[i] == '/') && (i != len-1))
|
|
||||||
ptr = inp + i + 1;
|
|
||||||
}
|
|
||||||
strcpy(buffer, ptr);
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Note - I changed this function to read from memory instead.
|
|
||||||
// -- BAILOPAN
|
|
||||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr)
|
|
||||||
{
|
|
||||||
AMX_DBG_HDR dbghdr;
|
|
||||||
unsigned char *ptr;
|
|
||||||
int index, dim;
|
|
||||||
AMX_DBG_SYMDIM *symdim;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
|
|
||||||
char *addr = (char *)(dbg_addr);
|
|
||||||
|
|
||||||
memset(&dbghdr, 0, sizeof(AMX_DBG_HDR));
|
|
||||||
memread(&dbghdr, &addr, sizeof(AMX_DBG_HDR));
|
|
||||||
|
|
||||||
//brabbby graa gragghty graaahhhh
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_Align32((uint32_t*)&dbghdr.size);
|
|
||||||
amx_Align16(&dbghdr.magic);
|
|
||||||
amx_Align16(&dbghdr.flags);
|
|
||||||
amx_Align16(&dbghdr.files);
|
|
||||||
amx_Align16(&dbghdr.lines);
|
|
||||||
amx_Align16(&dbghdr.symbols);
|
|
||||||
amx_Align16(&dbghdr.tags);
|
|
||||||
amx_Align16(&dbghdr.automatons);
|
|
||||||
amx_Align16(&dbghdr.states);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (dbghdr.magic != AMX_DBG_MAGIC)
|
|
||||||
return AMX_ERR_FORMAT;
|
|
||||||
|
|
||||||
/* allocate all memory */
|
|
||||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
|
||||||
amxdbg->hdr = (AMX_DBG_HDR *)malloc((size_t)dbghdr.size);
|
|
||||||
if (dbghdr.files > 0)
|
|
||||||
amxdbg->filetbl = (AMX_DBG_FILE **)malloc(dbghdr.files * sizeof(AMX_DBG_FILE *));
|
|
||||||
if (dbghdr.symbols > 0)
|
|
||||||
amxdbg->symboltbl = (AMX_DBG_SYMBOL **)malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *));
|
|
||||||
if (dbghdr.tags > 0)
|
|
||||||
amxdbg->tagtbl = (AMX_DBG_TAG **)malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *));
|
|
||||||
if (dbghdr.automatons > 0)
|
|
||||||
amxdbg->automatontbl = (AMX_DBG_MACHINE **)malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *));
|
|
||||||
if (dbghdr.states > 0)
|
|
||||||
amxdbg->statetbl = (AMX_DBG_STATE **)malloc(dbghdr.states * sizeof(AMX_DBG_STATE *));
|
|
||||||
if (amxdbg->hdr == NULL
|
|
||||||
|| (dbghdr.files > 0 && amxdbg->filetbl == NULL)
|
|
||||||
|| (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL)
|
|
||||||
|| (dbghdr.tags > 0 && amxdbg->tagtbl == NULL)
|
|
||||||
|| (dbghdr.states > 0 && amxdbg->statetbl == NULL)
|
|
||||||
|| (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL))
|
|
||||||
{
|
|
||||||
dbg_FreeInfo(amxdbg);
|
|
||||||
return AMX_ERR_MEMORY;
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
/* load the entire symbolic information block into memory */
|
|
||||||
memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr);
|
|
||||||
ptr = (unsigned char *)(amxdbg->hdr + 1);
|
|
||||||
memread(ptr, &addr, (size_t)(dbghdr.size-sizeof(dbghdr)));
|
|
||||||
|
|
||||||
/* file table */
|
|
||||||
for (index = 0; index < dbghdr.files; index++) {
|
|
||||||
assert(amxdbg->filetbl != NULL);
|
|
||||||
amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_AlignCell(&amxdbg->filetbl[index]->address);
|
|
||||||
#endif
|
|
||||||
for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
ptr++; /* skip '\0' too */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
//debug("Files: %d\n", amxdbg->hdr->files);
|
|
||||||
for (index=0;index<amxdbg->hdr->files; index++)
|
|
||||||
{
|
|
||||||
strcpy((char *)amxdbg->filetbl[index]->name, ClipFileName(amxdbg->filetbl[index]->name));
|
|
||||||
//debug(" [%d] %s\n", index, amxdbg->filetbl[index]->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* line table */
|
|
||||||
amxdbg->linetbl = (AMX_DBG_LINE*)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
for (index = 0; index < dbghdr.lines; index++) {
|
|
||||||
amx_AlignCell(&amxdbg->linetbl[index].address);
|
|
||||||
amx_Align32((uint32_t*)&amxdbg->linetbl[index].line);
|
|
||||||
} /* for */
|
|
||||||
#endif
|
|
||||||
ptr += dbghdr.lines * sizeof(AMX_DBG_LINE);
|
|
||||||
|
|
||||||
/* symbol table (plus index tags) */
|
|
||||||
for (index = 0; index < dbghdr.symbols; index++) {
|
|
||||||
assert(amxdbg->symboltbl != NULL);
|
|
||||||
amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_AlignCell(&amxdbg->symboltbl[index]->address);
|
|
||||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag);
|
|
||||||
amx_AlignCell(&amxdbg->symboltbl[index]->codestart);
|
|
||||||
amx_AlignCell(&amxdbg->symboltbl[index]->codeend);
|
|
||||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim);
|
|
||||||
#endif
|
|
||||||
for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
ptr++; /* skip '\0' too */
|
|
||||||
for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) {
|
|
||||||
symdim = (AMX_DBG_SYMDIM *)ptr;
|
|
||||||
amx_Align16((uint16_t*)&symdim->tag);
|
|
||||||
amx_AlignCell(&symdim->size);
|
|
||||||
ptr += sizeof(AMX_DBG_SYMDIM);
|
|
||||||
} /* for */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* tag name table */
|
|
||||||
for (index = 0; index < dbghdr.tags; index++) {
|
|
||||||
assert(amxdbg->tagtbl != NULL);
|
|
||||||
amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_Align16(&amxdbg->tagtbl[index]->tag);
|
|
||||||
#endif
|
|
||||||
for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
ptr++; /* skip '\0' too */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* automaton name table */
|
|
||||||
for (index = 0; index < dbghdr.automatons; index++) {
|
|
||||||
assert(amxdbg->automatontbl != NULL);
|
|
||||||
amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
|
||||||
amx_AlignCell(&amxdbg->automatontbl[index]->address);
|
|
||||||
#endif
|
|
||||||
for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
ptr++; /* skip '\0' too */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* state name table */
|
|
||||||
for (index = 0; index < dbghdr.states; index++) {
|
|
||||||
assert(amxdbg->statetbl != NULL);
|
|
||||||
amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr;
|
|
||||||
#if BYTE_ORDER==BIG_ENDIAN
|
|
||||||
amx_Align16(&amxdbg->statetbl[index]->state);
|
|
||||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
|
||||||
#endif
|
|
||||||
for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
ptr++; /* skip '\0' too */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
*filename = NULL;
|
|
||||||
/* this is a simple linear look-up; a binary search would be possible too */
|
|
||||||
for (index = 0; index < amxdbg->hdr->files && amxdbg->filetbl[index]->address <= address; index++)
|
|
||||||
/* nothing */;
|
|
||||||
/* reset for overrun */
|
|
||||||
if (--index < 0)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*filename = amxdbg->filetbl[index]->name;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(line != NULL);
|
|
||||||
*line = 0;
|
|
||||||
/* this is a simple linear look-up; a binary search would be possible too */
|
|
||||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address <= address; index++)
|
|
||||||
/* nothing */;
|
|
||||||
/* reset for overrun */
|
|
||||||
if (--index < 0)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*line = (long)amxdbg->linetbl[index].line;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname)
|
|
||||||
{
|
|
||||||
/* dbg_LookupFunction() finds the function a code address is in. It can be
|
|
||||||
* used for stack walking, and for stepping through a function while stepping
|
|
||||||
* over sub-functions
|
|
||||||
*/
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(funcname != NULL);
|
|
||||||
*funcname = NULL;
|
|
||||||
for (index = 0; index < amxdbg->hdr->symbols; index++) {
|
|
||||||
if (amxdbg->symboltbl[index]->ident == iFUNCTN
|
|
||||||
&& amxdbg->symboltbl[index]->codestart <= address
|
|
||||||
&& amxdbg->symboltbl[index]->codeend > address)
|
|
||||||
break;
|
|
||||||
} /* for */
|
|
||||||
if (index >= amxdbg->hdr->symbols)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*funcname = amxdbg->symboltbl[index]->name;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(name != NULL);
|
|
||||||
*name = NULL;
|
|
||||||
for (index = 0; index < amxdbg->hdr->tags && amxdbg->tagtbl[index]->tag != tag; index++)
|
|
||||||
/* nothing */;
|
|
||||||
if (index >= amxdbg->hdr->tags)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*name = amxdbg->tagtbl[index]->name;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(name != NULL);
|
|
||||||
*name = NULL;
|
|
||||||
for (index = 0; index < amxdbg->hdr->automatons && amxdbg->automatontbl[index]->automaton != automaton; index++)
|
|
||||||
/* nothing */;
|
|
||||||
if (index >= amxdbg->hdr->automatons)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*name = amxdbg->automatontbl[index]->name;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(name != NULL);
|
|
||||||
*name = NULL;
|
|
||||||
for (index = 0; index < amxdbg->hdr->states && amxdbg->statetbl[index]->state != state; index++)
|
|
||||||
/* nothing */;
|
|
||||||
if (index >= amxdbg->hdr->states)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
*name = amxdbg->statetbl[index]->name;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address)
|
|
||||||
{
|
|
||||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
|
||||||
* the specified file). The address is moved up to the next "breakable" line
|
|
||||||
* if no "breakpoint" is available on the specified line. You can use function
|
|
||||||
* dbg_LookupLine() to find out at which precise line the breakpoint was set.
|
|
||||||
*
|
|
||||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
|
||||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
|
||||||
* structure.
|
|
||||||
*/
|
|
||||||
int file, index;
|
|
||||||
ucell bottomaddr,topaddr;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
assert(address != NULL);
|
|
||||||
*address = 0;
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
for (file = 0; file < amxdbg->hdr->files; file++) {
|
|
||||||
/* find the (next) mathing instance of the file */
|
|
||||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
|
||||||
continue;
|
|
||||||
/* get address range for the current file */
|
|
||||||
bottomaddr = amxdbg->filetbl[file]->address;
|
|
||||||
topaddr = (file + 1 < amxdbg->hdr->files) ? amxdbg->filetbl[file+1]->address : (ucell)(cell)-1;
|
|
||||||
/* go to the starting address in the line table */
|
|
||||||
while (index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < bottomaddr)
|
|
||||||
index++;
|
|
||||||
/* browse until the line is found or until the top address is exceeded */
|
|
||||||
while (index < amxdbg->hdr->lines
|
|
||||||
&& amxdbg->linetbl[index].line < line
|
|
||||||
&& amxdbg->linetbl[index].address < topaddr)
|
|
||||||
index++;
|
|
||||||
if (index >= amxdbg->hdr->lines)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
if (amxdbg->linetbl[index].line >= line)
|
|
||||||
break;
|
|
||||||
/* if not found (and the line table is not yet exceeded) try the next
|
|
||||||
* instance of the same file (a file may appear twice in the file table)
|
|
||||||
*/
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
assert(index < amxdbg->hdr->lines);
|
|
||||||
*address = amxdbg->linetbl[index].address;
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address)
|
|
||||||
{
|
|
||||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
|
||||||
* the specified file). The address is moved up to the first "breakable" line
|
|
||||||
* in the function. You can use function dbg_LookupLine() to find out at which
|
|
||||||
* precise line the breakpoint was set.
|
|
||||||
*
|
|
||||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
|
||||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
|
||||||
* structure. The function name comparison is case sensitive too.
|
|
||||||
*/
|
|
||||||
int index, err;
|
|
||||||
const char *tgtfile;
|
|
||||||
ucell funcaddr;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(funcname != NULL);
|
|
||||||
assert(filename != NULL);
|
|
||||||
assert(address != NULL);
|
|
||||||
*address = 0;
|
|
||||||
|
|
||||||
index = 0;
|
|
||||||
for ( ;; ) {
|
|
||||||
/* find (next) matching function */
|
|
||||||
while (index < amxdbg->hdr->symbols
|
|
||||||
&& (amxdbg->symboltbl[index]->ident != iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, funcname) != 0))
|
|
||||||
index++;
|
|
||||||
if (index >= amxdbg->hdr->symbols)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
/* verify that this line falls in the appropriate file */
|
|
||||||
err = dbg_LookupFile(amxdbg, amxdbg->symboltbl[index]->address, &tgtfile);
|
|
||||||
if (err == AMX_ERR_NONE || strcmp(filename, tgtfile) == 0)
|
|
||||||
break;
|
|
||||||
index++; /* line is the wrong file, search further */
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
/* now find the first line in the function where we can "break" on */
|
|
||||||
assert(index < amxdbg->hdr->symbols);
|
|
||||||
funcaddr = amxdbg->symboltbl[index]->address;
|
|
||||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < funcaddr; index++)
|
|
||||||
/* nothing */;
|
|
||||||
|
|
||||||
if (index >= amxdbg->hdr->lines)
|
|
||||||
return AMX_ERR_NOTFOUND;
|
|
||||||
*address = amxdbg->linetbl[index].address;
|
|
||||||
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym)
|
|
||||||
{
|
|
||||||
ucell codestart,codeend;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(symname != NULL);
|
|
||||||
assert(sym != NULL);
|
|
||||||
*sym = NULL;
|
|
||||||
|
|
||||||
codestart = codeend = 0;
|
|
||||||
index = 0;
|
|
||||||
for ( ;; ) {
|
|
||||||
/* find (next) matching variable */
|
|
||||||
while (index < amxdbg->hdr->symbols
|
|
||||||
&& (amxdbg->symboltbl[index]->ident == iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, symname) != 0)
|
|
||||||
&& (amxdbg->symboltbl[index]->codestart > scopeaddr || amxdbg->symboltbl[index]->codeend < scopeaddr))
|
|
||||||
index++;
|
|
||||||
if (index >= amxdbg->hdr->symbols)
|
|
||||||
break;
|
|
||||||
/* check the range, keep a pointer to the symbol with the smallest range */
|
|
||||||
if (strcmp(amxdbg->symboltbl[index]->name, symname) == 0
|
|
||||||
&& (codestart == 0 && codeend == 0
|
|
||||||
|| amxdbg->symboltbl[index]->codestart >= codestart && amxdbg->symboltbl[index]->codeend <= codeend))
|
|
||||||
{
|
|
||||||
*sym = amxdbg->symboltbl[index];
|
|
||||||
codestart = amxdbg->symboltbl[index]->codestart;
|
|
||||||
codeend = amxdbg->symboltbl[index]->codeend;
|
|
||||||
} /* if */
|
|
||||||
index++;
|
|
||||||
} /* for */
|
|
||||||
|
|
||||||
return (*sym == NULL) ? AMX_ERR_NOTFOUND : AMX_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim)
|
|
||||||
{
|
|
||||||
/* retrieves a pointer to the array dimensions structures of an array symbol */
|
|
||||||
const char *ptr;
|
|
||||||
|
|
||||||
assert(amxdbg != NULL);
|
|
||||||
assert(sym != NULL);
|
|
||||||
assert(symdim != NULL);
|
|
||||||
*symdim = NULL;
|
|
||||||
|
|
||||||
if (sym->ident != iARRAY && sym->ident != iREFARRAY)
|
|
||||||
return AMX_ERR_PARAMS;
|
|
||||||
assert(sym->dim > 0); /* array must have at least one dimension */
|
|
||||||
|
|
||||||
/* find the end of the symbol name */
|
|
||||||
for (ptr = sym->name; *ptr != '\0'; ptr++)
|
|
||||||
/* nothing */;
|
|
||||||
*symdim = (AMX_DBG_SYMDIM *)(ptr + 1);/* skip '\0' too */
|
|
||||||
|
|
||||||
return AMX_ERR_NONE;
|
|
||||||
}
|
|
172
amxmodx/amxdbg.h
172
amxmodx/amxdbg.h
@ -1,172 +0,0 @@
|
|||||||
/* Abstract Machine for the Pawn compiler, debugger support
|
|
||||||
*
|
|
||||||
* This file contains extra definitions that are convenient for debugger
|
|
||||||
* support.
|
|
||||||
*
|
|
||||||
* Copyright (c) ITB CompuPhase, 2005
|
|
||||||
*
|
|
||||||
* This software is provided "as-is", without any express or implied warranty.
|
|
||||||
* In no event will the authors be held liable for any damages arising from
|
|
||||||
* the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* a product, an acknowledgment in the product documentation would be
|
|
||||||
* appreciated but is not required.
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
* misrepresented as being the original software.
|
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef AMXDBG_H_INCLUDED
|
|
||||||
#define AMXDBG_H_INCLUDED
|
|
||||||
|
|
||||||
#ifndef AMX_H_INCLUDED
|
|
||||||
#include "amx.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
|
||||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
|
||||||
*/
|
|
||||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
|
||||||
#define AMX_NO_ALIGN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __GNUC__
|
|
||||||
#define PACKED __attribute__((packed))
|
|
||||||
#else
|
|
||||||
#define PACKED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
|
||||||
#if defined LINUX || defined __FreeBSD__
|
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
|
||||||
#elif defined MACOS && defined __MWERKS__
|
|
||||||
#pragma options align=mac68k
|
|
||||||
#else
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
|
||||||
#if defined __TURBOC__
|
|
||||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_HDR {
|
|
||||||
int32_t size PACKED; /* size of the debug information chunk */
|
|
||||||
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
|
||||||
char file_version; /* file format version */
|
|
||||||
char amx_version; /* required version of the AMX */
|
|
||||||
int16_t flags PACKED; /* currently unused */
|
|
||||||
int16_t files PACKED; /* number of entries in the "file" table */
|
|
||||||
int16_t lines PACKED; /* number of entries in the "line" table */
|
|
||||||
int16_t symbols PACKED; /* number of entries in the "symbol" 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 states PACKED; /* number of entries in the "state" table */
|
|
||||||
} PACKED AMX_DBG_HDR;
|
|
||||||
#define AMX_DBG_MAGIC 0xf1ef
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_FILE {
|
|
||||||
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
|
||||||
} PACKED AMX_DBG_FILE;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_LINE {
|
|
||||||
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
|
||||||
int32_t line PACKED; /* line number */
|
|
||||||
} PACKED AMX_DBG_LINE;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMBOL {
|
|
||||||
ucell address PACKED; /* address in the data segment or relative to the frame */
|
|
||||||
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 codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
|
||||||
char ident; /* kind of symbol (function/variable) */
|
|
||||||
char vclass; /* class of symbol (global/local) */
|
|
||||||
int16_t dim PACKED; /* number of dimensions */
|
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
|
||||||
} PACKED AMX_DBG_SYMBOL;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMDIM {
|
|
||||||
int16_t tag PACKED; /* tag for the array dimension */
|
|
||||||
ucell size PACKED; /* size of the array dimension */
|
|
||||||
} PACKED AMX_DBG_SYMDIM;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_TAG {
|
|
||||||
int16_t tag PACKED; /* tag id */
|
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
|
||||||
} PACKED AMX_DBG_TAG;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_MACHINE {
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
ucell address PACKED; /* address of state variable */
|
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
|
||||||
} PACKED AMX_DBG_MACHINE;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_STATE {
|
|
||||||
int16_t state PACKED; /* state id */
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
const char name[1]; /* ASCII string, zero-terminated */
|
|
||||||
} PACKED AMX_DBG_STATE;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG {
|
|
||||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
|
||||||
AMX_DBG_FILE _FAR **filetbl PACKED;
|
|
||||||
AMX_DBG_LINE _FAR *linetbl PACKED;
|
|
||||||
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
|
|
||||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
|
||||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
|
||||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
|
||||||
} PACKED AMX_DBG;
|
|
||||||
|
|
||||||
#if !defined iVARIABLE
|
|
||||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
|
||||||
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
|
||||||
#define iARRAY 3
|
|
||||||
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
|
||||||
#define iFUNCTN 9
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
|
|
||||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr);
|
|
||||||
|
|
||||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
|
|
||||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
|
|
||||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
|
|
||||||
|
|
||||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
|
|
||||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
|
|
||||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
|
|
||||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
|
|
||||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
|
|
||||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
|
|
||||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
|
||||||
#if defined LINUX || defined __FreeBSD__
|
|
||||||
#pragma pack() /* reset default packing */
|
|
||||||
#elif defined MACOS && defined __MWERKS__
|
|
||||||
#pragma options align=reset
|
|
||||||
#else
|
|
||||||
#pragma pack(pop) /* reset previous packing */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* AMXDBG_H_INCLUDED */
|
|
@ -1,86 +0,0 @@
|
|||||||
; Definition of the AMX structure for assembler syntax (NASM)
|
|
||||||
|
|
||||||
struc amx_s
|
|
||||||
_base: resd 1
|
|
||||||
_dataseg: resd 1
|
|
||||||
_callback: resd 1
|
|
||||||
_debug: resd 1
|
|
||||||
_cip: resd 1
|
|
||||||
_frm: resd 1
|
|
||||||
_hea: resd 1
|
|
||||||
_hlw: resd 1
|
|
||||||
_stk: resd 1
|
|
||||||
_stp: resd 1
|
|
||||||
_flags: resd 1
|
|
||||||
_usertags: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
|
||||||
_userdata: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
|
||||||
_error: resd 1
|
|
||||||
_paramcount: resd 1
|
|
||||||
_pri: resd 1
|
|
||||||
_alt: resd 1
|
|
||||||
_reset_stk: resd 1
|
|
||||||
_reset_hea: resd 1
|
|
||||||
_syscall_d: resd 1
|
|
||||||
%ifdef JIT
|
|
||||||
; the two fields below are for the JIT; they do not exist in
|
|
||||||
; the non-JIT version of the abstract machine
|
|
||||||
_reloc_size: resd 1 ; memory block for relocations
|
|
||||||
_code_size: resd 1 ; memory size of the native code
|
|
||||||
%endif
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
struc amxhead_s
|
|
||||||
_size: resd 1 ; size of the "file"
|
|
||||||
_magic: resw 1 ; signature
|
|
||||||
_file_version: resb 1; file format version
|
|
||||||
_amx_version: resb 1 ; required version of the AMX
|
|
||||||
_h_flags: resw 1
|
|
||||||
_defsize: resw 1 ; size of one public/native function entry
|
|
||||||
_cod: resd 1 ; initial value of COD - code block
|
|
||||||
_dat: resd 1 ; initial value of DAT - data block
|
|
||||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
|
||||||
_h_stp: resd 1 ; initial value of STP - stack top
|
|
||||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
|
||||||
_publics: resd 1 ; offset to the "public functions" table
|
|
||||||
_natives: resd 1 ; offset to the "native functions" table
|
|
||||||
_libraries: resd 1 ; offset to the "library" table
|
|
||||||
_pubvars: resd 1 ; offset to the "public variables" table
|
|
||||||
_tags: resd 1 ; offset to the "public tagnames" table
|
|
||||||
_nametable: resd 1 ; offset to the name table, file version 7 only
|
|
||||||
endstruc
|
|
||||||
|
|
||||||
|
|
||||||
AMX_ERR_NONE EQU 0
|
|
||||||
AMX_ERR_EXIT EQU 1
|
|
||||||
AMX_ERR_ASSERT EQU 2
|
|
||||||
AMX_ERR_STACKERR EQU 3
|
|
||||||
AMX_ERR_BOUNDS EQU 4
|
|
||||||
AMX_ERR_MEMACCESS EQU 5
|
|
||||||
AMX_ERR_INVINSTR EQU 6
|
|
||||||
AMX_ERR_STACKLOW EQU 7
|
|
||||||
AMX_ERR_HEAPLOW EQU 8
|
|
||||||
AMX_ERR_CALLBACK EQU 9
|
|
||||||
AMX_ERR_NATIVE EQU 10
|
|
||||||
AMX_ERR_DIVIDE EQU 11 ; for catching divide errors
|
|
||||||
AMX_ERR_SLEEP EQU 12
|
|
||||||
|
|
||||||
AMX_ERR_MEMORY EQU 16
|
|
||||||
AMX_ERR_FORMAT EQU 17
|
|
||||||
AMX_ERR_VERSION EQU 18
|
|
||||||
AMX_ERR_NOTFOUND EQU 19
|
|
||||||
AMX_ERR_INDEX EQU 20
|
|
||||||
AMX_ERR_DEBUG EQU 21
|
|
||||||
AMX_ERR_INIT EQU 22
|
|
||||||
AMX_ERR_USERDATA EQU 23
|
|
||||||
AMX_ERR_INIT_JIT EQU 24
|
|
||||||
AMX_ERR_PARAMS EQU 25
|
|
||||||
AMX_ERR_DOMAIN EQU 26
|
|
||||||
AMX_ERR_GENERAL EQU 27
|
|
||||||
|
|
||||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
|
||||||
AMX_FLAG_COMPACT EQU 0004h
|
|
||||||
AMX_FLAG_BYTEOPC EQU 0008h
|
|
||||||
AMX_FLAG_NOCHECKS EQU 0010h
|
|
||||||
AMX_FLAG_BROWSE EQU 4000h
|
|
||||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
; AMXEXECN.ASM Abstract Machine for the "Pawn" language
|
; AMXEXECN.ASM Abstract Machine for the "Small" language
|
||||||
;
|
;
|
||||||
|
|
||||||
;Some notes:
|
;Some notes:
|
||||||
@ -25,7 +25,7 @@
|
|||||||
;
|
;
|
||||||
;Copyright and license of use, please read
|
;Copyright and license of use, please read
|
||||||
;-----------------------------------------
|
;-----------------------------------------
|
||||||
;The assembler implementation of the abstract machine for the Pawn language,
|
;The assembler implementation of the abstract machine for the Small language,
|
||||||
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
|
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
|
||||||
;
|
;
|
||||||
;Permission is hereby granted, without written agreement and without paid
|
;Permission is hereby granted, without written agreement and without paid
|
||||||
@ -56,10 +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
|
|
||||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
|
||||||
; 6 march 2004 by Thiadmer Riemersma
|
; 6 march 2004 by Thiadmer Riemersma
|
||||||
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
; Corrected a bug in OP_FILL, where a cell preceding the array would
|
||||||
; be overwritten (zero'ed out). This bug was brought to my attention
|
; be overwritten (zero'ed out). This bug was brought to my attention
|
||||||
@ -99,7 +95,84 @@
|
|||||||
%endif
|
%endif
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%include "amxdefn.asm"
|
|
||||||
|
; I could not get NASM's structure definition to work (it appears to confuse
|
||||||
|
; ENDSTRUC with "end segment"). So the definition below uses constants for
|
||||||
|
; the field offsets.
|
||||||
|
;amx_s STRUC
|
||||||
|
_base EQU 00h ;DD ?
|
||||||
|
_dataseg EQU 04h ;DD ?
|
||||||
|
_callback EQU 08h ;DD ?
|
||||||
|
_debug EQU 0ch ;DD ?
|
||||||
|
_cip EQU 10h ;DD ?
|
||||||
|
_frm EQU 14h ;DD ?
|
||||||
|
_hea EQU 18h ;DD ?
|
||||||
|
_hlw EQU 1ch ;DD ?
|
||||||
|
_stk EQU 20h ;DD ?
|
||||||
|
_stp EQU 24h ;DD ?
|
||||||
|
_flags EQU 28h ;DD ?
|
||||||
|
_curline EQU 2ch ;DD ?
|
||||||
|
_curfile EQU 30h ;DD ?
|
||||||
|
_dbgcode EQU 34h ;DD ?
|
||||||
|
_dbgaddr EQU 38h ;DD ?
|
||||||
|
_dbgparam EQU 3ch ;DD ?
|
||||||
|
_dbgname EQU 40h ;DD ?
|
||||||
|
_usertags EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||||
|
_userdata EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||||
|
_error EQU 64h ;DD ?
|
||||||
|
_pri EQU 68h ;DD ?
|
||||||
|
_alt EQU 6ch ;DD ?
|
||||||
|
_reset_stk EQU 70h ;DD ?
|
||||||
|
_reset_hea EQU 74h ;DD ?
|
||||||
|
_syscall_d EQU 78h ;DD ?
|
||||||
|
; the two fields below are for the JIT; they do not exist in
|
||||||
|
; the non-JIT version of the abstract machine
|
||||||
|
; _reloc_size EQU 7ch ;DD ? ; memory block for relocations
|
||||||
|
; _code_size EQU 80h ;DD ? ; memory size of the native code
|
||||||
|
;amx_s ENDS
|
||||||
|
|
||||||
|
|
||||||
|
AMX_ERR_NONE EQU 0
|
||||||
|
AMX_ERR_EXIT EQU 1
|
||||||
|
AMX_ERR_ASSERT EQU 2
|
||||||
|
AMX_ERR_STACKERR EQU 3
|
||||||
|
AMX_ERR_BOUNDS EQU 4
|
||||||
|
AMX_ERR_MEMACCESS EQU 5
|
||||||
|
AMX_ERR_INVINSTR EQU 6
|
||||||
|
AMX_ERR_STACKLOW EQU 7
|
||||||
|
AMX_ERR_HEAPLOW EQU 8
|
||||||
|
AMX_ERR_CALLBACK EQU 9
|
||||||
|
AMX_ERR_NATIVE EQU 10
|
||||||
|
AMX_ERR_DIVIDE EQU 11 ; MP: added for catching divide errors
|
||||||
|
AMX_ERR_SLEEP EQU 12 ; (TR)
|
||||||
|
|
||||||
|
AMX_ERR_MEMORY EQU 16
|
||||||
|
AMX_ERR_FORMAT EQU 17
|
||||||
|
AMX_ERR_VERSION EQU 18
|
||||||
|
AMX_ERR_NOTFOUND EQU 19
|
||||||
|
AMX_ERR_INDEX EQU 20
|
||||||
|
AMX_ERR_DEBUG EQU 21
|
||||||
|
AMX_ERR_INIT EQU 22
|
||||||
|
AMX_ERR_USERDATA EQU 23
|
||||||
|
AMX_ERR_INIT_JIT EQU 24
|
||||||
|
AMX_ERR_PARAMS EQU 25
|
||||||
|
AMX_ERR_DOMAIN EQU 26
|
||||||
|
|
||||||
|
DBG_INIT EQU 0
|
||||||
|
DBG_FILE EQU 1
|
||||||
|
DBG_LINE EQU 2
|
||||||
|
DBG_SYMBOL EQU 3
|
||||||
|
DBG_CLRSYM EQU 4
|
||||||
|
DBG_CALL EQU 5
|
||||||
|
DBG_RETURN EQU 6
|
||||||
|
DBG_TERMINATE EQU 7
|
||||||
|
DBG_SRANGE EQU 8 ; (TR)
|
||||||
|
DBG_SYMTAG EQU 9 ; (TR)
|
||||||
|
|
||||||
|
AMX_FLAG_CHAR16 EQU 0001h ; characters are 16-bit
|
||||||
|
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||||
|
AMX_FLAG_BROWSE EQU 4000h
|
||||||
|
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||||
|
|
||||||
;#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
|
||||||
@ -131,28 +204,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]
|
||||||
@ -600,6 +651,29 @@ OP_POP_ALT:
|
|||||||
|
|
||||||
;good
|
;good
|
||||||
OP_STACK:
|
OP_STACK:
|
||||||
|
mov edx,ecx
|
||||||
|
add ecx,[esi+4]
|
||||||
|
_CHKMARGIN
|
||||||
|
_CHKSTACK
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||||
|
jz short op_stk_goon
|
||||||
|
; update several structure fields and call the debug hook
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||||
|
mov [ebp+_stk],ecx
|
||||||
|
push eax
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax ; pass parameter via the stack
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop eax
|
||||||
|
op_stk_goon:
|
||||||
|
add esi,8
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
OP_STACK_nodebug:
|
||||||
mov edx,ecx
|
mov edx,ecx
|
||||||
add ecx,[esi+4]
|
add ecx,[esi+4]
|
||||||
_CHKMARGIN
|
_CHKMARGIN
|
||||||
@ -629,6 +703,35 @@ OP_PROC:
|
|||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_RET:
|
OP_RET:
|
||||||
|
_POP ebx
|
||||||
|
_POP esi
|
||||||
|
cmp esi,code ; verify ESI>=code
|
||||||
|
jb err_memaccess
|
||||||
|
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||||
|
jae err_memaccess
|
||||||
|
mov frm,ebx
|
||||||
|
add ebx,edi
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_ret_goon
|
||||||
|
; update several structure fields and call the debug hook
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||||
|
mov [ebp+_dbgparam],eax
|
||||||
|
push eax
|
||||||
|
mov [ebp+_stk],ecx ; store STK
|
||||||
|
mov eax,hea
|
||||||
|
mov [ebp+_hea],eax ; store HEA
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop eax
|
||||||
|
op_ret_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
OP_RET_nodebug:
|
||||||
_POP ebx
|
_POP ebx
|
||||||
_POP esi
|
_POP esi
|
||||||
cmp esi,code ; verify ESI>=code
|
cmp esi,code ; verify ESI>=code
|
||||||
@ -649,17 +752,107 @@ OP_RETN:
|
|||||||
jae err_memaccess
|
jae err_memaccess
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
add ebx,edi
|
add ebx,edi
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_retn_goon
|
||||||
|
; update several structure fields and call the debug hook
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_RETURN
|
||||||
|
mov [ebp+_dbgparam],eax
|
||||||
|
push eax
|
||||||
|
mov [ebp+_stk],ecx ; store STK
|
||||||
|
mov eax,hea
|
||||||
|
mov [ebp+_hea],eax ; store HEA
|
||||||
|
mov eax,ebp ; parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
; also send the DBG_CLRSYM code
|
||||||
|
mov eax,[edi+ecx]
|
||||||
|
lea ecx,[ecx+eax+4]
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
|
||||||
|
mov [ebp+_stk],ecx
|
||||||
|
mov eax,ebp ; parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop eax
|
||||||
|
; ECX already adjusted
|
||||||
|
GO_ON
|
||||||
|
op_retn_goon:
|
||||||
mov ebp,[edi+ecx]
|
mov ebp,[edi+ecx]
|
||||||
lea ecx,[ecx+ebp+4]
|
lea ecx,[ecx+ebp+4]
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
OP_RETN_nodebug:
|
||||||
|
_POP ebx
|
||||||
|
_POP esi
|
||||||
|
cmp esi,code ; verify ESI>=code
|
||||||
|
jb err_memaccess
|
||||||
|
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
|
||||||
|
jae err_memaccess
|
||||||
|
mov frm,ebx
|
||||||
|
mov ebp,[edi+ecx]
|
||||||
|
add ebx,edi
|
||||||
|
lea ecx,[ecx+ebp+4]
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
;good
|
||||||
OP_CALL:
|
OP_CALL:
|
||||||
|
lea ebp,[esi+8]
|
||||||
|
mov esi,[esi+4]
|
||||||
|
_PUSH ebp
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_call_goon
|
||||||
|
; update several structure fields and call the debug hook
|
||||||
|
push eax
|
||||||
|
mov eax,[esp+24] ; this is "code", but ESP moved
|
||||||
|
mov [ebp+_dbgaddr],esi
|
||||||
|
sub [ebp+_dbgaddr],eax ; dbgaddr = cip - code
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop eax
|
||||||
|
op_call_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
OP_CALL_nodebug:
|
||||||
lea ebp,[esi+8]
|
lea ebp,[esi+8]
|
||||||
mov esi,[esi+4]
|
mov esi,[esi+4]
|
||||||
_PUSH ebp
|
_PUSH ebp
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_CALL_PRI:
|
OP_CALL_PRI:
|
||||||
|
lea ebp,[esi+4]
|
||||||
|
mov esi,eax
|
||||||
|
add esi,code ; cip = PRI + code
|
||||||
|
_PUSH ebp
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_calli_goon
|
||||||
|
; update several structure fields and call the debug hook
|
||||||
|
mov [ebp+_dbgaddr],eax ; dbgaddr = PRI (== cip - code)
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_CALL
|
||||||
|
push eax
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop eax
|
||||||
|
op_calli_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
OP_CALL_PRI_nodebug:
|
||||||
lea ebp,[esi+4]
|
lea ebp,[esi+4]
|
||||||
mov esi,eax
|
mov esi,eax
|
||||||
add esi,code ; cip = PRI + code
|
add esi,code ; cip = PRI + code
|
||||||
@ -727,7 +920,7 @@ OP_JGRTR:
|
|||||||
|
|
||||||
OP_JGEQ:
|
OP_JGEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jae short jump_taken ; unsigned comparison
|
jae short jump_taken ; unsigned comparison
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
@ -740,19 +933,19 @@ OP_JSLESS:
|
|||||||
;good
|
;good
|
||||||
OP_JSLEQ:
|
OP_JSLEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jle near jump_taken
|
jle short jump_taken
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_JSGRTR:
|
OP_JSGRTR:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jg near jump_taken
|
jg short jump_taken
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
OP_JSGEQ:
|
OP_JSGEQ:
|
||||||
cmp eax,edx
|
cmp eax,edx
|
||||||
jge near jump_taken ; signed comparison
|
jge near jump_taken ; signed comparison
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
@ -1149,11 +1342,12 @@ OP_CMPS:
|
|||||||
_VERIFYADDRESS eax ; PRI
|
_VERIFYADDRESS eax ; PRI
|
||||||
_VERIFYADDRESS edx ; ALT
|
_VERIFYADDRESS edx ; ALT
|
||||||
mov ebp,eax
|
mov ebp,eax
|
||||||
add ebp,[esi+4] ; size in bytes
|
add ebp,[esi+4]
|
||||||
dec ebp ; EBP = PRI + size - 1
|
dec ebp
|
||||||
_VERIFYADDRESS ebp ; PRI + size - 1
|
_VERIFYADDRESS ebp ; PRI + size - 1
|
||||||
sub ebp,eax ; EBP = size - 1
|
mov ebp,edx
|
||||||
add ebp,edx ; EBP = ALT + size - 1
|
add ebp,[esi+4]
|
||||||
|
dec ebp
|
||||||
_VERIFYADDRESS ebp ; ALT + size - 1
|
_VERIFYADDRESS ebp ; ALT + size - 1
|
||||||
|
|
||||||
push ecx
|
push ecx
|
||||||
@ -1220,7 +1414,21 @@ 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
|
; optionally call the debug hook
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short halt_goon
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_TERMINATE
|
||||||
|
mov [ebp+_dbgaddr],eax
|
||||||
|
mov [ebp+_dbgparam],ebx
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
halt_goon:
|
||||||
|
mov eax,ebx ; return the parameter of the HALT opcode
|
||||||
|
jmp _return
|
||||||
|
|
||||||
|
|
||||||
OP_BOUNDS:
|
OP_BOUNDS:
|
||||||
@ -1244,7 +1452,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 +1482,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 +1524,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
|
||||||
@ -1333,21 +1541,159 @@ OP_FILE:
|
|||||||
|
|
||||||
OP_LINE:
|
OP_LINE:
|
||||||
add esi,12
|
add esi,12
|
||||||
|
mov ebp,amx
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
mov eax,[esi-8] ; get curline
|
||||||
|
mov edx,[esi-4] ; get curfile
|
||||||
|
mov [ebp+_curline],eax
|
||||||
|
mov [ebp+_curfile],edx
|
||||||
|
pop edx
|
||||||
|
pop eax
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short line_goon
|
||||||
|
; update several structure fields
|
||||||
|
mov [ebp+_pri],eax
|
||||||
|
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
||||||
|
mov eax,frm
|
||||||
|
mov edx,hea
|
||||||
|
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
||||||
|
mov [ebp+_hea],edx
|
||||||
|
mov [ebp+_stk],ecx
|
||||||
|
mov eax,esi
|
||||||
|
sub eax,code ; EAX = CIP (relative to start of code segment)
|
||||||
|
mov [ebp+_cip],eax
|
||||||
|
; call the debugger hook
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
cmp eax,AMX_ERR_NONE
|
||||||
|
je short line_noabort ; continue running
|
||||||
|
mov [ebp+_dbgcode],eax ; save EAX (error code) before restoring all regs
|
||||||
|
_RESTOREREGS ; abort run, but restore stack first
|
||||||
|
mov eax,[ebp+_dbgcode] ; get error code in EAX back again
|
||||||
|
jmp _return ; return error code
|
||||||
|
line_noabort:
|
||||||
|
_RESTOREREGS
|
||||||
|
mov eax,[ebp+_pri] ; restore PRI and ALT
|
||||||
|
mov edx,[ebp+_alt]
|
||||||
|
line_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
|
OP_LINE_nodebug:
|
||||||
|
add esi,12
|
||||||
|
mov ebp,amx
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
mov eax,[esi-8] ; get curline
|
||||||
|
mov edx,[esi-4] ; get curfile
|
||||||
|
mov [ebp+_curline],eax
|
||||||
|
mov [ebp+_curfile],edx
|
||||||
|
pop edx
|
||||||
|
pop eax
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SYMBOL:
|
OP_SYMBOL:
|
||||||
|
mov ebp,amx
|
||||||
|
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
|
||||||
|
jz short op_symbol_goon
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
mov eax,[esi+8] ; address
|
||||||
|
mov edx,[esi+12] ; flags
|
||||||
|
mov [ebp+_dbgaddr],eax
|
||||||
|
mov [ebp+_dbgparam],edx
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_SYMBOL
|
||||||
|
mov eax,esi
|
||||||
|
add eax,16 ; start of symbol name
|
||||||
|
mov [ebp+_dbgname],eax
|
||||||
|
mov edx,[esp+8] ; this is FRM, but offset by two PUSH'es
|
||||||
|
mov [ebp+_frm],edx
|
||||||
|
mov eax,ebp ; parameter of the debugger hook
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debugger hook
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop edx
|
||||||
|
pop eax
|
||||||
|
op_symbol_goon:
|
||||||
|
add esi,[esi+4]
|
||||||
|
add esi,8 ; skip "fixed" part
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
|
OP_SYMBOL_nodebug:
|
||||||
add esi,[esi+4]
|
add esi,[esi+4]
|
||||||
add esi,8 ; skip "fixed" part
|
add esi,8 ; skip "fixed" part
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SRANGE:
|
OP_SRANGE:
|
||||||
|
mov ebp,amx
|
||||||
|
add esi,12
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_srange_goon
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
mov eax,[esi-8] ; get dimensions
|
||||||
|
mov edx,[esi-4] ; get size
|
||||||
|
mov [ebp+_dbgaddr],eax
|
||||||
|
mov [ebp+_dbgparam],edx
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||||
|
mov edx,frm
|
||||||
|
mov [ebp+_frm],edx
|
||||||
|
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||||
|
; call the debugger hook
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop edx
|
||||||
|
pop eax
|
||||||
|
op_srange_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
|
OP_SRANGE_nodebug:
|
||||||
add esi,12
|
add esi,12
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
OP_SYMTAG:
|
OP_SYMTAG:
|
||||||
|
mov ebp,amx
|
||||||
|
add esi,8
|
||||||
|
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
|
||||||
|
jz short op_symtag_goon
|
||||||
|
mov ebp,amx
|
||||||
|
push eax
|
||||||
|
push edx
|
||||||
|
mov eax,[esi-4] ; get tag
|
||||||
|
mov edx,frm
|
||||||
|
mov DWORD [ebp+_dbgcode],DBG_SRANGE
|
||||||
|
mov [ebp+_dbgparam],eax
|
||||||
|
mov [ebp+_frm],edx
|
||||||
|
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
|
||||||
|
; call the debugger hook
|
||||||
|
mov eax,ebp ; 1st parm: amx
|
||||||
|
_SAVEREGS
|
||||||
|
push eax
|
||||||
|
call [ebp+_debug] ; call debug function
|
||||||
|
_DROPARGS 4 ; remove arguments from stack
|
||||||
|
_RESTOREREGS
|
||||||
|
pop edx
|
||||||
|
pop eax
|
||||||
|
op_symtag_goon:
|
||||||
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
|
OP_SYMTAG_nodebug: ; (TR)
|
||||||
add esi,8
|
add esi,8
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
@ -1405,179 +1751,47 @@ OP_PUSHADDR:
|
|||||||
|
|
||||||
|
|
||||||
OP_NOP:
|
OP_NOP:
|
||||||
add esi,4
|
|
||||||
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:
|
|
||||||
mov ebp,amx ; get amx into ebp
|
|
||||||
add esi,4
|
|
||||||
cmp DWORD [ebp+_debug], 0
|
|
||||||
jnz break_calldebug
|
|
||||||
GO_ON ; debug hook not active, ignore
|
|
||||||
|
|
||||||
break_calldebug:
|
|
||||||
; store the status in the AMX (FRM, STK, HEA, CIP, and PRI + ALT)
|
|
||||||
mov [ebp+_pri],eax
|
|
||||||
mov [ebp+_alt],edx ; EAX and EDX are now free to use
|
|
||||||
mov eax,frm
|
|
||||||
mov edx,hea
|
|
||||||
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
|
|
||||||
mov [ebp+_hea],edx
|
|
||||||
mov [ebp+_stk],ecx
|
|
||||||
mov eax,esi
|
|
||||||
sub eax,code ; EAX = CIP (relative to start of code segment)
|
|
||||||
mov [ebp+_cip],eax
|
|
||||||
; call the debug hook
|
|
||||||
mov eax,ebp ; 1st parm: amx
|
|
||||||
_SAVEREGS
|
|
||||||
push eax
|
|
||||||
call [ebp+_debug] ; call debug function
|
|
||||||
_DROPARGS 4 ; remove arguments from stack
|
|
||||||
cmp eax,AMX_ERR_NONE
|
|
||||||
je short break_noabort; continue running
|
|
||||||
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
|
|
||||||
_RESTOREREGS ; abort run, but restore stack first
|
|
||||||
mov eax,[ebp+_error] ; get error code in EAX back again
|
|
||||||
_FASTABORT
|
|
||||||
break_noabort:
|
|
||||||
_RESTOREREGS
|
|
||||||
mov eax,[ebp+_pri] ; restore PRI and ALT
|
|
||||||
mov edx,[ebp+_alt]
|
|
||||||
GO_ON
|
GO_ON
|
||||||
|
|
||||||
|
|
||||||
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 paraneters, 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 +1819,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:
|
||||||
@ -1753,11 +1959,144 @@ _amx_opcodelist DD OP_INVALID
|
|||||||
DD OP_NOP
|
DD OP_NOP
|
||||||
DD OP_SYSREQ_D
|
DD OP_SYSREQ_D
|
||||||
DD OP_SYMTAG
|
DD OP_SYMTAG
|
||||||
DD OP_BREAK
|
|
||||||
DD OP_FLOAT_MUL
|
GLOBAL amx_opcodelist_nodebug
|
||||||
DD OP_FLOAT_DIV
|
GLOBAL _amx_opcodelist_nodebug
|
||||||
DD OP_FLOAT_ADD
|
amx_opcodelist_nodebug:
|
||||||
DD OP_FLOAT_SUB
|
_amx_opcodelist_nodebug DD OP_INVALID
|
||||||
DD OP_FLOAT_TO
|
DD OP_LOAD_PRI
|
||||||
DD OP_FLOAT_ROUND
|
DD OP_LOAD_ALT
|
||||||
DD OP_FLOAT_CMP
|
DD OP_LOAD_S_PRI
|
||||||
|
DD OP_LOAD_S_ALT
|
||||||
|
DD OP_LREF_PRI
|
||||||
|
DD OP_LREF_ALT
|
||||||
|
DD OP_LREF_S_PRI
|
||||||
|
DD OP_LREF_S_ALT
|
||||||
|
DD OP_LOAD_I
|
||||||
|
DD OP_LODB_I
|
||||||
|
DD OP_CONST_PRI
|
||||||
|
DD OP_CONST_ALT
|
||||||
|
DD OP_ADDR_PRI
|
||||||
|
DD OP_ADDR_ALT
|
||||||
|
DD OP_STOR_PRI
|
||||||
|
DD OP_STOR_ALT
|
||||||
|
DD OP_STOR_S_PRI
|
||||||
|
DD OP_STOR_S_ALT
|
||||||
|
DD OP_SREF_PRI
|
||||||
|
DD OP_SREF_ALT
|
||||||
|
DD OP_SREF_S_PRI
|
||||||
|
DD OP_SREF_S_ALT
|
||||||
|
DD OP_STOR_I
|
||||||
|
DD OP_STRB_I
|
||||||
|
DD OP_LIDX
|
||||||
|
DD OP_LIDX_B
|
||||||
|
DD OP_IDXADDR
|
||||||
|
DD OP_IDXADDR_B
|
||||||
|
DD OP_ALIGN_PRI
|
||||||
|
DD OP_ALIGN_ALT
|
||||||
|
DD OP_LCTRL
|
||||||
|
DD OP_SCTRL
|
||||||
|
DD OP_MOVE_PRI
|
||||||
|
DD OP_MOVE_ALT
|
||||||
|
DD OP_XCHG
|
||||||
|
DD OP_PUSH_PRI
|
||||||
|
DD OP_PUSH_ALT
|
||||||
|
DD OP_PUSH_R_PRI
|
||||||
|
DD OP_PUSH_C
|
||||||
|
DD OP_PUSH
|
||||||
|
DD OP_PUSH_S
|
||||||
|
DD OP_POP_PRI
|
||||||
|
DD OP_POP_ALT
|
||||||
|
DD OP_STACK_nodebug
|
||||||
|
DD OP_HEAP
|
||||||
|
DD OP_PROC
|
||||||
|
DD OP_RET_nodebug
|
||||||
|
DD OP_RETN_nodebug
|
||||||
|
DD OP_CALL_nodebug
|
||||||
|
DD OP_CALL_PRI_nodebug
|
||||||
|
DD OP_JUMP
|
||||||
|
DD OP_JREL
|
||||||
|
DD OP_JZER
|
||||||
|
DD OP_JNZ
|
||||||
|
DD OP_JEQ
|
||||||
|
DD OP_JNEQ
|
||||||
|
DD OP_JLESS
|
||||||
|
DD OP_JLEQ
|
||||||
|
DD OP_JGRTR
|
||||||
|
DD OP_JGEQ
|
||||||
|
DD OP_JSLESS
|
||||||
|
DD OP_JSLEQ
|
||||||
|
DD OP_JSGRTR
|
||||||
|
DD OP_JSGEQ
|
||||||
|
DD OP_SHL
|
||||||
|
DD OP_SHR
|
||||||
|
DD OP_SSHR
|
||||||
|
DD OP_SHL_C_PRI
|
||||||
|
DD OP_SHL_C_ALT
|
||||||
|
DD OP_SHR_C_PRI
|
||||||
|
DD OP_SHR_C_ALT
|
||||||
|
DD OP_SMUL
|
||||||
|
DD OP_SDIV
|
||||||
|
DD OP_SDIV_ALT
|
||||||
|
DD OP_UMUL
|
||||||
|
DD OP_UDIV
|
||||||
|
DD OP_UDIV_ALT
|
||||||
|
DD OP_ADD
|
||||||
|
DD OP_SUB
|
||||||
|
DD OP_SUB_ALT
|
||||||
|
DD OP_AND
|
||||||
|
DD OP_OR
|
||||||
|
DD OP_XOR
|
||||||
|
DD OP_NOT
|
||||||
|
DD OP_NEG
|
||||||
|
DD OP_INVERT
|
||||||
|
DD OP_ADD_C
|
||||||
|
DD OP_SMUL_C
|
||||||
|
DD OP_ZERO_PRI
|
||||||
|
DD OP_ZERO_ALT
|
||||||
|
DD OP_ZERO
|
||||||
|
DD OP_ZERO_S
|
||||||
|
DD OP_SIGN_PRI
|
||||||
|
DD OP_SIGN_ALT
|
||||||
|
DD OP_EQ
|
||||||
|
DD OP_NEQ
|
||||||
|
DD OP_LESS
|
||||||
|
DD OP_LEQ
|
||||||
|
DD OP_GRTR
|
||||||
|
DD OP_GEQ
|
||||||
|
DD OP_SLESS
|
||||||
|
DD OP_SLEQ
|
||||||
|
DD OP_SGRTR
|
||||||
|
DD OP_SGEQ
|
||||||
|
DD OP_EQ_C_PRI
|
||||||
|
DD OP_EQ_C_ALT
|
||||||
|
DD OP_INC_PRI
|
||||||
|
DD OP_INC_ALT
|
||||||
|
DD OP_INC
|
||||||
|
DD OP_INC_S
|
||||||
|
DD OP_INC_I
|
||||||
|
DD OP_DEC_PRI
|
||||||
|
DD OP_DEC_ALT
|
||||||
|
DD OP_DEC
|
||||||
|
DD OP_DEC_S
|
||||||
|
DD OP_DEC_I
|
||||||
|
DD OP_MOVS
|
||||||
|
DD OP_CMPS
|
||||||
|
DD OP_FILL
|
||||||
|
DD OP_HALT
|
||||||
|
DD OP_BOUNDS
|
||||||
|
DD OP_SYSREQ_PRI
|
||||||
|
DD OP_SYSREQ_C
|
||||||
|
DD OP_FILE
|
||||||
|
DD OP_LINE_nodebug
|
||||||
|
DD OP_SYMBOL_nodebug
|
||||||
|
DD OP_SRANGE_nodebug
|
||||||
|
DD OP_JUMP_PRI
|
||||||
|
DD OP_SWITCH
|
||||||
|
DD OP_CASETBL
|
||||||
|
DD OP_SWAP_PRI
|
||||||
|
DD OP_SWAP_ALT
|
||||||
|
DD OP_PUSHADDR
|
||||||
|
DD OP_NOP
|
||||||
|
DD OP_SYSREQ_D
|
||||||
|
DD OP_SYMTAG_nodebug
|
||||||
|
@ -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
|
|
5465
amxmodx/amxmodx.cpp
5465
amxmodx/amxmodx.cpp
File diff suppressed because it is too large
Load Diff
@ -32,23 +32,13 @@
|
|||||||
#ifndef AMXMODX_H
|
#ifndef AMXMODX_H
|
||||||
#define AMXMODX_H
|
#define AMXMODX_H
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "sclinux.h"
|
|
||||||
#endif
|
|
||||||
#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>
|
||||||
|
|
||||||
#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"
|
||||||
@ -65,61 +55,39 @@
|
|||||||
#include "CLogEvent.h"
|
#include "CLogEvent.h"
|
||||||
#include "CForward.h"
|
#include "CForward.h"
|
||||||
#include "CCmd.h"
|
#include "CCmd.h"
|
||||||
|
#include "CMenu.h"
|
||||||
#include "CEvent.h"
|
#include "CEvent.h"
|
||||||
#include "CLang.h"
|
#include "CLang.h"
|
||||||
#include "fakemeta.h"
|
#include "fakemeta.h"
|
||||||
#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 "0.2"
|
||||||
|
|
||||||
|
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[];
|
|
||||||
extern AMX_NATIVE_INFO g_DataStructNatives[];
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
#define PATH_SEP_CHAR '\\'
|
|
||||||
#define ALT_SEP_CHAR '/'
|
|
||||||
#else
|
|
||||||
#define PATH_SEP_CHAR '/'
|
|
||||||
#define ALT_SEP_CHAR '\\'
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GETPLAYERAUTHID
|
#ifndef GETPLAYERAUTHID
|
||||||
@ -135,35 +103,31 @@ extern AMX_NATIVE_INFO g_DataStructNatives[];
|
|||||||
|
|
||||||
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, ...);
|
|
||||||
|
|
||||||
|
|
||||||
#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 CLog g_log;
|
extern CLog g_log;
|
||||||
@ -176,18 +140,18 @@ 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;
|
||||||
extern LogEventsMngr g_logevents;
|
extern LogEventsMngr g_logevents;
|
||||||
|
extern MenuMngr g_menucmds;
|
||||||
extern CLangMngr g_langMngr;
|
extern CLangMngr g_langMngr;
|
||||||
extern String g_log_dir;
|
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;
|
||||||
@ -202,7 +166,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;
|
||||||
@ -251,16 +214,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);
|
||||||
void detachModules();
|
void detachModules();
|
||||||
void detachReloadModules();
|
void detachReloadModules();
|
||||||
|
void attachModules();
|
||||||
#ifdef FAKEMETA
|
void attachMetaModModules(PLUG_LOADTIME now, const char* filename);
|
||||||
void attachModules();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Count modules
|
// Count modules
|
||||||
enum CountModulesMode
|
enum CountModulesMode
|
||||||
@ -272,49 +233,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);
|
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
||||||
char* build_pathname(char *fmt, ...);
|
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
char* build_pathname(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, ...);
|
|
||||||
|
|
||||||
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
|
||||||
|
extern CQueue<String> CurModuleList;
|
||||||
void Module_CacheFunctions();
|
|
||||||
void Module_UncacheFunctions();
|
|
||||||
|
|
||||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||||
|
|
||||||
@ -332,27 +285,7 @@ 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;
|
|
||||||
|
|
||||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
|
||||||
|
|
||||||
#define MM_CVAR2_VERS 13
|
|
||||||
|
|
||||||
struct func_s
|
|
||||||
{
|
|
||||||
void *pfn;
|
|
||||||
const char *desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum AdminProperty
|
|
||||||
{
|
|
||||||
Admin_Auth = 0,
|
|
||||||
Admin_Password,
|
|
||||||
Admin_Access,
|
|
||||||
Admin_Flags
|
|
||||||
};
|
|
||||||
|
|
||||||
extern enginefuncs_t *g_pEngTable;
|
|
||||||
|
|
||||||
|
extern CFakeMeta g_FakeMeta;
|
||||||
#endif // AMXMODX_H
|
#endif // AMXMODX_H
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
// 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"
|
||||||
@ -54,7 +52,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__
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
* 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
|
||||||
@ -35,25 +36,28 @@
|
|||||||
/**********************
|
/**********************
|
||||||
****** 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
|
||||||
|
|
||||||
|
typedef char mint8_t;
|
||||||
|
typedef int16_t mint16_t;
|
||||||
|
typedef int32_t mint32_t;
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
@ -72,9 +76,6 @@ struct TableEntry
|
|||||||
|
|
||||||
CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||||
{
|
{
|
||||||
m_Bh.plugins = NULL;
|
|
||||||
m_AmxxFile = false;
|
|
||||||
|
|
||||||
if (!filename)
|
if (!filename)
|
||||||
{
|
{
|
||||||
m_Status = Err_InvalidParam;
|
m_Status = Err_InvalidParam;
|
||||||
@ -83,8 +84,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,71 +96,42 @@ 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 != 0x414D5842)
|
||||||
if (magic == 0x524C4542)
|
|
||||||
{
|
{
|
||||||
|
// check for old file
|
||||||
|
AMX_HEADER hdr;
|
||||||
|
rewind(m_pFile);
|
||||||
|
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||||
|
amx_Align16(&hdr.magic);
|
||||||
|
if (hdr.magic == AMX_MAGIC)
|
||||||
|
{
|
||||||
|
if (cellsize != 4)
|
||||||
|
{
|
||||||
|
m_Status = Err_SectionNotFound;
|
||||||
|
fclose(m_pFile);
|
||||||
|
m_pFile = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_OldFile = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no known file format
|
||||||
|
m_Status = Err_FileInvalid;
|
||||||
|
fclose(m_pFile);
|
||||||
|
m_pFile = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else 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 {
|
||||||
else if (magic == MAGIC_HEADER2)
|
|
||||||
{
|
|
||||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
|
||||||
|
|
||||||
if (m_Bh.version > MAGIC_VERSION)
|
|
||||||
{
|
|
||||||
m_Status = Err_OldFile;
|
|
||||||
fclose(m_pFile);
|
|
||||||
m_pFile = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_AmxxFile = true;
|
|
||||||
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
|
||||||
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
|
||||||
PluginEntry *pe;
|
|
||||||
m_SectionHdrOffset = 0;
|
|
||||||
m_Entry = -1;
|
|
||||||
|
|
||||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
|
||||||
{
|
|
||||||
pe = &(m_Bh.plugins[i]);
|
|
||||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
|
||||||
DATAREAD(&pe->disksize, sizeof(int32_t), 1);
|
|
||||||
DATAREAD(&pe->imagesize, sizeof(int32_t), 1);
|
|
||||||
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
|
||||||
DATAREAD(&pe->offs, sizeof(int32_t), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
|
||||||
{
|
|
||||||
pe = &(m_Bh.plugins[i]);
|
|
||||||
|
|
||||||
if (pe->cellsize == m_CellSize)
|
|
||||||
{
|
|
||||||
m_Entry = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Entry == -1)
|
|
||||||
{
|
|
||||||
m_Status = Err_SectionNotFound;
|
|
||||||
fclose(m_pFile);
|
|
||||||
m_pFile = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pe = &(m_Bh.plugins[m_Entry]);
|
|
||||||
m_SectionLength = pe->disksize;
|
|
||||||
}
|
|
||||||
else if (magic == MAGIC_HEADER)
|
|
||||||
{
|
|
||||||
// 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 +140,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 +149,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,45 +158,18 @@ 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;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// check for old file
|
|
||||||
AMX_HEADER hdr;
|
|
||||||
rewind(m_pFile);
|
|
||||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
|
||||||
amx_Align16(&hdr.magic);
|
|
||||||
|
|
||||||
if (hdr.magic == AMX_MAGIC)
|
|
||||||
{
|
|
||||||
if (cellsize != 4)
|
|
||||||
{
|
|
||||||
m_Status = Err_SectionNotFound;
|
|
||||||
fclose(m_pFile);
|
|
||||||
m_pFile = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_OldFile = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// no known file format
|
|
||||||
m_Status = Err_FileInvalid;
|
|
||||||
fclose(m_pFile);
|
|
||||||
m_pFile = NULL;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,12 +180,6 @@ CAmxxReader::~CAmxxReader()
|
|||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Bh.plugins)
|
|
||||||
{
|
|
||||||
delete [] m_Bh.plugins;
|
|
||||||
m_Bh.plugins = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmxxReader::Error CAmxxReader::GetStatus()
|
CAmxxReader::Error CAmxxReader::GetStatus()
|
||||||
@ -268,6 +205,7 @@ size_t CAmxxReader::GetBufferSize()
|
|||||||
if (!m_pFile)
|
if (!m_pFile)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
long save = ftell(m_pFile);
|
long save = ftell(m_pFile);
|
||||||
|
|
||||||
if (m_OldFile)
|
if (m_OldFile)
|
||||||
@ -276,31 +214,20 @@ 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)
|
|
||||||
{
|
|
||||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
|
||||||
|
|
||||||
if (pe->imagesize > pe->memsize)
|
|
||||||
return pe->imagesize + 1;
|
|
||||||
|
|
||||||
return pe->memsize + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||||
|
|
||||||
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,51 +251,31 @@ 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)
|
|
||||||
|
// new file type: go to the section table entry
|
||||||
|
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||||
|
// go to the offset
|
||||||
|
TableEntry entry;
|
||||||
|
DATAREAD(&entry, sizeof(entry), 1);
|
||||||
|
fseek(m_pFile, entry.offset, SEEK_SET);
|
||||||
|
// AMXXLOG_Log("|||| Offset needed: %d At: %d", entry.offset, ftell(m_pFile));
|
||||||
|
uLongf destLen = GetBufferSize();
|
||||||
|
// read the data to a temporary buffer
|
||||||
|
char *tempBuffer = new char[m_SectionLength + 1];
|
||||||
|
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||||
|
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||||
|
// decompress
|
||||||
|
// AMXXLOG_Log("|||| First Bytes: %d %d %d %d", tempBuffer[0], tempBuffer[1], tempBuffer[2], tempBuffer[3]);
|
||||||
|
int result = uncompress((Bytef *)buffer, &destLen,
|
||||||
|
(Bytef *)tempBuffer, m_SectionLength);
|
||||||
|
delete [] tempBuffer;
|
||||||
|
// AMXXLOG_Log("|||| Result: %d, m_SectionLength=%d, destLen=%d", result, m_SectionLength, destLen);
|
||||||
|
if (result != Z_OK)
|
||||||
{
|
{
|
||||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
m_Status = Err_Decompress;
|
||||||
char *tempBuffer = new char[m_SectionLength + 1];
|
return Err_Decompress;
|
||||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
|
||||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
|
||||||
uLongf destLen = GetBufferSize();
|
|
||||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
|
||||||
delete [] tempBuffer;
|
|
||||||
|
|
||||||
if (result != Z_OK)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
|
||||||
m_Status = Err_Decompress;
|
|
||||||
return Err_Decompress;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Err_None;
|
|
||||||
} else {
|
|
||||||
// new file type: go to the section table entry
|
|
||||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
|
||||||
// go to the offset
|
|
||||||
TableEntry entry;
|
|
||||||
DATAREAD(&entry, sizeof(entry), 1);
|
|
||||||
fseek(m_pFile, entry.offset, SEEK_SET);
|
|
||||||
uLongf destLen = GetBufferSize();
|
|
||||||
// read the data to a temporary buffer
|
|
||||||
char *tempBuffer = new char[m_SectionLength + 1];
|
|
||||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
|
||||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
|
||||||
// decompress
|
|
||||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
|
||||||
delete [] tempBuffer;
|
|
||||||
|
|
||||||
if (result != Z_OK)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
|
||||||
m_Status = Err_Decompress;
|
|
||||||
|
|
||||||
return Err_Decompress;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Err_None;
|
|
||||||
}
|
}
|
||||||
|
return Err_None;
|
||||||
}
|
}
|
||||||
|
@ -32,31 +32,6 @@
|
|||||||
#ifndef __AMXXFILE_H__
|
#ifndef __AMXXFILE_H__
|
||||||
#define __AMXXFILE_H__
|
#define __AMXXFILE_H__
|
||||||
|
|
||||||
#define MAGIC_HEADER 0x414D5842
|
|
||||||
#define MAGIC_HEADER2 0x414D5858
|
|
||||||
#define MAGIC_VERSION 0x0300
|
|
||||||
|
|
||||||
typedef char mint8_t;
|
|
||||||
typedef int16_t mint16_t;
|
|
||||||
typedef int32_t mint32_t;
|
|
||||||
|
|
||||||
struct PluginEntry
|
|
||||||
{
|
|
||||||
mint8_t cellsize; //cell size
|
|
||||||
int32_t imagesize; //uncompressed image size
|
|
||||||
int32_t disksize; //compressed image size
|
|
||||||
int32_t memsize; //memory image size
|
|
||||||
int32_t offs; //file offset
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BinHeader
|
|
||||||
{
|
|
||||||
int32_t magic;
|
|
||||||
mint16_t version;
|
|
||||||
mint8_t numPlugins;
|
|
||||||
PluginEntry *plugins;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CAmxxReader
|
class CAmxxReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -78,9 +53,6 @@ private:
|
|||||||
FILE *m_pFile;
|
FILE *m_pFile;
|
||||||
|
|
||||||
bool m_OldFile; // old .amx file
|
bool m_OldFile; // old .amx file
|
||||||
bool m_AmxxFile; // new 'AMXX' header format
|
|
||||||
BinHeader m_Bh; // binary header
|
|
||||||
int m_Entry; // entry #
|
|
||||||
|
|
||||||
int m_CellSize;
|
int m_CellSize;
|
||||||
int m_SectionHdrOffset; // offset to the table in the header that describes the required section
|
int m_SectionHdrOffset; // offset to the table in the header that describes the required section
|
||||||
@ -92,7 +64,8 @@ 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,22 +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
|
||||||
|
|
||||||
#include "svn_version.h"
|
|
||||||
|
|
||||||
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()
|
||||||
@ -65,11 +61,10 @@ 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);
|
||||||
fp = fopen(m_LogFile.c_str(), "a+");
|
fopen(m_LogFile.c_str(), "a+");
|
||||||
|
|
||||||
// get time
|
// get time
|
||||||
time_t td;
|
time_t td;
|
||||||
@ -82,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,61 +84,47 @@ 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];
|
|
||||||
char name[256];
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
snprintf(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
|
m_LogFile.assign(build_pathname("%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i));
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s", name);
|
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 {
|
|
||||||
fprintf(fp, "AMX Mod X log file started (file \"%s\") (version \"%s\")\n", name, SVN_VERSION_STRING);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::UseFile(const String &fileName)
|
void CLog::UseFile(const String &fileName)
|
||||||
{
|
{
|
||||||
static char file[256];
|
m_LogFile.assign(build_pathname("%s/%s", g_log_dir.c_str(), fileName.c_str()));
|
||||||
m_LogFile.assign(build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), fileName.c_str()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::MapChange()
|
void CLog::MapChange()
|
||||||
{
|
{
|
||||||
// create dir if not existing
|
// create dir if not existing
|
||||||
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("%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("%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");
|
||||||
@ -152,23 +132,21 @@ 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];
|
|
||||||
|
|
||||||
if (m_LogType == 1 || m_LogType == 2)
|
if (m_LogType == 1 || m_LogType == 2)
|
||||||
{
|
{
|
||||||
// get time
|
// get time
|
||||||
@ -180,14 +158,14 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
||||||
|
|
||||||
// msg
|
// msg
|
||||||
static char msg[3072];
|
char msg[3072];
|
||||||
|
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
va_start(arglst, fmt);
|
va_start(arglst, fmt);
|
||||||
vsnprintf(msg, 3071, fmt, arglst);
|
vsnprintf(msg, 3071, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
|
|
||||||
FILE *pF = NULL;
|
FILE *pF;
|
||||||
if (m_LogType == 2)
|
if (m_LogType == 2)
|
||||||
{
|
{
|
||||||
pF = fopen(m_LogFile.c_str(), "a+");
|
pF = fopen(m_LogFile.c_str(), "a+");
|
||||||
@ -195,7 +173,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());
|
||||||
@ -203,82 +180,35 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/L%04d%02d%02d.log", g_log_dir.c_str(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday);
|
|
||||||
pF = fopen(file, "a+");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pF = fopen(build_pathname("%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday), "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 {
|
}
|
||||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
|
else
|
||||||
|
{
|
||||||
|
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());
|
||||||
m_LogType = 0;
|
m_LogType = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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];
|
// :TODO: Overflow possible here
|
||||||
|
char msg[3072];
|
||||||
va_list arglst;
|
va_list arglst;
|
||||||
va_start(arglst, fmt);
|
va_start(arglst, fmt);
|
||||||
vsnprintf(msg_, 3071, fmt, arglst);
|
vsnprintf(msg, 3071, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
ALERT(at_logged, "%s\n", msg_);
|
ALERT(at_logged, "%s\n", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLog::LogError(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
static char file[256];
|
|
||||||
static char name[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;
|
|
||||||
snprintf(name, sizeof(name), "%s/error_%04d%02d%02d.log", g_log_dir.c_str(), curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday);
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s", name);
|
|
||||||
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\") (file \"%s\")\n", date, STRING(gpGlobals->mapname), name);
|
|
||||||
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
|
|
@ -1,608 +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"
|
|
||||||
#include "datastructs.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Note: All handles start at 1. 0 and below are invalid handles.
|
|
||||||
// This way, a plugin that doesn't initialize a vector or
|
|
||||||
// string will not be able to modify another plugin's data
|
|
||||||
// on accident.
|
|
||||||
CVector<CellVector*> VectorHolder;
|
|
||||||
|
|
||||||
|
|
||||||
// Array:ArrayCreate(cellsize=1, reserved=32);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayCreate(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
// params[1] (cellsize) is how big in cells each element is.
|
|
||||||
// this MUST be greater than 0!
|
|
||||||
int cellsize=params[1];
|
|
||||||
|
|
||||||
// params[2] (reserved) is how many elements to allocate
|
|
||||||
// immediately when the list is created.
|
|
||||||
// this MUST be greater than 0!
|
|
||||||
int reserved=params[2];
|
|
||||||
|
|
||||||
if (cellsize<=0)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array size (%d)", cellsize);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (reserved<=0)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid reserved size (%d)", reserved);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan through the vector list to see if any are NULL.
|
|
||||||
// NULL means the vector was previously destroyed.
|
|
||||||
for (unsigned int i=0; i < VectorHolder.size(); ++i)
|
|
||||||
{
|
|
||||||
if (VectorHolder[i]==NULL)
|
|
||||||
{
|
|
||||||
VectorHolder[i]=new CellVector(cellsize);
|
|
||||||
VectorHolder[i]->Grow(reserved);
|
|
||||||
return i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// None are NULL, create a new vector
|
|
||||||
CellVector* NewVector=new CellVector(cellsize);
|
|
||||||
NewVector->Grow(reserved);
|
|
||||||
|
|
||||||
VectorHolder.push_back(NewVector);
|
|
||||||
|
|
||||||
return VectorHolder.size();
|
|
||||||
}
|
|
||||||
// ArrayClear(Array:which)
|
|
||||||
static cell AMX_NATIVE_CALL ArrayClear(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->Clear();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArraySize(Array:which)
|
|
||||||
static cell AMX_NATIVE_CALL ArraySize(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vec->Size();
|
|
||||||
}
|
|
||||||
// ArrayGetArray(Array:which, item, any:output[]);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayGetArray(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->GetArray(params[2],get_amxaddr(amx, params[3]))!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayGetCell(Array:which, item, any:&output);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayGetCell(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell ret;
|
|
||||||
if (vec->GetCell(params[2],&ret)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// ArrayGetString(Array:which, item, any:output[], size);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayGetString(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->GetString(params[2],get_amxaddr(amx, params[3]),params[4])!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArraySetArray(Array:which, item, any:output[]);
|
|
||||||
static cell AMX_NATIVE_CALL ArraySetArray(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->SetArray(params[2],get_amxaddr(amx, params[3]))!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArraySetCell(Array:which, item, any:&output);
|
|
||||||
static cell AMX_NATIVE_CALL ArraySetCell(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->SetCell(params[2], params[3])!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArraySetString(Array:which, item, any:output[]);
|
|
||||||
static cell AMX_NATIVE_CALL ArraySetString(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->SetString(params[2],get_amxaddr(amx, params[3]))!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayPushArray(Array:which, any:output[]);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayPushArray(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetArray(vec->Push(),get_amxaddr(amx, params[2]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayPushCell(Array:which, &any:output);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayPushCell(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetCell(vec->Push(), params[2]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayPushString(Array:which, any:output[]);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayPushString(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec==NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetString(vec->Push(),get_amxaddr(amx, params[2]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
static cell AMX_NATIVE_CALL ArrayGetStringHandle(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (vec == NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cell* ptr=vec->GetCellPointer(params[2]);
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reinterpret_cast<cell>(ptr);
|
|
||||||
|
|
||||||
}
|
|
||||||
// ArrayInsertArrayAfter(Array:which, item, const value[])
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertArrayAfter(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2]+1;
|
|
||||||
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayAfter (%d:%d)", params[1], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetArray(item, get_amxaddr(amx, params[3]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayInsertCellAfter(Array:which, item, value[])
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertCellAfter(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2]+1;
|
|
||||||
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellAfter (%d:%d)", params[1], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetCell(item, params[3]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayInsertStringAfter(Array:which, item, const value[])
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertStringAfter(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2]+1;
|
|
||||||
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringAfter (%d:%d)", params[1], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetString(item, get_amxaddr(amx, params[3]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayInsertArrayBefore(Array:which, item, const value[])
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertArrayBefore(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2];
|
|
||||||
|
|
||||||
if (item==vec->Size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetArray(item, get_amxaddr(amx, params[3]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayInsertCellBefore(Array:which, item, const value)
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertCellBefore(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2];
|
|
||||||
|
|
||||||
if (item==vec->Size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetCell(item, params[3]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// ArrayInsertStringBefore(Array:which, item, const value[])
|
|
||||||
static cell AMX_NATIVE_CALL ArrayInsertStringBefore(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int item=params[2];
|
|
||||||
|
|
||||||
if (item==vec->Size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (vec->ShiftUpFrom(item)!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec->SetString(item, get_amxaddr(amx, params[3]));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ArraySwap(Array:which, item1, item2)
|
|
||||||
static cell AMX_NATIVE_CALL ArraySwap(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (vec->Swap(params[2], params[3])!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArraySwap (%d , %d:%d)",params[2], params[3], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ArrayDeleteItem(Array:which, item);
|
|
||||||
static cell AMX_NATIVE_CALL ArrayDeleteItem(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
CellVector* vec=HandleToVector(amx, params[1]);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vec->Delete(params[2])!=1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayDeleteItem (%d:%d)", params[2], vec->Size());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ArrayDestroy(Array:&which)
|
|
||||||
static cell AMX_NATIVE_CALL ArrayDestroy(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
// byref the handle here so we can zero it out after destroying
|
|
||||||
// this way they cannot accidentally reuse it
|
|
||||||
cell* handle=get_amxaddr(amx,params[1]);
|
|
||||||
CellVector* vec=HandleToVector(amx, *handle);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete vec;
|
|
||||||
|
|
||||||
VectorHolder[*handle-1]=NULL;
|
|
||||||
|
|
||||||
*handle=0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct ArraySort_s
|
|
||||||
{
|
|
||||||
int handle;
|
|
||||||
int forward;
|
|
||||||
cell data;
|
|
||||||
cell size;
|
|
||||||
|
|
||||||
} ArraySort_t;
|
|
||||||
|
|
||||||
static CStack<ArraySort_t *> ArraySortStack;
|
|
||||||
|
|
||||||
int SortArrayList(const void *itema, const void *itemb)
|
|
||||||
{
|
|
||||||
ArraySort_t *Info = ArraySortStack.front();
|
|
||||||
|
|
||||||
return executeForwards(Info->forward, Info->handle, *((int *)itema), *((int *)itemb), Info->data, Info->size);
|
|
||||||
|
|
||||||
}
|
|
||||||
// native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0);
|
|
||||||
static cell AMX_NATIVE_CALL ArraySort(AMX* amx, cell* params)
|
|
||||||
{
|
|
||||||
int handle=params[1];
|
|
||||||
CellVector* vec=HandleToVector(amx, handle);
|
|
||||||
|
|
||||||
if (!vec)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is kind of a cheating way to go about this but...
|
|
||||||
// Create an array of integers as big as however many elements are in the vector.
|
|
||||||
// Pass that array to qsort
|
|
||||||
// After the array is sorted out, then create a NEW cellvector
|
|
||||||
// and copy in the old data in the order of what was sorted
|
|
||||||
int len;
|
|
||||||
char* FuncName=get_amxstring(amx, params[2], 0, len);
|
|
||||||
// MySortFunc(Array:array, item1, item2, const data[], data_size)
|
|
||||||
int Forward = registerSPForwardByName(amx, FuncName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
if (Forward < 0)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", FuncName);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *IntList=new int[vec->Size()];
|
|
||||||
|
|
||||||
for (int i=0; i< vec->Size(); i++)
|
|
||||||
{
|
|
||||||
IntList[i]=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArraySort_t *Info=new ArraySort_t;
|
|
||||||
|
|
||||||
Info->handle=handle;
|
|
||||||
Info->forward=Forward;
|
|
||||||
Info->data=params[3];
|
|
||||||
Info->size=params[4];
|
|
||||||
|
|
||||||
ArraySortStack.push(Info);
|
|
||||||
qsort(IntList, vec->Size(), sizeof(int), SortArrayList);
|
|
||||||
ArraySortStack.pop();
|
|
||||||
|
|
||||||
CellVector* newvec=new CellVector(vec->GetCellCount());
|
|
||||||
|
|
||||||
// Set the new vector's values
|
|
||||||
for (int i=0; i< vec->Size(); i++)
|
|
||||||
{
|
|
||||||
if (newvec->SetArray(newvec->Push(), vec->GetCellPointer(IntList[i]))!=1)
|
|
||||||
{
|
|
||||||
// This should never happen..
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Failed to SetArray in ArraySort (i=%d, IntList=%d)",i,IntList[i]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the old vector
|
|
||||||
delete vec;
|
|
||||||
|
|
||||||
// Now save the new vector in its handle location
|
|
||||||
VectorHolder[handle-1]=newvec;
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
delete Info;
|
|
||||||
delete IntList;
|
|
||||||
|
|
||||||
unregisterSPForward(Forward);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_DataStructNatives[] =
|
|
||||||
{
|
|
||||||
{ "ArrayCreate", ArrayCreate },
|
|
||||||
{ "ArrayClear", ArrayClear },
|
|
||||||
{ "ArraySize", ArraySize },
|
|
||||||
{ "ArrayGetArray", ArrayGetArray },
|
|
||||||
{ "ArrayGetCell", ArrayGetCell },
|
|
||||||
{ "ArrayGetString", ArrayGetString },
|
|
||||||
{ "ArraySetArray", ArraySetArray },
|
|
||||||
{ "ArraySetCell", ArraySetCell },
|
|
||||||
{ "ArraySetString", ArraySetString },
|
|
||||||
{ "ArrayPushArray", ArrayPushArray },
|
|
||||||
{ "ArrayPushCell", ArrayPushCell },
|
|
||||||
{ "ArrayPushString", ArrayPushString },
|
|
||||||
{ "ArrayInsertArrayAfter", ArrayInsertArrayAfter },
|
|
||||||
{ "ArrayInsertCellAfter", ArrayInsertCellAfter },
|
|
||||||
{ "ArrayInsertStringAfter", ArrayInsertStringAfter },
|
|
||||||
{ "ArrayInsertArrayBefore", ArrayInsertArrayBefore },
|
|
||||||
{ "ArrayInsertCellBefore", ArrayInsertCellBefore },
|
|
||||||
{ "ArrayInsertStringBefore", ArrayInsertStringBefore },
|
|
||||||
{ "ArraySwap", ArraySwap },
|
|
||||||
{ "ArrayDeleteItem", ArrayDeleteItem },
|
|
||||||
{ "ArrayGetStringHandle", ArrayGetStringHandle },
|
|
||||||
{ "ArrayDestroy", ArrayDestroy },
|
|
||||||
{ "ArraySort", ArraySort },
|
|
||||||
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
@ -1,323 +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 DATASTRUCTS_H
|
|
||||||
#define DATASTRUCTS_H
|
|
||||||
|
|
||||||
class CellVector
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
cell* data; // allocated with malloc
|
|
||||||
size_t cellcount; // how many cells per element
|
|
||||||
size_t cursize; // current size of the vector (maximum elements)
|
|
||||||
size_t count; // how many units of the vector are in use
|
|
||||||
|
|
||||||
public:
|
|
||||||
CellVector(): data(NULL), cellcount(0), cursize(0), count(0)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
CellVector(int cellsize): data(NULL), cellcount(cellsize), cursize(0), count(0)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
~CellVector()
|
|
||||||
{
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
size_t GetCellCount()
|
|
||||||
{
|
|
||||||
return cellcount;
|
|
||||||
};
|
|
||||||
void Grow(size_t howmany)
|
|
||||||
{
|
|
||||||
cursize+=howmany;
|
|
||||||
if (data)
|
|
||||||
{
|
|
||||||
data=(cell*)realloc(data, (sizeof(cell) * cellcount) * cursize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data=(cell*)malloc((sizeof(cell) * cellcount) * cursize);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
void FreeUnused(void)
|
|
||||||
{
|
|
||||||
if (cursize != count &&
|
|
||||||
data != NULL)
|
|
||||||
{
|
|
||||||
cursize=count;
|
|
||||||
data=(cell*)realloc(data, cursize * (sizeof(cell) * cellcount));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds.
|
|
||||||
int GetArray(size_t which, cell* output)
|
|
||||||
{
|
|
||||||
// make sure it is in bounds.
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// align output data
|
|
||||||
cell* out=data + (cellcount * which);
|
|
||||||
|
|
||||||
memcpy(output, out, sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds
|
|
||||||
int GetCell(size_t which, cell* output)
|
|
||||||
{
|
|
||||||
// check bounds
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*output=*(data + (cellcount * which));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds
|
|
||||||
int GetString(size_t which, cell* output, size_t size)
|
|
||||||
{
|
|
||||||
// check bounds
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
cell* out=data + (cellcount * which);
|
|
||||||
|
|
||||||
size_t count=cellcount;
|
|
||||||
|
|
||||||
while (size-- &&
|
|
||||||
count-- &&
|
|
||||||
(*output++=*out++)!='\0')
|
|
||||||
/* do nothing */ ;
|
|
||||||
|
|
||||||
// If size is zero here, then the string was never null terminated.
|
|
||||||
if (size==0)
|
|
||||||
{
|
|
||||||
*out='\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds
|
|
||||||
int SetArray(size_t which, cell* output)
|
|
||||||
{
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// align output
|
|
||||||
cell* out=data + (cellcount * which);
|
|
||||||
|
|
||||||
memcpy(out, output, sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds
|
|
||||||
int SetCell(size_t which, cell output)
|
|
||||||
{
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// align output
|
|
||||||
*(data + (cellcount * which))=output;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
// Returns 1 on success
|
|
||||||
// 0 on out of bounds
|
|
||||||
int SetString(size_t which, cell* output)
|
|
||||||
{
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// align output
|
|
||||||
cell* out=data + (cellcount * which);
|
|
||||||
|
|
||||||
memcpy(out, output, sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
// now force a null terminator on the last entry.
|
|
||||||
out+=(cellcount - 1);
|
|
||||||
*out='\0';
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
int Push()
|
|
||||||
{
|
|
||||||
if (count >= cursize)
|
|
||||||
{
|
|
||||||
// Grow in 8s to cause less reallocation
|
|
||||||
this->Grow(8);
|
|
||||||
};
|
|
||||||
|
|
||||||
this->count++;
|
|
||||||
|
|
||||||
return this->count-1;
|
|
||||||
};
|
|
||||||
int Size()
|
|
||||||
{
|
|
||||||
return this->count;
|
|
||||||
};
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
free(data);
|
|
||||||
data=(cell*)malloc(sizeof(cell) * cellcount);
|
|
||||||
cursize=1;
|
|
||||||
count=0;
|
|
||||||
};
|
|
||||||
cell* GetCellPointer(size_t which)
|
|
||||||
{
|
|
||||||
if (which >= count)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return data + (which * cellcount);
|
|
||||||
};
|
|
||||||
// Shifts all items from this item, and including this item up 1.
|
|
||||||
int ShiftUpFrom(size_t which)
|
|
||||||
{
|
|
||||||
// No point shifting this.
|
|
||||||
if (this->count < 0 ||
|
|
||||||
which > this->count)
|
|
||||||
{
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// First make a new item.
|
|
||||||
this->Push();
|
|
||||||
|
|
||||||
// If we got an InsertAfter(lastitem), then which will equal this->count - 1
|
|
||||||
// all we needed to do was Push()
|
|
||||||
if (which == this->count ||
|
|
||||||
which == this->count - 1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate a temporary buffer to store data in
|
|
||||||
size_t tempbuffsize=(sizeof(cell) * cellcount) * (this->count - which);
|
|
||||||
|
|
||||||
cell* temp=(cell*)malloc(tempbuffsize);
|
|
||||||
|
|
||||||
// Copy old data to temp buffer
|
|
||||||
memcpy(temp, GetCellPointer(which), tempbuffsize);
|
|
||||||
|
|
||||||
// Now copy temp buffer to adjusted location
|
|
||||||
memcpy(GetCellPointer(which+1), temp, tempbuffsize);
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
};
|
|
||||||
// Shifts all items from this item, and including this item down 1.
|
|
||||||
// This deletes the item specified.
|
|
||||||
int Delete(size_t which)
|
|
||||||
{
|
|
||||||
// No point shifting this.
|
|
||||||
if (this->count < 0 ||
|
|
||||||
which >= this->count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (size_t i=which; i<this->count - 1; i++)
|
|
||||||
{
|
|
||||||
memcpy(GetCellPointer(i), GetCellPointer(i + 1), sizeof(cell) * cellcount);
|
|
||||||
}
|
|
||||||
this->count--;
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
int Swap(size_t item1, size_t item2)
|
|
||||||
{
|
|
||||||
if (item1 >= this->count ||
|
|
||||||
item2 >= this->count)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a temp buffer to store item2
|
|
||||||
cell* temp=(cell*)malloc(sizeof(cell) * cellcount);
|
|
||||||
memcpy(temp, GetCellPointer(item2), sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
// copy item1 to item2
|
|
||||||
memcpy(GetCellPointer(item2), GetCellPointer(item1), sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
// copy item2 to item1
|
|
||||||
memcpy(GetCellPointer(item1), temp, sizeof(cell) * cellcount);
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
free(temp);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CVector<CellVector*> VectorHolder;
|
|
||||||
|
|
||||||
|
|
||||||
inline CellVector* HandleToVector(AMX* amx, int handle)
|
|
||||||
{
|
|
||||||
if (handle <= 0 ||
|
|
||||||
handle > (int)VectorHolder.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CellVector* ret=VectorHolder[handle-1];
|
|
||||||
|
|
||||||
if (ret == NULL)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
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 > -1); }
|
|
||||||
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_
|
|
387
amxmodx/emsg.cpp
387
amxmodx/emsg.cpp
@ -30,7 +30,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "CMenu.h"
|
|
||||||
|
|
||||||
int gmsgAmmoPickup;
|
int gmsgAmmoPickup;
|
||||||
int gmsgAmmoX;
|
int gmsgAmmoX;
|
||||||
@ -58,241 +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;
|
||||||
|
|
||||||
switch (mState++)
|
int iwpn = iId;
|
||||||
{
|
|
||||||
case 0:
|
if (iId > 31) {
|
||||||
wpnName = (char*)mValue;
|
iwpn -= 31;
|
||||||
break;
|
blocker = &wpnList2;
|
||||||
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->current = iId;
|
mPlayer->lastHit = mPlayer->lastTrace;
|
||||||
|
}
|
||||||
|
|
||||||
if (*(int*)mValue < mPlayer->weapons[iId].clip && // Only update the lastHit vector if the clip size is decreasing
|
|
||||||
*(int*)mValue != -1) // But not if it's a melee weapon
|
|
||||||
{
|
|
||||||
mPlayer->lastHit = mPlayer->lastTrace;
|
|
||||||
}
|
|
||||||
mPlayer->weapons[iId].clip = *(int*)mValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_AmmoX(void* mValue)
|
void Client_AmmoX(void* mValue)
|
||||||
{
|
{
|
||||||
static int iAmmo;
|
|
||||||
|
|
||||||
switch (mState++)
|
static int iAmmo;
|
||||||
{
|
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;
|
||||||
}
|
}
|
||||||
@ -306,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
2723
amxmodx/fakemeta.cpp
2723
amxmodx/fakemeta.cpp
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,199 @@
|
|||||||
#ifndef __FAKEMETA_H__
|
#ifndef __FAKEMETA_H__
|
||||||
#define __FAKEMETA_H__
|
#define __FAKEMETA_H__
|
||||||
|
|
||||||
int UnloadMetamodPlugin(void *handle);
|
// Fake metamod api for modules
|
||||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
|
||||||
|
#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 // #ifndef __FAKEMETA_H__
|
#endif // #ifndef __FAKEMETA_H__
|
||||||
|
|
||||||
|
1199
amxmodx/file.cpp
1199
amxmodx/file.cpp
File diff suppressed because it is too large
Load Diff
@ -96,7 +96,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Now convert the Small String into a C type null terminated string */
|
/* Now convert the Small String into a C type null terminated string */
|
||||||
amx_GetStringOld(szSource, pString, 0);
|
amx_GetString(szSource, pString, 0);
|
||||||
|
|
||||||
/* Now convert this to a float. */
|
/* Now convert this to a float. */
|
||||||
fNum = (REAL)atof(szSource);
|
fNum = (REAL)atof(szSource);
|
||||||
@ -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,651 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include "format.h"
|
|
||||||
#include "datastructs.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 UPPERDIGITS 0x00000200 /* make alpha digits uppercase */
|
|
||||||
#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, int flags)
|
|
||||||
{
|
|
||||||
int digits; // non-fraction part digits
|
|
||||||
double tmp; // temporary
|
|
||||||
U *buf = *buf_p; // output buffer pointer
|
|
||||||
int val; // temporary
|
|
||||||
int sign = 0; // 0: positive, 1: negative
|
|
||||||
int fieldlength; // for padding
|
|
||||||
int significant_digits = 0; // number of significant digits written
|
|
||||||
const int MAX_SIGNIFICANT_DIGITS = 16;
|
|
||||||
|
|
||||||
// default precision
|
|
||||||
if (prec < 0)
|
|
||||||
{
|
|
||||||
prec = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the sign
|
|
||||||
if (fval < 0)
|
|
||||||
{
|
|
||||||
fval = -fval;
|
|
||||||
sign = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute whole-part digits count
|
|
||||||
digits = (int)log10(fval) + 1;
|
|
||||||
|
|
||||||
// Only print 0.something if 0 < fval < 1
|
|
||||||
if (digits < 1)
|
|
||||||
{
|
|
||||||
digits = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the field length
|
|
||||||
fieldlength = digits + prec + ((prec > 0) ? 1 : 0) + sign;
|
|
||||||
|
|
||||||
// minus sign BEFORE left padding if padding with zeros
|
|
||||||
if (sign && maxlen && (flags & ZEROPAD))
|
|
||||||
{
|
|
||||||
*buf++ = '-';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// right justify if required
|
|
||||||
if ((flags & LADJUST) == 0)
|
|
||||||
{
|
|
||||||
while ((fieldlength < width) && maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// minus sign AFTER left padding if padding with spaces
|
|
||||||
if (sign && maxlen && !(flags & ZEROPAD))
|
|
||||||
{
|
|
||||||
*buf++ = '-';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the whole part
|
|
||||||
tmp = pow(10.0, digits-1);
|
|
||||||
while ((digits--) && maxlen)
|
|
||||||
{
|
|
||||||
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
|
||||||
{
|
|
||||||
*buf++ = '0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
val = (int)(fval / tmp);
|
|
||||||
*buf++ = '0' + val;
|
|
||||||
fval -= val * tmp;
|
|
||||||
tmp *= 0.1;
|
|
||||||
}
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the fraction part
|
|
||||||
if (maxlen)
|
|
||||||
{
|
|
||||||
*buf++ = '.';
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = pow(10.0, prec);
|
|
||||||
|
|
||||||
fval *= tmp;
|
|
||||||
while (prec-- && maxlen)
|
|
||||||
{
|
|
||||||
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
|
||||||
{
|
|
||||||
*buf++ = '0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmp *= 0.1;
|
|
||||||
val = (int)(fval / tmp);
|
|
||||||
*buf++ = '0' + val;
|
|
||||||
fval -= val * tmp;
|
|
||||||
}
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// left justify if required
|
|
||||||
if (flags & LADJUST)
|
|
||||||
{
|
|
||||||
while ((fieldlength < width) && maxlen)
|
|
||||||
{
|
|
||||||
// right-padding only with spaces, ZEROPAD is ignored
|
|
||||||
*buf++ = ' ';
|
|
||||||
width--;
|
|
||||||
maxlen--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update parent's buffer pointer
|
|
||||||
*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 U>
|
|
||||||
void AddHex(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
|
||||||
{
|
|
||||||
U text[32];
|
|
||||||
int digits;
|
|
||||||
U *buf;
|
|
||||||
U digit;
|
|
||||||
int hexadjust;
|
|
||||||
|
|
||||||
if (flags & UPPERDIGITS)
|
|
||||||
{
|
|
||||||
hexadjust = 'A' - '9' - 1;
|
|
||||||
} else {
|
|
||||||
hexadjust = 'a' - '9' - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
digits = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
digit = ('0' + val % 16);
|
|
||||||
if (digit > '9')
|
|
||||||
{
|
|
||||||
digit += hexadjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
text[digits++] = digit;
|
|
||||||
val /= 16;
|
|
||||||
} 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 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, flags);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
flags |= UPPERDIGITS;
|
|
||||||
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
|
|
||||||
arg++;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
{
|
|
||||||
CHECK_ARGS(0);
|
|
||||||
// %a is passed a pointer directly to a cell string.
|
|
||||||
cell* ptr=reinterpret_cast<cell*>(*get_amxaddr(amx, params[arg]));
|
|
||||||
if (!ptr)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid vector string handle provided (%d)", *get_amxaddr(amx, params[arg]));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddString(&buf_p, llen, ptr, 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,835 +0,0 @@
|
|||||||
#include "amxmodx.h"
|
|
||||||
#include "messages.h"
|
|
||||||
|
|
||||||
Message Msg;
|
|
||||||
//CVector<int> msgHooks[256];
|
|
||||||
RegisteredMessage 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].Hooked()) {
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (inblock)
|
|
||||||
{
|
|
||||||
inblock = false;
|
|
||||||
if (msgBlocks[msgType] == BLOCK_ONCE)
|
|
||||||
{
|
|
||||||
msgBlocks[msgType] = BLOCK_NOT;
|
|
||||||
}
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
} else if (inhook) {
|
|
||||||
|
|
||||||
mres = msgHooks[msgType].Execute((cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
|
||||||
|
|
||||||
/*
|
|
||||||
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]].AddHook(id);
|
|
||||||
return id;
|
|
||||||
} else {
|
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unregister_message(msgid, msghandle)
|
|
||||||
static cell AMX_NATIVE_CALL unregister_message(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!Msg.Ready())
|
|
||||||
Msg.Init();
|
|
||||||
|
|
||||||
if (params[1]>0 && params[1] < 256)
|
|
||||||
{
|
|
||||||
int id = params[2];
|
|
||||||
if (id != -1)
|
|
||||||
{
|
|
||||||
msgHooks[params[1]].RemoveHook(id);
|
|
||||||
return id;
|
|
||||||
} else {
|
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid registered message handle");
|
|
||||||
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},
|
|
||||||
{"unregister_message", unregister_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},
|
|
||||||
};
|
|
@ -1,216 +0,0 @@
|
|||||||
#ifndef _MSGS_INCLUDE_H
|
|
||||||
#define _MSGS_INCLUDE_H
|
|
||||||
|
|
||||||
#include <extdll.h>
|
|
||||||
#include <meta_api.h>
|
|
||||||
#include "amx.h"
|
|
||||||
#include "CVector.h"
|
|
||||||
#include "CString.h"
|
|
||||||
#include "sh_stack.h"
|
|
||||||
|
|
||||||
#define MAX_MESSAGES 255
|
|
||||||
|
|
||||||
#define MSGBLOCK_SET 0
|
|
||||||
#define MSGBLOCK_GET 1
|
|
||||||
#define BLOCK_NOT 0
|
|
||||||
#define BLOCK_ONCE 1
|
|
||||||
#define BLOCK_SET 2
|
|
||||||
|
|
||||||
class RegisteredMessage
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CVector<int> m_Forwards;
|
|
||||||
CStack<int> m_InExecution;
|
|
||||||
bool m_Cleanup;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RegisteredMessage() : m_Cleanup(false) { }
|
|
||||||
~RegisteredMessage() { this->Clear(); }
|
|
||||||
|
|
||||||
void AddHook(int fwd)
|
|
||||||
{
|
|
||||||
m_Forwards.push_back(fwd);
|
|
||||||
}
|
|
||||||
bool RemoveHook(int fwd)
|
|
||||||
{
|
|
||||||
// Don't erase a forward if we're in the middle of execution; this
|
|
||||||
// could throw off the iterator that is going through the forwards
|
|
||||||
// and executing them. Instead, unregister the forward and set it
|
|
||||||
// to -1 from within the vector.
|
|
||||||
if (m_InExecution.size())
|
|
||||||
{
|
|
||||||
this->m_Cleanup = true;
|
|
||||||
|
|
||||||
CVector<int>::iterator iter = m_Forwards.begin();
|
|
||||||
CVector<int>::iterator end = m_Forwards.end();
|
|
||||||
while (iter != end)
|
|
||||||
{
|
|
||||||
if (*iter == fwd)
|
|
||||||
{
|
|
||||||
if (*iter != -1)
|
|
||||||
{
|
|
||||||
unregisterSPForward(*iter);
|
|
||||||
}
|
|
||||||
*iter = -1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CVector<int>::iterator iter = m_Forwards.begin();
|
|
||||||
CVector<int>::iterator end = m_Forwards.end();
|
|
||||||
while (iter != end)
|
|
||||||
{
|
|
||||||
if (*iter == fwd)
|
|
||||||
{
|
|
||||||
if (fwd != -1)
|
|
||||||
{
|
|
||||||
unregisterSPForward(fwd);
|
|
||||||
|
|
||||||
m_Forwards.erase(iter);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// -1 could be in here more than once
|
|
||||||
m_Forwards.erase(iter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
while (m_InExecution.size())
|
|
||||||
{
|
|
||||||
m_InExecution.pop();
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < m_Forwards.size(); i++)
|
|
||||||
{
|
|
||||||
int fwd = m_Forwards[i];
|
|
||||||
|
|
||||||
if (fwd != -1)
|
|
||||||
{
|
|
||||||
unregisterSPForward(m_Forwards[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Forwards.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
cell Execute(cell type, cell dest, cell entity)
|
|
||||||
{
|
|
||||||
m_InExecution.push(1);
|
|
||||||
cell res = 0;
|
|
||||||
cell thisres = 0;
|
|
||||||
for (size_t i = 0; i < m_Forwards.size(); i++)
|
|
||||||
{
|
|
||||||
int fwd = m_Forwards[i];
|
|
||||||
|
|
||||||
if (fwd != -1)
|
|
||||||
{
|
|
||||||
thisres = executeForwards(fwd, type, dest, entity);
|
|
||||||
if (thisres > res)
|
|
||||||
{
|
|
||||||
res = thisres;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_InExecution.pop();
|
|
||||||
|
|
||||||
if (m_InExecution.size() == 0 && m_Cleanup)
|
|
||||||
{
|
|
||||||
this->RemoveHook(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
bool Hooked() const
|
|
||||||
{
|
|
||||||
return m_Forwards.size() != 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
enum msgtype
|
|
||||||
{
|
|
||||||
arg_byte = 1,
|
|
||||||
arg_char,
|
|
||||||
arg_short,
|
|
||||||
arg_long,
|
|
||||||
arg_angle,
|
|
||||||
arg_coord,
|
|
||||||
arg_string,
|
|
||||||
arg_entity,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct msgparam
|
|
||||||
{
|
|
||||||
msgtype type;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
REAL fData;
|
|
||||||
int iData;
|
|
||||||
} v;
|
|
||||||
String szData;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Message
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Message();
|
|
||||||
~Message();
|
|
||||||
void AddParam(float data, msgtype type);
|
|
||||||
void AddParam(int data, msgtype type);
|
|
||||||
void AddParam(const char *data, msgtype type);
|
|
||||||
void SetParam(size_t index, float data);
|
|
||||||
void SetParam(size_t index, int data);
|
|
||||||
void SetParam(size_t index, const char *data);
|
|
||||||
const char *GetParamString(size_t index);
|
|
||||||
float GetParamFloat(size_t index);
|
|
||||||
bool Ready();
|
|
||||||
void Init();
|
|
||||||
int GetParamInt(size_t index);
|
|
||||||
msgtype GetParamType(size_t index);
|
|
||||||
void Reset();
|
|
||||||
void Send();
|
|
||||||
size_t Params();
|
|
||||||
private:
|
|
||||||
msgparam *AdvPtr();
|
|
||||||
private:
|
|
||||||
CVector<msgparam *> m_Params;
|
|
||||||
size_t m_CurParam;
|
|
||||||
};
|
|
||||||
|
|
||||||
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
|
||||||
void C_WriteByte(int iValue);
|
|
||||||
void C_WriteChar(int iValue);
|
|
||||||
void C_WriteShort(int iValue);
|
|
||||||
void C_WriteLong(int iValue);
|
|
||||||
void C_WriteAngle(float flValue);
|
|
||||||
void C_WriteCoord(float flValue);
|
|
||||||
void C_WriteString(const char *sz);
|
|
||||||
void C_WriteEntity(int iValue);
|
|
||||||
void C_MessageEnd(void);
|
|
||||||
|
|
||||||
extern RegisteredMessage msgHooks[256];
|
|
||||||
extern int msgBlocks[256];
|
|
||||||
|
|
||||||
void ClearMessages();
|
|
||||||
|
|
||||||
#endif //_MSGS_INCLUDE_H
|
|
||||||
|
|
2025
amxmodx/meta_api.cpp
2025
amxmodx/meta_api.cpp
File diff suppressed because it is too large
Load Diff
@ -930,11 +930,7 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
|
|||||||
|
|
||||||
// Danger Will Robinson!
|
// Danger Will Robinson!
|
||||||
|
|
||||||
if (reservoir == NULL)
|
if (reservoir == NULL) throw "Unable to allocate RAM for internal memory tracking data";
|
||||||
{
|
|
||||||
log("%s: Unable to allocate RAM for internal memory tracking data", ownerString(sourceFile, sourceLine, sourceFunc));
|
|
||||||
throw "Unable to allocate RAM for internal memory tracking data";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a linked-list of the elements in our reservoir
|
// Build a linked-list of the elements in our reservoir
|
||||||
|
|
||||||
@ -1002,7 +998,6 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
|
|||||||
|
|
||||||
if (au->actualAddress == NULL)
|
if (au->actualAddress == NULL)
|
||||||
{
|
{
|
||||||
log("%s: Request for allocation failed. Out of memory.", ownerString(sourceFile, sourceLine, sourceFunc));
|
|
||||||
throw "Request for allocation failed. Out of memory.";
|
throw "Request for allocation failed. Out of memory.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1113,11 +1108,7 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
|
|||||||
|
|
||||||
// If you hit this assert, you tried to reallocate RAM that wasn't allocated by this memory manager.
|
// If you hit this assert, you tried to reallocate RAM that wasn't allocated by this memory manager.
|
||||||
m_assert(au != NULL);
|
m_assert(au != NULL);
|
||||||
if (au == NULL)
|
if (au == NULL) throw "Request to reallocate RAM that was never allocated";
|
||||||
{
|
|
||||||
log("%s: Request to reallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
|
|
||||||
throw "Request to reallocate RAM that was never allocated";
|
|
||||||
}
|
|
||||||
|
|
||||||
// If you hit this assert, then the allocation unit that is about to be reallocated is damaged. But you probably
|
// If you hit this assert, then the allocation unit that is about to be reallocated is damaged. But you probably
|
||||||
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
||||||
@ -1171,11 +1162,7 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
|
|||||||
m_assert(newActualAddress);
|
m_assert(newActualAddress);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!newActualAddress)
|
if (!newActualAddress) throw "Request for reallocation failed. Out of memory.";
|
||||||
{
|
|
||||||
log("%s: Request for reallocation failed. Out of memory", ownerString(sourceFile, sourceLine, sourceFunc));
|
|
||||||
throw "Request for reallocation failed. Out of memory.";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove this allocation from our stats (we'll add the new reallocation again later)
|
// Remove this allocation from our stats (we'll add the new reallocation again later)
|
||||||
|
|
||||||
@ -1304,11 +1291,7 @@ void m_deallocator(const char *sourceFile, const unsigned int sourceLine, const
|
|||||||
|
|
||||||
// If you hit this assert, you tried to deallocate RAM that wasn't allocated by this memory manager.
|
// If you hit this assert, you tried to deallocate RAM that wasn't allocated by this memory manager.
|
||||||
m_assert(au != NULL);
|
m_assert(au != NULL);
|
||||||
if (au == NULL)
|
if (au == NULL) throw "Request to deallocate RAM that was never allocated";
|
||||||
{
|
|
||||||
log("%s: Request to deallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
|
|
||||||
throw "Request to deallocate RAM that was never allocated";
|
|
||||||
}
|
|
||||||
|
|
||||||
// If you hit this assert, then the allocation unit that is about to be deallocated is damaged. But you probably
|
// If you hit this assert, then the allocation unit that is about to be deallocated is damaged. But you probably
|
||||||
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
// already know that from a previous assert you should have seen in validateAllocUnit() :)
|
||||||
|
2050
amxmodx/modules.cpp
2050
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -36,56 +36,144 @@
|
|||||||
|
|
||||||
#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
|
||||||
#define C_DLLEXPORT extern "C" DLLEXPORT
|
#define C_DLLEXPORT extern "C" DLLEXPORT
|
||||||
|
|
||||||
|
#define AMX_INTERFACE_VERSION 6
|
||||||
|
|
||||||
#define RELOAD_MODULE 0
|
#define RELOAD_MODULE 0
|
||||||
#define STATIC_MODULE 1
|
#define STATIC_MODULE 1
|
||||||
|
|
||||||
typedef enum
|
struct module_info_s {
|
||||||
{
|
const char* name;
|
||||||
Player_Name, //String
|
const char* author;
|
||||||
Player_Ip, //String
|
const char* version;
|
||||||
Player_Team, //String
|
int ivers;
|
||||||
Player_Ingame, //bool
|
int type;
|
||||||
Player_Authorized, //bool
|
long int serial;
|
||||||
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]);
|
// Small scripting language
|
||||||
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
|
struct pfnamx_engine_g {
|
||||||
const char *StrCaseStr(const char *as, const char *bs);
|
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
|
||||||
|
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
|
||||||
|
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
|
||||||
|
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
|
||||||
|
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
|
||||||
|
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
|
||||||
|
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
|
||||||
|
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
|
||||||
|
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
|
||||||
|
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
|
||||||
|
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
|
||||||
|
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
|
||||||
|
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
|
||||||
|
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
|
||||||
|
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
|
||||||
|
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
|
||||||
|
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
|
||||||
|
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
|
||||||
|
int (*pfnamx_Init)(AMX*, void *); // amx, program
|
||||||
|
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
|
||||||
|
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
|
||||||
|
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
|
||||||
|
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
|
||||||
|
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
|
||||||
|
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
|
||||||
|
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
|
||||||
|
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
|
||||||
|
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
|
||||||
|
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
|
||||||
|
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
|
||||||
|
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
|
||||||
|
};
|
||||||
|
extern pfnamx_engine_g* g_engAmxFunc;
|
||||||
|
|
||||||
class Debugger;
|
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
|
||||||
Debugger *DisableDebugHandler(AMX *amx);
|
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
|
||||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
|
||||||
|
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
|
||||||
|
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
|
||||||
|
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
|
||||||
|
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
|
||||||
|
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
|
||||||
|
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
|
||||||
|
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
|
||||||
|
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
|
||||||
|
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
|
||||||
|
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
|
||||||
|
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
|
||||||
|
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
|
||||||
|
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
|
||||||
|
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
|
||||||
|
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
|
||||||
|
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
|
||||||
|
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
|
||||||
|
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
|
||||||
|
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
|
||||||
|
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
|
||||||
|
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
|
||||||
|
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
|
||||||
|
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
|
||||||
|
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
|
||||||
|
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
|
||||||
|
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
|
||||||
|
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
|
||||||
|
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
|
||||||
|
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
|
||||||
|
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
|
||||||
|
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
|
||||||
|
|
||||||
bool DirExists(const char *dir);
|
// Modules API
|
||||||
const char* GetFileName(AMX *amx);
|
struct pfnmodule_engine_g {
|
||||||
|
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
|
||||||
|
char* (*pfnbuild_pathname)(char*, ...); // format, ....
|
||||||
|
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
|
||||||
|
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
|
||||||
|
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
|
||||||
|
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
|
||||||
|
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
|
||||||
|
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
|
||||||
|
void (*pfnget_modname)(char*); // modname
|
||||||
|
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64], int); // amx, code, path, error info
|
||||||
|
void (*pfnprint_console)(char*, ...); // format, ....
|
||||||
|
void (*pfnreport_error)(int code, char*, ... );
|
||||||
|
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
|
||||||
|
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
|
||||||
|
int (*pfnamxstring_length)(cell*); // src
|
||||||
|
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
|
||||||
|
void* (*pfnalloc_amxmemory)(void**,int size);
|
||||||
|
void (*pfnfree_amxmemory)(void**);
|
||||||
|
};
|
||||||
|
extern pfnmodule_engine_g* g_engModuleFunc;
|
||||||
|
|
||||||
|
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
|
||||||
|
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
|
||||||
|
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
|
||||||
|
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
|
||||||
|
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
|
||||||
|
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
|
||||||
|
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
|
||||||
|
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
|
||||||
|
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
|
||||||
|
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
|
||||||
|
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
|
||||||
|
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
|
||||||
|
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
|
||||||
|
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
|
||||||
|
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
|
||||||
|
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
|
||||||
|
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
|
||||||
|
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
|
||||||
|
|
||||||
inline cell FloatToCell(float input)
|
|
||||||
{
|
|
||||||
REAL output = input;
|
|
||||||
return *(cell *)&output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __MODULES_H__
|
#endif // __MODULES_H__
|
||||||
|
12
amxmodx/msvc/.cvsignore
Executable file
12
amxmodx/msvc/.cvsignore
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
amxmodx.sln
|
||||||
|
amxmodx.suo
|
||||||
|
amxmodx.aps
|
||||||
|
amxmodx.ncb
|
||||||
|
Debug
|
||||||
|
JITDebug
|
||||||
|
JITMemtestRelease
|
||||||
|
JITRelease
|
||||||
|
MaximalSpeed
|
||||||
|
MemtestDebug
|
||||||
|
MemtestRelease
|
||||||
|
Release
|
804
amxmodx/msvc/amxmodx.vcproj
Executable file
804
amxmodx/msvc/amxmodx.vcproj
Executable file
@ -0,0 +1,804 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="amxmodx"
|
||||||
|
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||||
|
SccProjectName=""
|
||||||
|
SccLocalPath="">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<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=""
|
||||||
|
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||||
|
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
|
||||||
|
Name="JITDebug|Win32"
|
||||||
|
OutputDirectory="JITDebug"
|
||||||
|
IntermediateDirectory="JITDebug"
|
||||||
|
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;JIT"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="5"
|
||||||
|
StructMemberAlignment="3"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\jitdebug/"
|
||||||
|
ObjectFile=".\jitdebug/"
|
||||||
|
ProgramDataBaseFileName=".\jitdebug/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||||
|
Version="0.1"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\jitdebug/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="JITRelease|Win32"
|
||||||
|
OutputDirectory="JITRelease"
|
||||||
|
IntermediateDirectory="JITRelease"
|
||||||
|
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;JIT"
|
||||||
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\jitrelease/"
|
||||||
|
ObjectFile=".\jitrelease/"
|
||||||
|
ProgramDataBaseFileName=".\jitrelease/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
||||||
|
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\jitrelease/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="JITMemtestRelease|Win32"
|
||||||
|
OutputDirectory="JITMemtestRelease"
|
||||||
|
IntermediateDirectory="JITMemtestRelease"
|
||||||
|
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;JIT"
|
||||||
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\jitmemtestrelease/"
|
||||||
|
ObjectFile=".\jitmemtestrelease/"
|
||||||
|
ProgramDataBaseFileName=".\jitmemtestrelease/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\jitmemtestrelease/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="MaximalSpeed|Win32"
|
||||||
|
OutputDirectory="MaximalSpeed"
|
||||||
|
IntermediateDirectory="MaximalSpeed"
|
||||||
|
ConfigurationType="2"
|
||||||
|
UseOfMFC="0"
|
||||||
|
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
GlobalOptimizations="TRUE"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
EnableIntrinsicFunctions="TRUE"
|
||||||
|
FavorSizeOrSpeed="1"
|
||||||
|
OptimizeForProcessor="2"
|
||||||
|
OptimizeForWindowsApplication="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"
|
||||||
|
StringPooling="TRUE"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
EnableFunctionLevelLinking="TRUE"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
PrecompiledHeaderThrough="amxmodx.h"
|
||||||
|
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
|
||||||
|
AssemblerListingLocation=".\MaximalSpeed/"
|
||||||
|
ObjectFile=".\MaximalSpeed/"
|
||||||
|
ProgramDataBaseFileName=".\MaximalSpeed/"
|
||||||
|
WarningLevel="3"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
CompileAs="0"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalOptions="/MACHINE:I386"
|
||||||
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||||
|
OutputFile="MaximalSpeed/amxmodx_mm.dll"
|
||||||
|
LinkIncremental="1"
|
||||||
|
SuppressStartupBanner="TRUE"
|
||||||
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
|
ModuleDefinitionFile=""
|
||||||
|
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
|
||||||
|
ImportLibrary=".\jitrelease/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>
|
||||||
|
</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="..\amxmodx.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxtime.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxxfile.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxxlog.cpp">
|
||||||
|
</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="..\emsg.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\fakemeta.cpp">
|
||||||
|
<FileConfiguration
|
||||||
|
Name="MemtestDebug|Win32">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
GeneratePreprocessedFile="0"/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\file.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\float.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\md5.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\meta_api.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\modules.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\power.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\srvcmd.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\string.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\strptime.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\util.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\vault.cpp">
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="mmgr"
|
||||||
|
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
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl">
|
||||||
|
<File
|
||||||
|
RelativePath="..\amx.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxmodx.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxxfile.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxxlog.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="..\CRList.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CString.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CTask.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CVault.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\CVector.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\fakemeta.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\md5.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\modules.h">
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="mmgr"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\mmgr\mmgr.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mmgr\nommgr.h">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc">
|
||||||
|
<File
|
||||||
|
RelativePath="..\version.rc">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
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
|
292
amxmodx/msvc/amxmodx_mm.dsp
Executable file
292
amxmodx/msvc/amxmodx_mm.dsp
Executable file
@ -0,0 +1,292 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="amxmodx_mm" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=amxmodx_mm - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "amxmodx_mm.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "amxmodx_mm.mak" CFG="amxmodx_mm - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "amxmodx_mm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "amxmodx_mm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "amxmodx_mm - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "release"
|
||||||
|
# PROP Intermediate_Dir "release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\metamod\metamod" /I "..\..\hlsdk\sourcecode\common" /I "..\..\hlsdk\sourcecode\engine" /I "..\..\hlsdk\sourcecode\dlls" /I "..\..\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:".\amxmodx_mm.def" /out:"release/amxx_mm.dll" /libpath:"..\extra\lib_win32"
|
||||||
|
# Begin Custom Build
|
||||||
|
TargetPath=.\release\amxx_mm.dll
|
||||||
|
TargetName=amxx_mm
|
||||||
|
InputPath=.\release\amxx_mm.dll
|
||||||
|
SOURCE="$(InputPath)"
|
||||||
|
|
||||||
|
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||||
|
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
|
||||||
|
|
||||||
|
# End Custom Build
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "amxmodx_mm - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "debug"
|
||||||
|
# PROP Intermediate_Dir "debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /Zp4 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\metamod\metamod" /I "..\...\hlsdk\sourcecode\common" /I "..\...\hlsdk\sourcecode\engine" /I "..\...\hlsdk\sourcecode\dlls" /I "..\...\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\amxmodx_mm.def" /out:"debug/amxx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
|
||||||
|
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||||
|
# Begin Custom Build
|
||||||
|
TargetPath=.\debug\amxx_mm.dll
|
||||||
|
TargetName=amxx_mm
|
||||||
|
InputPath=.\debug\amxx_mm.dll
|
||||||
|
SOURCE="$(InputPath)"
|
||||||
|
|
||||||
|
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||||
|
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
|
||||||
|
|
||||||
|
# End Custom Build
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "amxmodx_mm - Win32 Release"
|
||||||
|
# Name "amxmodx_mm - Win32 Debug"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amx.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amxcore.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amxmodx.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amxtime.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amxxlog.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CCmd.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CEvent.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CFile.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CForward.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CLogEvent.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CMenu.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CMisc.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CModule.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CPlugin.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CString.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CTask.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CVault.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\emsg.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\file.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\float.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\meta_api.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\modules.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\power.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\srvcmd.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\string.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\strptime.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\util.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\vault.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\amxmodx.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CCmd.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CEvent.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CFile.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CForward.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CList.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CLogEvent.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CMenu.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CMisc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CModule.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CPlugin.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CString.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CTask.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\CVault.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\modules.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
4
editor/studio/plugins/Hello_World CPP/Hello_World.dsw → amxmodx/msvc/amxmodx_mm.dsw
Normal file → Executable file
4
editor/studio/plugins/Hello_World CPP/Hello_World.dsw → amxmodx/msvc/amxmodx_mm.dsw
Normal file → Executable file
@ -1,9 +1,9 @@
|
|||||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Project: "Hello_World"=".\Hello_World.dsp" - Package Owner=<4>
|
Project: "amxmodx_mm"=.\amxmodx_mm.dsp - Package Owner=<4>
|
||||||
|
|
||||||
Package=<5>
|
Package=<5>
|
||||||
{{{
|
{{{
|
@ -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
|
|
File diff suppressed because it is too large
Load Diff
@ -1,91 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
|
||||||
; register_native functions for amd64 ;;;;;;
|
|
||||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
|
||||||
; Thanks to T(+)rget for pushing me to implement this ;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;;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.
|
|
||||||
|
|
||||||
;;Initializes the global variable
|
|
||||||
|
|
||||||
BITS 64
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
global amxx_DynaInit, _amxx_DynaInit
|
|
||||||
;void amxx_DynaInit(void *ptr);
|
|
||||||
amxx_DynaInit:
|
|
||||||
_amxx_DynaInit:
|
|
||||||
mov [GLOBAL_GATE wrt rip], rdi
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;Assembles the gateway function
|
|
||||||
global amxx_DynaMake, _amxx_DynaMake
|
|
||||||
;int amxx_DynaMake(char *buffer, int id);
|
|
||||||
amxx_DynaMake:
|
|
||||||
_amxx_DynaMake:
|
|
||||||
;we're not damaging the stack I think so we should be safe with no prologue
|
|
||||||
|
|
||||||
;save these two we're about to destroy them
|
|
||||||
push rsi ;push id
|
|
||||||
push rdi ;push buffer
|
|
||||||
|
|
||||||
mov rsi, _amxx_DynaFuncStart
|
|
||||||
mov rcx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
||||||
cld ;clear direction flag (just in case)
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
pop rdi ;get buffer as destination
|
|
||||||
pop rax ;get id
|
|
||||||
;align us to mov rsi, 1234... - on x86-64 this is 2 bytes after the differential
|
|
||||||
add rdi, (_amxx_DynaFuncStart.move-_amxx_DynaFuncStart) + 2
|
|
||||||
mov [rdi], qword rax
|
|
||||||
;align rdi to the call
|
|
||||||
add rdi, (_amxx_DynaFuncStart.call-_amxx_DynaFuncStart.move)
|
|
||||||
mov rax, qword [GLOBAL_GATE wrt rip]
|
|
||||||
;copy the real address
|
|
||||||
mov [rdi], rax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;The gateway function we will re-assemble
|
|
||||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
|
||||||
;; and NASM > GAS :')
|
|
||||||
global amxx_DynaFunc, _amxx_DynaFunc
|
|
||||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
|
||||||
amxx_DynaFunc:
|
|
||||||
_amxx_DynaFunc:
|
|
||||||
_amxx_DynaFuncStart:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
|
|
||||||
;we're given an amx and params... we're also hardcoded for this though:
|
|
||||||
mov rdx, rsi ;move 2nd param to 3rd
|
|
||||||
mov rsi, rdi ;move 1st param to 2nd
|
|
||||||
;this old trick, we'll move in the real pointer in a bit.
|
|
||||||
.move:
|
|
||||||
mov rdi, qword 1234567812345678h
|
|
||||||
.call:
|
|
||||||
mov rcx, qword 1234567812345678h
|
|
||||||
call rcx
|
|
||||||
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
_amxx_DynaFuncEnd:
|
|
||||||
|
|
||||||
;;Just returns the buffer size required
|
|
||||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
|
||||||
;int amxx_DynaCodesize()
|
|
||||||
amxx_DynaCodesize:
|
|
||||||
_amxx_DynaCodesize:
|
|
||||||
; on x86-64 this is 34 bytes
|
|
||||||
mov rax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
||||||
ret
|
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
GLOBAL_GATE DQ 0
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
|
||||||
; register_native functions for x86 ;;;;;;
|
|
||||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
|
||||||
; Thanks to T(+)rget for pushing me to implement this ;
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
|
|
||||||
;;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.
|
|
||||||
|
|
||||||
;;Initializes the global variable
|
|
||||||
|
|
||||||
section .text
|
|
||||||
|
|
||||||
global amxx_DynaInit, _amxx_DynaInit
|
|
||||||
;void amxx_DynaInit(void *ptr);
|
|
||||||
amxx_DynaInit:
|
|
||||||
_amxx_DynaInit:
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
mov eax, [ebp+8] ;get pointer
|
|
||||||
mov [GLOBAL_GATE], eax ;store
|
|
||||||
|
|
||||||
mov eax, 1
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;Assembles the gateway function
|
|
||||||
global amxx_DynaMake, _amxx_DynaMake
|
|
||||||
;int amxx_DynaMake(char *buffer, int id);
|
|
||||||
amxx_DynaMake:
|
|
||||||
_amxx_DynaMake:
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
push edi
|
|
||||||
push esi
|
|
||||||
|
|
||||||
mov edi, [ebp+8] ;buffer
|
|
||||||
mov esi, _amxx_DynaFuncStart
|
|
||||||
mov ecx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
||||||
cld ;clear direction flag (just in case)
|
|
||||||
rep movsb
|
|
||||||
|
|
||||||
mov edi, [ebp+8] ;get buffer again
|
|
||||||
;align us to mov eax, 1234 - on x86 this is 4 bytes
|
|
||||||
add edi, (_amxx_DynaMoveOffset-_amxx_DynaFuncStart) + 1
|
|
||||||
mov eax, [ebp+12]
|
|
||||||
mov [edi], eax
|
|
||||||
|
|
||||||
pop esi
|
|
||||||
pop edi
|
|
||||||
|
|
||||||
mov eax, 1
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
;;The gateway function we will re-assemble
|
|
||||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
|
||||||
;; and NASM > GAS :')
|
|
||||||
global amxx_DynaFunc, _amxx_DynaFunc
|
|
||||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
|
||||||
amxx_DynaFunc:
|
|
||||||
_amxx_DynaFunc:
|
|
||||||
_amxx_DynaFuncStart:
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
;we're given an amx and params... we're also hardcoded for this though:
|
|
||||||
_amxx_DynaMoveOffset:
|
|
||||||
mov eax, 12345678h ;this old trick, we'll move in the real pointer in a bit.
|
|
||||||
push dword [ebp+12] ;push params
|
|
||||||
push dword [ebp+8] ;push amx
|
|
||||||
push eax ;push the id
|
|
||||||
call [GLOBAL_GATE] ;pass through teh global gateway.
|
|
||||||
add esp, 12 ;reset stack oops
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
_amxx_DynaFuncEnd:
|
|
||||||
|
|
||||||
;;Just returns the buffer size required
|
|
||||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
|
||||||
;int amxx_DynaCodesize()
|
|
||||||
amxx_DynaCodesize:
|
|
||||||
_amxx_DynaCodesize:
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
|
|
||||||
; on x86 is this 17 bytes
|
|
||||||
mov eax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
|
||||||
|
|
||||||
pop ebp
|
|
||||||
ret
|
|
||||||
|
|
||||||
section .data
|
|
||||||
|
|
||||||
GLOBAL_GATE DD 0
|
|
@ -1,536 +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"
|
|
||||||
#include "sh_stack.h"
|
|
||||||
#include "natives.h"
|
|
||||||
#include "debugger.h"
|
|
||||||
#include "libraries.h"
|
|
||||||
#include "format.h"
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include "sclinux.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Written by David "BAILOPAN" Anderson
|
|
||||||
//With the exception for param_convert, which was written by
|
|
||||||
// Julien "dJeyL" Laurent
|
|
||||||
|
|
||||||
CVector<regnative *> g_RegNatives;
|
|
||||||
static char g_errorStr[512] = {0};
|
|
||||||
bool g_Initialized = false;
|
|
||||||
|
|
||||||
/* Stack stuff */
|
|
||||||
regnative *g_pCurNative = NULL;
|
|
||||||
AMX *g_pCaller = NULL;
|
|
||||||
cell g_Params[CALLFUNC_MAXPARAMS];
|
|
||||||
int g_CurError = AMX_ERR_NONE;
|
|
||||||
|
|
||||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
regnative *pNative = g_RegNatives[idx];
|
|
||||||
int numParams = params[0] / sizeof(cell);
|
|
||||||
|
|
||||||
if (numParams > CALLFUNC_MAXPARAMS)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative with too many parameters (%d)", CALLFUNC_MAXPARAMS);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save old values on ZE STACK */
|
|
||||||
AMX *pSaveCaller = g_pCaller;
|
|
||||||
cell saveParams[CALLFUNC_MAXPARAMS];
|
|
||||||
regnative *pSaveNative = g_pCurNative;
|
|
||||||
int saveError = g_CurError;
|
|
||||||
|
|
||||||
if (pSaveNative)
|
|
||||||
{
|
|
||||||
for (ucell i = 0; i <= g_Params[0] / sizeof(cell); i++)
|
|
||||||
{
|
|
||||||
saveParams[i] = g_Params[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Save current info */
|
|
||||||
g_CurError = AMX_ERR_NONE;
|
|
||||||
g_pCaller = amx;
|
|
||||||
g_pCurNative = pNative;
|
|
||||||
|
|
||||||
int err = 0;
|
|
||||||
cell ret = 0;
|
|
||||||
if (pNative->style == 0)
|
|
||||||
{
|
|
||||||
amx_Push(pNative->amx, numParams);
|
|
||||||
amx_Push(pNative->amx, pPlugin->getId());
|
|
||||||
for (int i=numParams; i>=0; i--)
|
|
||||||
{
|
|
||||||
g_Params[i] = params[i];
|
|
||||||
}
|
|
||||||
} else if (pNative->style == 1) {
|
|
||||||
/**
|
|
||||||
* use dJeyL's system .. very clever!
|
|
||||||
* NOTE: clever, but doesn't work at all since the JIT does bounds checking
|
|
||||||
* this should REALLY be deprecated
|
|
||||||
*/
|
|
||||||
for (int i=numParams; i>=1; i--)
|
|
||||||
{
|
|
||||||
amx_Push(pNative->amx, params[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
|
||||||
if (pDebugger)
|
|
||||||
{
|
|
||||||
pDebugger->BeginExec();
|
|
||||||
}
|
|
||||||
|
|
||||||
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
if (pDebugger && pDebugger->ErrorExists())
|
|
||||||
{
|
|
||||||
//don't care
|
|
||||||
} else if (err != -1) {
|
|
||||||
//nothing logged the error
|
|
||||||
LogError(pNative->amx, err, NULL);
|
|
||||||
}
|
|
||||||
pNative->amx->error = AMX_ERR_NONE;
|
|
||||||
//furthermore, log an error in the parent plugin.
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
|
|
||||||
} else if (g_CurError != AMX_ERR_NONE) {
|
|
||||||
LogError(amx, g_CurError, g_errorStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDebugger)
|
|
||||||
{
|
|
||||||
pDebugger->EndExec();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore everything */
|
|
||||||
g_pCurNative = pSaveNative;
|
|
||||||
g_CurError = saveError;
|
|
||||||
g_pCaller = pSaveCaller;
|
|
||||||
if (pSaveNative)
|
|
||||||
{
|
|
||||||
for (ucell i = 0; i <= saveParams[0] / sizeof(cell); i++)
|
|
||||||
{
|
|
||||||
g_Params[i] = saveParams[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO *BuildNativeTable()
|
|
||||||
{
|
|
||||||
if (g_RegNatives.size() < 1)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO info;
|
|
||||||
regnative *pNative;
|
|
||||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
|
||||||
{
|
|
||||||
pNative = g_RegNatives[i];
|
|
||||||
info.name = pNative->name.c_str();
|
|
||||||
info.func = (AMX_NATIVE)((void *)(pNative->pfn));
|
|
||||||
pNatives[i] = info;
|
|
||||||
}
|
|
||||||
pNatives[g_RegNatives.size()].name = NULL;
|
|
||||||
pNatives[g_RegNatives.size()].func = NULL;
|
|
||||||
|
|
||||||
//this needs to be deleted
|
|
||||||
return pNatives;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *err = format_amxstring(amx, params, 2, len);
|
|
||||||
|
|
||||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
|
||||||
g_CurError = params[1];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get_string(param, dest[], len)
|
|
||||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *str = get_amxstring(g_pCaller, g_Params[p], 0, len);
|
|
||||||
return set_amxstring(amx, params[2], str, params[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//set_string(param, source[], maxlen)
|
|
||||||
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *str = get_amxstring(amx, params[2], 0, len);
|
|
||||||
|
|
||||||
return set_amxstring(g_pCaller, g_Params[p], str, params[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//get a byvalue parameter
|
|
||||||
//get_param(num)
|
|
||||||
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
return g_Params[p];
|
|
||||||
}
|
|
||||||
|
|
||||||
//get_param_byref(num)
|
|
||||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
|
||||||
|
|
||||||
return addr[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//set_param_byref(num, val)
|
|
||||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
|
||||||
|
|
||||||
addr[0] = params[2];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get_array(param, dest[], size)
|
|
||||||
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *source = get_amxaddr(g_pCaller, g_Params[p]);
|
|
||||||
cell *dest = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
int size = params[3];
|
|
||||||
|
|
||||||
memcpy(dest, source, size * sizeof(cell));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set_array(param, source[], size)
|
|
||||||
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *dest = get_amxaddr(g_pCaller, g_Params[p]);
|
|
||||||
cell *source = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
int size = params[3];
|
|
||||||
|
|
||||||
memcpy(dest, source, size * sizeof(cell));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_pCurNative->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]);
|
|
||||||
|
|
||||||
cell max = g_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(g_pCaller, g_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, g_pCaller, g_Params, &vargPos);
|
|
||||||
|
|
||||||
/* copy back */
|
|
||||||
memcpy(realdest, dest, (total+1) * sizeof(cell));
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is basically right from dJeyL's lib_convert function
|
|
||||||
//This awesome hack modifies the stack frame to have an address offset
|
|
||||||
// that will align to the other plugin's memory.
|
|
||||||
//I've no idea how he thought of this, but it's great. No idea how well it works.
|
|
||||||
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_pCurNative->style != 1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
cell p = params[1];
|
|
||||||
|
|
||||||
AMX *caller = g_pCaller;
|
|
||||||
|
|
||||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
|
||||||
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
|
||||||
|
|
||||||
* (cell *)(data+(int)amx->frm+(p+2)*sizeof(cell)) -= (cell)data-(cell)realdata;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
|
||||||
|
|
||||||
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//register_native(const name[], const handler[])
|
|
||||||
static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_Initialized)
|
|
||||||
amxx_DynaInit((void *)(amxx_DynaCallback));
|
|
||||||
|
|
||||||
g_Initialized = true;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *name = get_amxstring(amx, params[1], 0, len);
|
|
||||||
char *func = get_amxstring(amx, params[2], 1, len);
|
|
||||||
|
|
||||||
int idx, err;
|
|
||||||
if ( (err=amx_FindPublic(amx, func, &idx)) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
LogError(amx, err, "Function \"%s\" was not found", func);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
regnative *pNative = new regnative;
|
|
||||||
pNative->amx = amx;
|
|
||||||
pNative->func = idx;
|
|
||||||
|
|
||||||
//we'll apply a safety buffer too
|
|
||||||
//make our function
|
|
||||||
int size = amxx_DynaCodesize();
|
|
||||||
#ifndef __linux__
|
|
||||||
DWORD temp;
|
|
||||||
pNative->pfn = new char[size + 10];
|
|
||||||
VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
|
|
||||||
#else
|
|
||||||
pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
|
|
||||||
mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int id = (int)g_RegNatives.size();
|
|
||||||
|
|
||||||
amxx_DynaMake(pNative->pfn, id);
|
|
||||||
pNative->func = idx;
|
|
||||||
pNative->style = params[3];
|
|
||||||
|
|
||||||
g_RegNatives.push_back(pNative);
|
|
||||||
|
|
||||||
pNative->name.assign(name);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearPluginLibraries()
|
|
||||||
{
|
|
||||||
ClearLibraries(LibSource_Plugin);
|
|
||||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
|
||||||
{
|
|
||||||
delete [] g_RegNatives[i]->pfn;
|
|
||||||
delete g_RegNatives[i];
|
|
||||||
}
|
|
||||||
g_RegNatives.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_NativeNatives[] = {
|
|
||||||
{"register_native", register_native},
|
|
||||||
{"log_error", log_error},
|
|
||||||
{"register_library",register_library},
|
|
||||||
{"get_string", get_string},
|
|
||||||
{"set_string", set_string},
|
|
||||||
{"get_param", get_param},
|
|
||||||
{"get_param_byref", get_param_byref},
|
|
||||||
{"set_param_byref", set_param_byref},
|
|
||||||
{"get_array", get_array},
|
|
||||||
{"set_array", set_array},
|
|
||||||
//these are dummy functions for floats ;p
|
|
||||||
{"get_param_f", get_param},
|
|
||||||
{"get_float_byref", get_param_byref},
|
|
||||||
{"set_float_byref", set_param_byref},
|
|
||||||
{"get_array_f", get_array},
|
|
||||||
{"set_array_f", set_array},
|
|
||||||
{"vdformat", vdformat},
|
|
||||||
{"param_convert", param_convert},
|
|
||||||
//////////////////////////
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
@ -1,67 +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_NATIVES_H
|
|
||||||
#define _INCLUDE_NATIVES_H
|
|
||||||
|
|
||||||
//only 16 for now sorry
|
|
||||||
#if !defined CALLFUNC_MAXPARAMS
|
|
||||||
#define CALLFUNC_MAXPARAMS 16
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CALLFUNC_FLAG_BYREF 1
|
|
||||||
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
|
||||||
|
|
||||||
#define N_CELL 1
|
|
||||||
#define N_ARRAY 2
|
|
||||||
#define N_BYREF 3
|
|
||||||
#define N_VARARG 4
|
|
||||||
|
|
||||||
struct regnative
|
|
||||||
{
|
|
||||||
AMX *amx;
|
|
||||||
String name;
|
|
||||||
char *pfn;
|
|
||||||
int func;
|
|
||||||
int style;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" void amxx_DynaInit(void *ptr);
|
|
||||||
extern "C" void amxx_DynaMake(char *buffer, int id);
|
|
||||||
extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
|
||||||
extern "C" int amxx_DynaCodesize();
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO *BuildNativeTable();
|
|
||||||
void ClearPluginLibraries();
|
|
||||||
|
|
||||||
//I couldn't resist :)
|
|
||||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_NATIVES_H
|
|
1096
amxmodx/newmenus.cpp
1096
amxmodx/newmenus.cpp
File diff suppressed because it is too large
Load Diff
@ -1,155 +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_NEWMENUS_H
|
|
||||||
#define _INCLUDE_NEWMENUS_H
|
|
||||||
|
|
||||||
#define MENU_EXIT -3
|
|
||||||
#define MENU_BACK -2
|
|
||||||
#define MENU_MORE -1
|
|
||||||
#define ITEM_IGNORE 0
|
|
||||||
#define ITEM_ENABLED 1
|
|
||||||
#define ITEM_DISABLED 2
|
|
||||||
|
|
||||||
#define MAX_MENU_ITEMS 10
|
|
||||||
|
|
||||||
#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
|
|
||||||
#define MPROP_SET_NUMBER_COLOR 10
|
|
||||||
|
|
||||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
|
||||||
|
|
||||||
class BlankItem
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
char *m_text;
|
|
||||||
bool m_num;
|
|
||||||
public:
|
|
||||||
BlankItem() : m_text(NULL), m_num(false) { }
|
|
||||||
BlankItem(BlankItem &src) { this->copyFrom(src); }
|
|
||||||
~BlankItem() { free(m_text); }
|
|
||||||
|
|
||||||
void copyFrom(BlankItem &src)
|
|
||||||
{
|
|
||||||
m_text = src.m_text;
|
|
||||||
m_num = src.m_num;
|
|
||||||
src.m_text = NULL; // stop the src from freeing the buffer
|
|
||||||
}
|
|
||||||
BlankItem &operator = (const BlankItem &src) { this->copyFrom(const_cast<BlankItem&>(src)); return *this; }
|
|
||||||
|
|
||||||
/* is this text instead of a blank */
|
|
||||||
bool IsText() { return m_text != NULL; }
|
|
||||||
|
|
||||||
/* is this a blank instead of text */
|
|
||||||
bool IsBlank() { return m_text == NULL; }
|
|
||||||
|
|
||||||
/* does this item take up a number */
|
|
||||||
bool EatNumber() { return m_num; }
|
|
||||||
|
|
||||||
/* the text this item is to display */
|
|
||||||
const char *GetDisplay() { return m_text == NULL ? "" : m_text; }
|
|
||||||
|
|
||||||
/* sets this item to use a blank */
|
|
||||||
void SetBlank() { free(m_text); m_text = NULL; }
|
|
||||||
|
|
||||||
/* sets this item to display text */
|
|
||||||
void SetText(const char *text) { free(m_text); m_text = strdup(text); }
|
|
||||||
|
|
||||||
/* sets whether or not this item takes up a line */
|
|
||||||
void SetEatNumber(bool val) { m_num = val; }
|
|
||||||
|
|
||||||
};
|
|
||||||
struct menuitem
|
|
||||||
{
|
|
||||||
String name;
|
|
||||||
String cmd;
|
|
||||||
|
|
||||||
int access;
|
|
||||||
int handler;
|
|
||||||
|
|
||||||
MENUITEM_CALLBACK pfn;
|
|
||||||
size_t id;
|
|
||||||
|
|
||||||
CVector<BlankItem> blanks;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef unsigned int menu_t;
|
|
||||||
typedef unsigned int item_t;
|
|
||||||
typedef unsigned int page_t;
|
|
||||||
|
|
||||||
class Menu
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Menu(const char *title, AMX *amx, int fid);
|
|
||||||
~Menu();
|
|
||||||
|
|
||||||
menuitem *GetMenuItem(item_t item);
|
|
||||||
size_t GetPageCount();
|
|
||||||
size_t GetItemCount();
|
|
||||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
|
||||||
|
|
||||||
const char *GetTextString(int player, page_t page, int &keys);
|
|
||||||
bool Display(int player, page_t page);
|
|
||||||
|
|
||||||
int PagekeyToItem(page_t page, item_t key);
|
|
||||||
int GetMenuMenuid();
|
|
||||||
public:
|
|
||||||
CVector<menuitem * > m_Items;
|
|
||||||
String m_Title;
|
|
||||||
String m_Text;
|
|
||||||
|
|
||||||
String m_OptNames[4];
|
|
||||||
|
|
||||||
String m_ItemColor;
|
|
||||||
bool m_NeverExit;
|
|
||||||
bool m_AutoColors;
|
|
||||||
|
|
||||||
int menuId;
|
|
||||||
int thisId;
|
|
||||||
int func;
|
|
||||||
bool isDestroying;
|
|
||||||
public:
|
|
||||||
unsigned int items_per_page;
|
|
||||||
};
|
|
||||||
|
|
||||||
void ClearMenus();
|
|
||||||
|
|
||||||
extern CVector<Menu *> g_NewMenus;
|
|
||||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_NEWMENUS_H
|
|
@ -1,23 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "nongpl_matches.h"
|
|
||||||
|
|
||||||
NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[] =
|
|
||||||
{
|
|
||||||
{"Live", "CZ Gun Game", "czgungame.amxx"},
|
|
||||||
{"Live", "AMXX 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,51 +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_AMXMODX_NONGPL_MATCHES_H_
|
|
||||||
#define _INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
|
||||||
|
|
||||||
struct NONGPL_PLUGIN_T
|
|
||||||
{
|
|
||||||
const char *author;
|
|
||||||
const char *title;
|
|
||||||
const char *filename;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NONGPL_CVAR_T
|
|
||||||
{
|
|
||||||
const char *cvar;
|
|
||||||
int type;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[];
|
|
||||||
extern NONGPL_CVAR_T NONGPL_CVAR_LIST[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user