Compare commits
1 Commits
amxmodx-1.
...
amxmodx-0.
Author | SHA1 | Date | |
---|---|---|---|
62e6b1c859 |
@ -35,9 +35,7 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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;
|
||||||
@ -51,9 +49,10 @@ 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);
|
||||||
@ -79,21 +78,17 @@ CmdMngr::Command* CmdMngr::registerCommand(CPluginMngr::CPlugin* plugin, int fun
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +98,9 @@ CmdMngr::Command* CmdMngr::getCmd(long int id, int type, int access)
|
|||||||
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;
|
||||||
@ -111,11 +108,17 @@ CmdMngr::Command* CmdMngr::getCmd(long int id, int type, int access)
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +138,10 @@ int CmdMngr::getCmdNum(int type, int access)
|
|||||||
|
|
||||||
while ( a )
|
while ( a )
|
||||||
{
|
{
|
||||||
if ((*a).gotAccess(access) && (*a).getPlugin()->isExecutable((*a).getFunction()) && (*a).isViewable())
|
|
||||||
|
if ( (*a).gotAccess( access ) &&
|
||||||
|
(*a).getPlugin()->isExecutable( (*a).getFunction() )
|
||||||
|
&& (*a).isViewable() )
|
||||||
++buf_num;
|
++buf_num;
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
@ -163,18 +169,20 @@ void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
|
|||||||
|
|
||||||
np->next = *a;
|
np->next = *a;
|
||||||
*a = np;
|
*a = np;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while ( *a ) a = &(*a)->next;
|
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;
|
||||||
@ -183,51 +191,39 @@ void CmdMngr::clearCmdLink(CmdLink** phead, bool pclear)
|
|||||||
|
|
||||||
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 );
|
parent->setCmdLink( &parent->sortedlists[1] , this );
|
||||||
|
|
||||||
if ( !parent->registerCmdPrefix( this ) )
|
if ( !parent->registerCmdPrefix( this ) )
|
||||||
parent->setCmdLink( &parent->clcmdlist , this , false );
|
parent->setCmdLink( &parent->clcmdlist , this , false );
|
||||||
}
|
}
|
||||||
|
if ( cmdtype & 2 ) { // ServerCommand
|
||||||
if (cmdtype & 2) // ServerCommand
|
|
||||||
{
|
|
||||||
parent->setCmdLink( &parent->sortedlists[2] , this );
|
parent->setCmdLink( &parent->sortedlists[2] , this );
|
||||||
parent->setCmdLink( &parent->srvcmdlist , this , false );
|
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 1: return"client";
|
||||||
case 2: return "server";
|
case 2: return "server";
|
||||||
case 3: return "console";
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,29 +231,22 @@ void CmdMngr::registerPrefix(const char* nn)
|
|||||||
{
|
{
|
||||||
if ( *nn == 0 ) return;
|
if ( *nn == 0 ) return;
|
||||||
CmdPrefix** b = findPrefix( nn );
|
CmdPrefix** b = findPrefix( nn );
|
||||||
|
|
||||||
if (*b) return;
|
if (*b) return;
|
||||||
*b = new CmdPrefix( nn , this );
|
*b = new CmdPrefix( nn , this );
|
||||||
}
|
}
|
||||||
|
|
||||||
CmdMngr::CmdPrefix** CmdMngr::findPrefix(const char* nn)
|
CmdMngr::CmdPrefix** CmdMngr::findPrefix( const char* nn ){
|
||||||
{
|
|
||||||
CmdPrefix** aa = &prefixHead;
|
CmdPrefix** aa = &prefixHead;
|
||||||
|
while(*aa){
|
||||||
while (*aa)
|
|
||||||
{
|
|
||||||
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
|
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
|
||||||
break;
|
break;
|
||||||
aa=&(*aa)->next;
|
aa=&(*aa)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return aa;
|
return aa;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::clearPrefix()
|
void CmdMngr::clearPrefix(){
|
||||||
{
|
while(prefixHead){
|
||||||
while (prefixHead)
|
|
||||||
{
|
|
||||||
CmdPrefix* a = prefixHead->next;
|
CmdPrefix* a = prefixHead->next;
|
||||||
delete prefixHead;
|
delete prefixHead;
|
||||||
prefixHead = a;
|
prefixHead = a;
|
||||||
@ -275,8 +264,7 @@ void CmdMngr::clear()
|
|||||||
clearBufforedInfo();
|
clearBufforedInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdMngr::clearBufforedInfo()
|
void CmdMngr::clearBufforedInfo() {
|
||||||
{
|
|
||||||
buf_type = -1;
|
buf_type = -1;
|
||||||
buf_access = 0;
|
buf_access = 0;
|
||||||
buf_id = -1;
|
buf_id = -1;
|
||||||
|
@ -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,10 +63,10 @@ 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(); }
|
||||||
@ -83,17 +79,17 @@ public:
|
|||||||
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,8 +99,7 @@ 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;
|
||||||
@ -127,16 +122,13 @@ public:
|
|||||||
// 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
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
|||||||
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
|
||||||
@ -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;
|
||||||
|
|
||||||
@ -229,6 +221,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
|||||||
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;
|
||||||
@ -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,7 +284,6 @@ 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)
|
||||||
@ -310,7 +301,6 @@ void EventsMngr::parseValue(int iValue)
|
|||||||
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,7 +330,6 @@ 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)
|
||||||
@ -352,12 +342,10 @@ void EventsMngr::parseValue(float fValue)
|
|||||||
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,7 +374,6 @@ 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)
|
||||||
@ -398,12 +385,10 @@ void EventsMngr::parseValue(const char *sz)
|
|||||||
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,11 +396,17 @@ void EventsMngr::parseValue(const char *sz)
|
|||||||
|
|
||||||
void EventsMngr::executeEvents()
|
void EventsMngr::executeEvents()
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
if (!m_ParseFun)
|
if (!m_ParseFun)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||||
{
|
{
|
||||||
if ( (*iter).m_Done )
|
if ( (*iter).m_Done )
|
||||||
@ -425,8 +416,21 @@ void EventsMngr::executeEvents()
|
|||||||
}
|
}
|
||||||
|
|
||||||
(*iter).m_Stamp = (float)*m_Timer;
|
(*iter).m_Stamp = (float)*m_Timer;
|
||||||
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
}
|
||||||
|
catch( ... )
|
||||||
|
{
|
||||||
|
AMXXLOG_Log( "[AMXX] fatal error at event execution");
|
||||||
|
}
|
||||||
|
#endif // #ifdef ENABLEEXEPTIONS
|
||||||
|
|
||||||
m_CurrentMsgType = -1;
|
m_CurrentMsgType = -1;
|
||||||
m_ParseFun = NULL;
|
m_ParseFun = NULL;
|
||||||
@ -481,9 +485,9 @@ float EventsMngr::getArgFloat(int a) const
|
|||||||
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)
|
||||||
{
|
{
|
||||||
@ -523,7 +526,6 @@ int EventsMngr::getEventId(const char* msg)
|
|||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
|
@ -34,8 +34,7 @@
|
|||||||
|
|
||||||
#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,
|
||||||
@ -117,7 +116,6 @@ 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
|
||||||
@ -142,13 +140,11 @@ 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;
|
||||||
@ -158,4 +154,6 @@ public:
|
|||||||
int getCurrentMsgType();
|
int getCurrentMsgType();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__CEVENTS_H__
|
#endif // #ifdef __CEVENTS_H__
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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 );
|
||||||
@ -71,6 +70,7 @@ File& operator<<(File& f, int 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 ) ;
|
||||||
@ -96,7 +96,6 @@ int File::getline(char* buf, int sz)
|
|||||||
{
|
{
|
||||||
int a = sz;
|
int a = sz;
|
||||||
char *origBuf = buf;
|
char *origBuf = buf;
|
||||||
|
|
||||||
if ( *this )
|
if ( *this )
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@ -124,3 +123,4 @@ File& File::skipWs()
|
|||||||
ungetc( c , fp );
|
ungetc( c , fp );
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +43,16 @@ class File
|
|||||||
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 String& n );
|
||||||
friend File& operator<<( File& f, const char* n );
|
friend File& operator<<( File& f, const char* n );
|
||||||
friend File& operator<<( File& f, const char& c );
|
friend File& operator<<( File& f, const char& c );
|
||||||
friend File& operator<<( File& f, int n );
|
friend File& operator<<( File& f, int n );
|
||||||
friend File& operator>>( File& f, String& n );
|
friend File& operator>>( File& f, String& n );
|
||||||
friend File& operator>>( File& f, char* n );
|
friend File& operator>>( File& f, char* n );
|
||||||
|
|
||||||
int getline( char* buf, int sz );
|
int getline( char* buf, int sz );
|
||||||
|
|
||||||
File& skipWs( );
|
File& skipWs( );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,21 +30,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "debugger.h"
|
|
||||||
|
|
||||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
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;
|
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 ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
||||||
@ -74,74 +70,47 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
{
|
{
|
||||||
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, ax = 0;
|
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)
|
||||||
{
|
{
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
amx_Allot(iter->pPlugin->getAMX(),
|
||||||
amx_SetStringOld(tmp, (const char *)(params[i]), 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(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;
|
cell retVal;
|
||||||
int err = amx_Exec(amx, &retVal, iter->func);
|
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
||||||
|
|
||||||
// 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)
|
||||||
@ -153,25 +122,23 @@ 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];
|
cell *tmp = physAddrs[i];
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +164,6 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return globRetVal;
|
return globRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +174,6 @@ void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *para
|
|||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -217,14 +182,10 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
|
|||||||
m_NumParams = numParams;
|
m_NumParams = numParams;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
{
|
{
|
||||||
if (isFree)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const int STRINGEX_MAXLENGTH = 128;
|
const int STRINGEX_MAXLENGTH = 128;
|
||||||
|
|
||||||
cell realParams[FORWARD_MAX_PARAMS];
|
cell realParams[FORWARD_MAX_PARAMS];
|
||||||
@ -237,67 +198,45 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
if (!pPlugin->isExecutable(m_Func))
|
if (!pPlugin->isExecutable(m_Func))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
amx_Allot(m_Amx,
|
||||||
amx_SetStringOld(tmp, (const char *)(params[i]), 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;
|
||||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams);
|
||||||
|
|
||||||
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)
|
||||||
@ -309,25 +248,23 @@ 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];
|
cell *tmp = physAddrs[i];
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
{
|
{
|
||||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
amx_Release(m_Amx, realParams[i]);
|
amx_Release(m_Amx, realParams[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,48 +276,30 @@ int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int
|
|||||||
{
|
{
|
||||||
int retVal = m_Forwards.size() << 1;
|
int retVal = m_Forwards.size() << 1;
|
||||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
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.size())
|
||||||
if (!m_FreeSPForwards.empty())
|
|
||||||
{
|
{
|
||||||
retVal = m_FreeSPForwards.front();
|
pForward = m_SPForwards[m_FreeSPForwards.back()];
|
||||||
pForward = m_SPForwards[retVal >> 1];
|
m_FreeSPForwards.pop_back();
|
||||||
pForward->Set(func, amx, numParams, paramTypes);
|
pForward->Set(func, amx, numParams, paramTypes);
|
||||||
|
}
|
||||||
if (pForward->getFuncsNum() == 0)
|
else
|
||||||
return -1;
|
{
|
||||||
|
|
||||||
m_FreeSPForwards.pop();
|
|
||||||
} 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)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
delete pForward;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_SPForwards.push_back(pForward);
|
m_SPForwards.push_back(pForward);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,58 +307,42 @@ 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.size())
|
||||||
if (!m_FreeSPForwards.empty())
|
|
||||||
{
|
{
|
||||||
retVal = m_FreeSPForwards.front();
|
pForward = m_SPForwards[m_FreeSPForwards.back()];
|
||||||
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
|
m_FreeSPForwards.pop_back();
|
||||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||||
|
}
|
||||||
if (pForward->getFuncsNum() == 0)
|
else
|
||||||
return -1;
|
{
|
||||||
|
|
||||||
m_FreeSPForwards.pop();
|
|
||||||
} 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)
|
|
||||||
{
|
|
||||||
delete pForward;
|
|
||||||
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 = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) :
|
||||||
|
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CForwardMngr::clear()
|
void CForwardMngr::clear()
|
||||||
@ -448,9 +351,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);
|
||||||
@ -458,10 +359,7 @@ void CForwardMngr::clear()
|
|||||||
|
|
||||||
m_Forwards.clear();
|
m_Forwards.clear();
|
||||||
m_SPForwards.clear();
|
m_SPForwards.clear();
|
||||||
|
m_FreeSPForwards.clear();
|
||||||
while (!m_FreeSPForwards.empty())
|
|
||||||
m_FreeSPForwards.pop();
|
|
||||||
|
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,98 +370,69 @@ bool CForwardMngr::isSPForward(int id) const
|
|||||||
|
|
||||||
void CForwardMngr::unregisterSPForward(int id)
|
void CForwardMngr::unregisterSPForward(int id)
|
||||||
{
|
{
|
||||||
//make sure the id is valid
|
m_FreeSPForwards.push_back(id);
|
||||||
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_SPForwards.at(id >> 1)->isFree = true;
|
|
||||||
m_FreeSPForwards.push(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
int 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 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,58 +442,38 @@ 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 (params[i] == FP_FLOAT)
|
||||||
{
|
{
|
||||||
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,7 +46,7 @@
|
|||||||
#ifndef FORWARD_H
|
#ifndef FORWARD_H
|
||||||
#define FORWARD_H
|
#define FORWARD_H
|
||||||
|
|
||||||
const int FORWARD_MAX_PARAMS = 32;
|
const int FORWARD_MAX_PARAMS = 16;
|
||||||
|
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
{
|
{
|
||||||
@ -77,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
|
||||||
@ -90,41 +87,27 @@ class CForward
|
|||||||
const char *m_FuncName;
|
const char *m_FuncName;
|
||||||
ForwardExecType m_ExecType;
|
ForwardExecType m_ExecType;
|
||||||
int m_NumParams;
|
int m_NumParams;
|
||||||
|
|
||||||
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);
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
ForwardParam getParamType(int paramId) const
|
|
||||||
{
|
|
||||||
if (paramId < 0 || paramId >= m_NumParams)
|
|
||||||
return FP_DONE;
|
|
||||||
|
|
||||||
return m_ParamTypes[paramId];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Single plugin forward
|
// Single plugin forward
|
||||||
@ -132,46 +115,31 @@ class CSPForward
|
|||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
public:
|
|
||||||
bool isFree;
|
|
||||||
public:
|
public:
|
||||||
CSPForward() { m_HasFunc = false; }
|
CSPForward() { m_HasFunc = false; }
|
||||||
void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
ForwardParam getParamType(int paramId) const
|
|
||||||
{
|
|
||||||
if (paramId < 0 || paramId >= m_NumParams)
|
|
||||||
return FP_DONE;
|
|
||||||
|
|
||||||
return m_ParamTypes[paramId];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CForwardMngr
|
class CForwardMngr
|
||||||
{
|
{
|
||||||
typedef CVector<CForward*> ForwardVec;
|
typedef CVector<CForward*> ForwardVec;
|
||||||
typedef CVector<CSPForward*> SPForwardVec;
|
typedef CVector<CSPForward*> SPForwardVec;
|
||||||
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
typedef CVector<int> FreeSPVec; // Free SP Forwards
|
||||||
|
|
||||||
ForwardVec m_Forwards;
|
ForwardVec m_Forwards;
|
||||||
|
|
||||||
@ -184,7 +152,8 @@ public:
|
|||||||
|
|
||||||
CForwardMngr()
|
CForwardMngr()
|
||||||
{ m_TmpArraysNum = 0; }
|
{ m_TmpArraysNum = 0; }
|
||||||
~CForwardMngr() {}
|
~CForwardMngr()
|
||||||
|
{ }
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
// Register normal forward
|
// Register normal forward
|
||||||
@ -192,21 +161,16 @@ public:
|
|||||||
// Register single plugin forward
|
// Register single plugin forward
|
||||||
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
|
||||||
// Unregister single plugin forward
|
// Unregister single plugin forward
|
||||||
void unregisterSPForward(int id);
|
void unregisterSPForward(int id);
|
||||||
|
|
||||||
// execute forward
|
// execute forward
|
||||||
cell executeForwards(int id, cell *params);
|
cell executeForwards(int id, cell *params);
|
||||||
void clear(); // delete all forwards
|
void clear(); // delete all forwards
|
||||||
|
|
||||||
bool isIdValid(int id) const; // check whether forward id is valid
|
bool isIdValid(int id) const; // check whether forward id is valid
|
||||||
bool isSPForward(int id) const; // check whether forward is single plugin
|
bool isSPForward(int id) const; // check whether forward is single plugin
|
||||||
int getParamsNum(int id) const; // get num of params of a forward
|
int getParamsNum(int id) const; // get num of params of a forward
|
||||||
int getFuncsNum(int id) const; // get num of found functions of a forward
|
int getFuncsNum(int id) const; // get num of found functions of a forward
|
||||||
|
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type); // prepare array
|
||||||
ForwardParam getParamType(int id, int paramId) const;
|
|
||||||
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// (un)register forward
|
// (un)register forward
|
||||||
@ -218,7 +182,8 @@ 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
|
|
||||||
|
@ -33,10 +33,6 @@
|
|||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "CLang.h"
|
#include "CLang.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#define _snprintf snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LITIDX_NONE 0
|
#define LITIDX_NONE 0
|
||||||
#define LITIDX_BRACKET 1
|
#define LITIDX_BRACKET 1
|
||||||
#define LITIDX_DEFINITION 2
|
#define LITIDX_DEFINITION 2
|
||||||
@ -51,6 +47,15 @@
|
|||||||
#define FFHL_VERSION 4
|
#define FFHL_VERSION 4
|
||||||
#define FFHL_MIN_VERSION 4
|
#define FFHL_MIN_VERSION 4
|
||||||
|
|
||||||
|
#define NEXT_PARAM() \
|
||||||
|
if (parm > paramCount) \
|
||||||
|
{ \
|
||||||
|
strcpy(outbuf, ""); \
|
||||||
|
len = 0; \
|
||||||
|
AMXXLOG_Log("[AMXX] Plugin did not format a string correctly (parameter %d (total %d), line %d, \"%s\")", parm, paramCount, amx->curline, g_plugins.findPluginFast(amx)); \
|
||||||
|
return outbuf; \
|
||||||
|
}
|
||||||
|
|
||||||
/*version history:
|
/*version history:
|
||||||
* 1 (BAILOPAN) - Simplest form possible, no reverse
|
* 1 (BAILOPAN) - Simplest form possible, no reverse
|
||||||
* 2 (BAILOPAN) - One language per file with full reverse
|
* 2 (BAILOPAN) - One language per file with full reverse
|
||||||
@ -184,7 +189,6 @@ size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
|
|||||||
}
|
}
|
||||||
|
|
||||||
newstr[pos] = 0;
|
newstr[pos] = 0;
|
||||||
|
|
||||||
return ptr - str + 1;
|
return ptr - str + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +310,6 @@ void CLangMngr::CLang::Clear()
|
|||||||
if (m_LookUpTable[i])
|
if (m_LookUpTable[i])
|
||||||
delete m_LookUpTable[i];
|
delete m_LookUpTable[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LookUpTable.clear();
|
m_LookUpTable.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,13 +337,11 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
|
|||||||
{
|
{
|
||||||
const char *def = 0;
|
const char *def = 0;
|
||||||
int key = -1;
|
int key = -1;
|
||||||
|
|
||||||
while (!vec.empty())
|
while (!vec.empty())
|
||||||
{
|
{
|
||||||
key = vec.front()->key;
|
key = vec.front()->key;
|
||||||
def = vec.front()->def->c_str();
|
def = vec.front()->def->c_str();
|
||||||
LangEntry *entry = GetEntry(key);
|
LangEntry *entry = GetEntry(key);
|
||||||
|
|
||||||
if (entry->GetDefHash() != MakeHash(def))
|
if (entry->GetDefHash() != MakeHash(def))
|
||||||
{
|
{
|
||||||
if (entry->GetCache())
|
if (entry->GetCache())
|
||||||
@ -349,10 +350,9 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
|
|||||||
entry->SetKey(key);
|
entry->SetKey(key);
|
||||||
entry->SetCache(false);
|
entry->SetCache(false);
|
||||||
} else {
|
} else {
|
||||||
//AMXXLOG_Log("[AMXX] Language key %s[%s] defined twice", m_LMan->GetKey(key), m_LanguageName);
|
AMXXLOG_Log("[AMXX] Language key %s[%s] defined twice", m_LMan->GetKey(key), m_LanguageName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete vec.front();
|
delete vec.front();
|
||||||
vec.pop();
|
vec.pop();
|
||||||
}
|
}
|
||||||
@ -362,22 +362,20 @@ const char * CLangMngr::CLang::GetDef(const char *key)
|
|||||||
{
|
{
|
||||||
static char nfind[1024] = "ML_NOTFOUND(KEY)";
|
static char nfind[1024] = "ML_NOTFOUND(KEY)";
|
||||||
int ikey = m_LMan->GetKeyEntry(key);
|
int ikey = m_LMan->GetKeyEntry(key);
|
||||||
|
|
||||||
if (ikey == -1)
|
if (ikey == -1)
|
||||||
{
|
{
|
||||||
sprintf(nfind, "ML_NOTFOUND: %s", key);
|
sprintf(nfind, "ML_NOTFOUND: %s", key);
|
||||||
return nfind;
|
return nfind;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_LookUpTable[i]->GetKey() == ikey)
|
if (m_LookUpTable[i]->GetKey() == ikey)
|
||||||
return m_LookUpTable[i]->GetDef();
|
return m_LookUpTable[i]->GetDef();
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct OffsetPair
|
struct OffsetPair
|
||||||
{
|
{
|
||||||
uint32_t defOffset;
|
uint32_t defOffset;
|
||||||
@ -388,7 +386,6 @@ struct OffsetPair
|
|||||||
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
|
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
|
||||||
{
|
{
|
||||||
unsigned short defLen = 0;
|
unsigned short defLen = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
|
||||||
{
|
{
|
||||||
defLen = m_LookUpTable[i]->GetDefLength();
|
defLen = m_LookUpTable[i]->GetDefLength();
|
||||||
@ -431,6 +428,7 @@ bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
|
|||||||
// assumes fp is set to the right position
|
// assumes fp is set to the right position
|
||||||
bool CLangMngr::CLang::Load(FILE *fp)
|
bool CLangMngr::CLang::Load(FILE *fp)
|
||||||
{
|
{
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +469,6 @@ int CLangMngr::GetKeyEntry(const char *key)
|
|||||||
for (i = 0; i<KeyList.size(); i++)
|
for (i = 0; i<KeyList.size(); i++)
|
||||||
{
|
{
|
||||||
cmpKey = KeyList[i]->hash;
|
cmpKey = KeyList[i]->hash;
|
||||||
|
|
||||||
if (hKey == cmpKey)
|
if (hKey == cmpKey)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
@ -509,37 +506,153 @@ int CLangMngr::GetKeyEntry(String &key)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
|
const char *CLangMngr::Format(const char *src, ...)
|
||||||
LogError(amx, AMX_ERR_STACKERR, "Buffer overflow in string formatting"); \
|
{
|
||||||
outbuf[0] = 0; \
|
va_list argptr;
|
||||||
len = 0; \
|
va_start(argptr, src);
|
||||||
return outbuf; }
|
static char outbuf[4096];
|
||||||
#define CHECK_OUTPTR(offset) CHECK_PTR(outptr+offset, outbuf, sizeof(outbuf))
|
char *outptr = outbuf;
|
||||||
#define ZEROTERM(buf) buf[(sizeof(buf)/sizeof(buf[0]))-1]=0;
|
enum State
|
||||||
#define NEXT_PARAM() \
|
{
|
||||||
if (parm > paramCount) \
|
S_Normal,
|
||||||
{ \
|
S_PercentSign,
|
||||||
strcpy(outbuf, ""); \
|
};
|
||||||
len = 0; \
|
|
||||||
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", parm, paramCount); \
|
State curState = S_Normal;
|
||||||
return outbuf; \
|
while (*src)
|
||||||
|
{
|
||||||
|
if (*src == '%' && curState == S_Normal)
|
||||||
|
curState = S_PercentSign;
|
||||||
|
else if (curState == S_PercentSign)
|
||||||
|
{
|
||||||
|
switch (*src)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
char *tmpArg = va_arg(argptr, char*);
|
||||||
|
while (*tmpArg)
|
||||||
|
*outptr++ = *tmpArg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f':
|
||||||
|
case 'g':
|
||||||
|
{
|
||||||
|
char format[16];
|
||||||
|
format[0] = '%';
|
||||||
|
char *ptr = format+1;
|
||||||
|
while (!isalpha(*ptr++ = *src++))
|
||||||
|
/*nothing*/;
|
||||||
|
--src;
|
||||||
|
*ptr = 0;
|
||||||
|
sprintf(outptr, format, va_arg(argptr, double));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'L':
|
||||||
|
{
|
||||||
|
char *langName = va_arg(argptr, char*);
|
||||||
|
const char *cpLangName=NULL;
|
||||||
|
// Handle player ids (1-32) and server language
|
||||||
|
if ((int)langName == LANG_PLAYER)
|
||||||
|
{
|
||||||
|
langName = (char*)m_CurGlobId;
|
||||||
|
}
|
||||||
|
if ((int)langName == LANG_SERVER)
|
||||||
|
{
|
||||||
|
cpLangName = g_vault.get("server_language");
|
||||||
|
} else if ((int)langName >= 1 && (int)langName <= 32) {
|
||||||
|
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||||
|
{
|
||||||
|
cpLangName = g_vault.get("server_language");
|
||||||
|
} else {
|
||||||
|
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I((int)langName)->pEdict, "lang");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cpLangName = langName;
|
||||||
|
}
|
||||||
|
if (!cpLangName || strlen(cpLangName) < 1)
|
||||||
|
cpLangName = "en";
|
||||||
|
char *key = va_arg(argptr, char*);
|
||||||
|
const char *def = GetDef(cpLangName, key);
|
||||||
|
while (*def)
|
||||||
|
{
|
||||||
|
switch (*def)
|
||||||
|
{
|
||||||
|
case INSERT_NUMBER:
|
||||||
|
{
|
||||||
|
sprintf(outptr, "%d", va_arg(argptr, int));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_STRING:
|
||||||
|
{
|
||||||
|
char *tmpArg = va_arg(argptr, char*);
|
||||||
|
while (*tmpArg)
|
||||||
|
*outptr++ = *tmpArg++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_FLOAT:
|
||||||
|
{
|
||||||
|
double tmpArg = va_arg(argptr, double);
|
||||||
|
sprintf(outptr, "%f", tmpArg);
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INSERT_NEWLINE:
|
||||||
|
*outptr++ = '\n';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*outptr++ = *def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
{
|
||||||
|
char format[16];
|
||||||
|
format[0] = '%';
|
||||||
|
char *ptr = format+1;
|
||||||
|
while (!isalpha(*ptr++ = *src++))
|
||||||
|
/*nothing*/;
|
||||||
|
--src;
|
||||||
|
*ptr = 0;
|
||||||
|
sprintf(outptr, format, va_arg(argptr, int));
|
||||||
|
outptr += strlen(outptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
*outptr++ = '%';
|
||||||
|
*outptr++ = *src;
|
||||||
|
}
|
||||||
|
curState = S_Normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*outptr++ = *src;
|
||||||
|
++src;
|
||||||
|
}
|
||||||
|
*outptr++ = 0;
|
||||||
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||||
{
|
{
|
||||||
// number of parameters ( for NEXT_PARAM macro )
|
|
||||||
int paramCount = *params / sizeof(cell);
|
int paramCount = *params / sizeof(cell);
|
||||||
|
|
||||||
// the output buffer
|
|
||||||
static char outbuf[4096];
|
static char outbuf[4096];
|
||||||
char *outptr = outbuf;
|
|
||||||
cell *src = get_amxaddr(amx, params[parm++]);
|
cell *src = get_amxaddr(amx, params[parm++]);
|
||||||
|
char *outptr = outbuf;
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
S_Normal,
|
||||||
|
S_PercentSign,
|
||||||
|
};
|
||||||
|
|
||||||
|
State curState = S_Normal;
|
||||||
while (*src)
|
while (*src)
|
||||||
{
|
{
|
||||||
if (*src == '%')
|
if (*src == '%' && curState == S_Normal)
|
||||||
|
curState = S_PercentSign;
|
||||||
|
else if (curState == S_PercentSign)
|
||||||
{
|
{
|
||||||
++src;
|
|
||||||
if (*src=='L')
|
if (*src=='L')
|
||||||
{
|
{
|
||||||
cell langName = params[parm]; // "en" case (langName contains the address to the string)
|
cell langName = params[parm]; // "en" case (langName contains the address to the string)
|
||||||
@ -547,41 +660,33 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases
|
cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases
|
||||||
const char *cpLangName=NULL;
|
const char *cpLangName=NULL;
|
||||||
// Handle player ids (1-32) and server language
|
// Handle player ids (1-32) and server language
|
||||||
|
|
||||||
if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER
|
if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER
|
||||||
{
|
{
|
||||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||||
{
|
{
|
||||||
cpLangName = g_vault.get("server_language");
|
cpLangName = g_vault.get("server_language");
|
||||||
} else {
|
} else {
|
||||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
|
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
|
||||||
}
|
}
|
||||||
}
|
} else if (*pAmxLangName == LANG_SERVER) { // LANG_SERVER
|
||||||
else if (*pAmxLangName == LANG_SERVER) // LANG_SERVER
|
|
||||||
{
|
|
||||||
cpLangName = g_vault.get("server_language");
|
cpLangName = g_vault.get("server_language");
|
||||||
}
|
} else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) { // Direct Client Id
|
||||||
else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) // Direct Client Id
|
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
||||||
{
|
|
||||||
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
|
|
||||||
{
|
{
|
||||||
cpLangName = g_vault.get("server_language");
|
cpLangName = g_vault.get("server_language");
|
||||||
} else {
|
} else {
|
||||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pAmxLangName)->pEdict, "lang");
|
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(*pAmxLangName)->pEdict, "lang");
|
||||||
}
|
}
|
||||||
} else { // Language Name
|
} else { // Language Name
|
||||||
int tmplen = 0;
|
int len = 0;
|
||||||
cpLangName = get_amxstring(amx, langName, 2, tmplen);
|
cpLangName = get_amxstring(amx, langName, 2, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cpLangName || strlen(cpLangName) < 1)
|
if (!cpLangName || strlen(cpLangName) < 1)
|
||||||
cpLangName = "en";
|
cpLangName = "en";
|
||||||
|
int len = 0;
|
||||||
int tmplen = 0;
|
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
char *key = get_amxstring(amx, params[parm++], 1, tmplen);
|
char *key = get_amxstring(amx, params[parm++], 1, len);
|
||||||
const char *def = GetDef(cpLangName, key);
|
const char *def = GetDef(cpLangName, key);
|
||||||
|
|
||||||
if (def == NULL)
|
if (def == NULL)
|
||||||
{
|
{
|
||||||
if (*pAmxLangName != LANG_SERVER)
|
if (*pAmxLangName != LANG_SERVER)
|
||||||
@ -594,383 +699,146 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
|||||||
}
|
}
|
||||||
if (!def)
|
if (!def)
|
||||||
{
|
{
|
||||||
static char buf[512];
|
static char buf[255];
|
||||||
CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
|
|
||||||
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
||||||
def = buf;
|
def = buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*def)
|
while (*def)
|
||||||
{
|
{
|
||||||
if (*def == '%')
|
if (*def == '%')
|
||||||
{
|
{
|
||||||
++def;
|
++def;
|
||||||
if (*def == '%' || *def == 0)
|
char format[16];
|
||||||
{
|
|
||||||
*outptr++ = '%';
|
|
||||||
++def;
|
|
||||||
} else {
|
|
||||||
static char format[32];
|
|
||||||
format[0] = '%';
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
|
while (!isalpha(*ptr++ = *def++))
|
||||||
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
ZEROTERM(format);
|
|
||||||
|
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
|
|
||||||
switch ( *(ptr-1) )
|
switch ( *(ptr-1) )
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
static char tmpString[4096];
|
char tmpString[256];
|
||||||
char *tmpPtr = tmpString;
|
char *tmpPtr = tmpString;
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||||
while (tmpPtr-tmpString < sizeof(tmpString) && *tmpCell)
|
while (*tmpCell)
|
||||||
*tmpPtr++ = static_cast<char>(*tmpCell++);
|
*tmpPtr++ = *tmpCell++;
|
||||||
*tmpPtr = 0;
|
*tmpPtr = 0;
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
sprintf(outptr, format, tmpString);
|
||||||
ZEROTERM(outbuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
ZEROTERM(outbuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'c':
|
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||||
ZEROTERM(outbuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
CHECK_OUTPTR(strlen(format) + 1);
|
*outptr++ = '%';
|
||||||
strcpy(outptr, format);
|
*outptr++ = *(ptr-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outptr += strlen(outptr);
|
outptr += strlen(outptr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (*def == '^')
|
else if (*def == '^')
|
||||||
{
|
{
|
||||||
++def;
|
++def;
|
||||||
|
|
||||||
switch (*def)
|
switch (*def)
|
||||||
{
|
{
|
||||||
case 'n':
|
case 'n':
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '\n';
|
*outptr++ = '\n';
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '\t';
|
*outptr++ = '\t';
|
||||||
break;
|
break;
|
||||||
case '^':
|
case '^':
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '^';
|
*outptr++ = '^';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CHECK_OUTPTR(2);
|
|
||||||
*outptr++ = '^';
|
*outptr++ = '^';
|
||||||
*outptr++ = *def;
|
*outptr++ = *def;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
++def;
|
++def;
|
||||||
} else {
|
}
|
||||||
CHECK_OUTPTR(1);
|
else
|
||||||
*outptr++ = *def++;
|
*outptr++ = *def++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
static char tmpString[4096];
|
{
|
||||||
|
char tmpString[256];
|
||||||
char *tmpPtr = tmpString;
|
char *tmpPtr = tmpString;
|
||||||
int tmpLen =0;
|
int tmpLen =0;
|
||||||
static char format[32] = {'%'};
|
char format[16];
|
||||||
|
format[0] = '%';
|
||||||
char *ptr = format+1;
|
char *ptr = format+1;
|
||||||
|
|
||||||
if (*src != '%')
|
if (*src != '%')
|
||||||
{
|
{
|
||||||
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = static_cast<char>(*src++)))
|
while (!isalpha(*ptr++ = *src++))
|
||||||
/*nothing*/;
|
/*nothing*/;
|
||||||
*ptr = 0;
|
|
||||||
ZEROTERM(format);
|
|
||||||
--src;
|
--src;
|
||||||
|
*ptr = 0;
|
||||||
switch ( *(ptr-1) )
|
switch ( *(ptr-1) )
|
||||||
{
|
{
|
||||||
case 's':
|
case 's':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
cell *tmpCell = get_amxaddr(amx, params[parm++]);
|
||||||
while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell)
|
while (*tmpCell)
|
||||||
*tmpPtr++ = static_cast<char>(*tmpCell++);
|
*tmpPtr++ = *tmpCell++;
|
||||||
*tmpPtr = 0;
|
*tmpPtr = 0;
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
|
sprintf(outptr, format, tmpString);
|
||||||
ZEROTERM(outbuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'g':
|
case 'g':
|
||||||
case 'f':
|
case 'f':
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'c':
|
|
||||||
{
|
{
|
||||||
NEXT_PARAM();
|
NEXT_PARAM();
|
||||||
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
|
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++]));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
CHECK_OUTPTR(strlen(format) + 1);
|
|
||||||
strcpy(outptr, format);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outptr += strlen(outptr);
|
|
||||||
} else {
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '%';
|
*outptr++ = '%';
|
||||||
|
*outptr++ = *(ptr-1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = static_cast<char>(*src);
|
|
||||||
}
|
|
||||||
++src;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = outptr - outbuf;
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = 0;
|
|
||||||
|
|
||||||
return outbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *CLangMngr::Format(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
const char *retVal = FormatString(fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef CHECK_PTR
|
|
||||||
#undef CHECK_OUTPR
|
|
||||||
#undef ZEROTERM
|
|
||||||
#undef NEXT_PARAM
|
|
||||||
|
|
||||||
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
|
|
||||||
AMXXLOG_Log("[AMXX] Buffer overflow in formatting"); \
|
|
||||||
outbuf[0] = 0; \
|
|
||||||
return outbuf; }
|
|
||||||
#define CHECK_OUTPTR(offset) CHECK_PTR(outptr+offset, outbuf, sizeof(outbuf))
|
|
||||||
#define ZEROTERM(buf) buf[(sizeof(buf)/sizeof(buf[0]))-1]=0;
|
|
||||||
#define NEXT_PARAM()
|
|
||||||
|
|
||||||
char *CLangMngr::FormatString(const char *fmt, va_list &ap)
|
|
||||||
{
|
|
||||||
// the output buffer
|
|
||||||
static char outbuf[4096];
|
|
||||||
char *outptr = outbuf;
|
|
||||||
const char *src = fmt;
|
|
||||||
|
|
||||||
while (*src)
|
|
||||||
{
|
|
||||||
if (*src == '%')
|
|
||||||
{
|
|
||||||
++src;
|
|
||||||
if (*src == 'L')
|
|
||||||
{
|
|
||||||
NEXT_PARAM();
|
|
||||||
const char *pAmxLangName = va_arg(ap, const char*);
|
|
||||||
const char *cpLangName=NULL;
|
|
||||||
// Handle player ids (1-32) and server language
|
|
||||||
|
|
||||||
if (pAmxLangName == (const char *)LANG_PLAYER) // LANG_PLAYER
|
|
||||||
{
|
|
||||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
|
||||||
{
|
|
||||||
cpLangName = g_vault.get("server_language");
|
|
||||||
} else {
|
|
||||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pAmxLangName == (const char *)LANG_SERVER) // LANG_SERVER
|
|
||||||
{
|
|
||||||
cpLangName = g_vault.get("server_language");
|
|
||||||
}
|
|
||||||
else if (pAmxLangName >= (const char *)1 && pAmxLangName <= (const char *)32) // Direct Client Id
|
|
||||||
{
|
|
||||||
if ((int)CVAR_GET_FLOAT("amx_client_languages"))
|
|
||||||
{
|
|
||||||
cpLangName = g_vault.get("server_language");
|
|
||||||
} else {
|
|
||||||
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I((int)pAmxLangName)->pEdict, "lang");
|
|
||||||
}
|
|
||||||
} else { // Language Name
|
|
||||||
int tmplen = 0;
|
|
||||||
cpLangName = pAmxLangName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cpLangName || strlen(cpLangName) < 1)
|
|
||||||
cpLangName = "en";
|
|
||||||
|
|
||||||
int tmplen = 0;
|
|
||||||
const char *key = va_arg(ap, const char *);
|
|
||||||
const char *def = GetDef(cpLangName, key);
|
|
||||||
|
|
||||||
if (def == NULL)
|
|
||||||
{
|
|
||||||
if (pAmxLangName != LANG_SERVER)
|
|
||||||
{
|
|
||||||
def = GetDef(g_vault.get("server_language"), key);
|
|
||||||
}
|
|
||||||
if (strcmp(cpLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0)
|
|
||||||
{
|
|
||||||
def = GetDef("en", key);
|
|
||||||
}
|
|
||||||
if (!def)
|
|
||||||
{
|
|
||||||
static char buf[512];
|
|
||||||
CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
|
|
||||||
sprintf(buf, "ML_LNOTFOUND: %s", key);
|
|
||||||
def = buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*def)
|
|
||||||
{
|
|
||||||
if (*def == '%')
|
|
||||||
{
|
|
||||||
++def;
|
|
||||||
static char format[32];
|
|
||||||
format[0] = '%';
|
|
||||||
char *ptr = format + 1;
|
|
||||||
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
|
|
||||||
/*nothing*/;
|
|
||||||
ZEROTERM(format);
|
|
||||||
|
|
||||||
*ptr = 0;
|
|
||||||
vsprintf(outptr, format, ap);
|
|
||||||
// vsprintf doesnt alter the ap, increment here
|
|
||||||
|
|
||||||
switch (*(ptr - 1))
|
|
||||||
{
|
|
||||||
case 'f':
|
|
||||||
va_arg(ap, double);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
va_arg(ap, char *);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
default: // default: assume int-like parameter
|
|
||||||
va_arg(ap, int);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
outptr += strlen(outptr);
|
|
||||||
}
|
|
||||||
else if (*def == '^')
|
|
||||||
{
|
|
||||||
++def;
|
|
||||||
|
|
||||||
switch (*def)
|
|
||||||
{
|
|
||||||
case 'n':
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '\n';
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '\t';
|
|
||||||
break;
|
|
||||||
case '^':
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '^';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
CHECK_OUTPTR(2);
|
|
||||||
*outptr++ = '^';
|
|
||||||
*outptr++ = *def;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++def;
|
|
||||||
} else {
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = *def++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
static char format[32] = {'%'};
|
|
||||||
char *ptr = format + 1;
|
|
||||||
|
|
||||||
if (*src != '%')
|
|
||||||
{
|
|
||||||
while (*src != 0 && ptr-format < sizeof(format) && !isalpha(*ptr++ = *src++))
|
|
||||||
/*nothing*/;
|
|
||||||
*ptr = 0;
|
|
||||||
ZEROTERM(format);
|
|
||||||
--src;
|
|
||||||
vsprintf(outptr, format, ap);
|
|
||||||
// vsprintf doesnt alter the ap, increment here
|
|
||||||
|
|
||||||
switch (*(ptr - 1))
|
|
||||||
{
|
|
||||||
case 'f':
|
|
||||||
va_arg(ap, double);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
va_arg(ap, char *);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
default: // default: assume int-like parameter
|
|
||||||
va_arg(ap, int);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
outptr += strlen(outptr);
|
|
||||||
} else {
|
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = '%';
|
*outptr++ = '%';
|
||||||
|
*outptr++ = '%';
|
||||||
|
src++;
|
||||||
}
|
}
|
||||||
|
outptr += strlen(outptr);
|
||||||
}
|
}
|
||||||
} else {
|
curState = S_Normal;
|
||||||
CHECK_OUTPTR(1);
|
}
|
||||||
|
else
|
||||||
*outptr++ = *src;
|
*outptr++ = *src;
|
||||||
}
|
|
||||||
++src;
|
++src;
|
||||||
}
|
}
|
||||||
|
len = outptr - outbuf;
|
||||||
CHECK_OUTPTR(1);
|
|
||||||
*outptr++ = 0;
|
*outptr++ = 0;
|
||||||
|
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1001,9 +869,8 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
|||||||
AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file);
|
AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MD5 md5;
|
MD5 md5;
|
||||||
md5.update(fp); // closes for us
|
md5.update(fp);
|
||||||
md5.finalize();
|
md5.finalize();
|
||||||
char md5buffer[33];
|
char md5buffer[33];
|
||||||
md5.hex_digest(md5buffer);
|
md5.hex_digest(md5buffer);
|
||||||
@ -1055,9 +922,6 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
|||||||
buf.trim();
|
buf.trim();
|
||||||
if (buf[0] == 0)
|
if (buf[0] == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((buf[0] == ';') || (buf[0] == '/' && buf[1] == '/'))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (buf[0] == '[' && buf.size() >= 3)
|
if (buf[0] == '[' && buf.size() >= 3)
|
||||||
{
|
{
|
||||||
if (multiline)
|
if (multiline)
|
||||||
@ -1067,20 +931,17 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
|||||||
delete tmpEntry;
|
delete tmpEntry;
|
||||||
tmpEntry = 0;
|
tmpEntry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Defq.empty())
|
if (!Defq.empty())
|
||||||
{
|
{
|
||||||
MergeDefinitions(language, Defq);
|
MergeDefinitions(language, Defq);
|
||||||
}
|
}
|
||||||
|
|
||||||
language[0] = buf[1];
|
language[0] = buf[1];
|
||||||
language[1] = buf[2];
|
language[1] = buf[2];
|
||||||
language[2] = 0;
|
language[2] = 0;
|
||||||
} else {
|
} else if (buf.size() > 4) {
|
||||||
if (!multiline)
|
if (!multiline)
|
||||||
{
|
{
|
||||||
pos = buf.find('=');
|
pos = buf.find('=');
|
||||||
|
|
||||||
if (pos > String::npos)
|
if (pos > String::npos)
|
||||||
{
|
{
|
||||||
tmpEntry = new sKeyDef;
|
tmpEntry = new sKeyDef;
|
||||||
@ -1101,7 +962,6 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
|||||||
tmpEntry = 0;
|
tmpEntry = 0;
|
||||||
} else {
|
} else {
|
||||||
pos = buf.find(':');
|
pos = buf.find(':');
|
||||||
|
|
||||||
if (pos > String::npos)
|
if (pos > String::npos)
|
||||||
{
|
{
|
||||||
tmpEntry = new sKeyDef;
|
tmpEntry = new sKeyDef;
|
||||||
@ -1132,13 +992,11 @@ int CLangMngr::MergeDefinitionFile(const char *file)
|
|||||||
} // if !multiline
|
} // if !multiline
|
||||||
} //if - main
|
} //if - main
|
||||||
}
|
}
|
||||||
|
|
||||||
// merge last section
|
// merge last section
|
||||||
if (!Defq.empty())
|
if (!Defq.empty())
|
||||||
{
|
{
|
||||||
MergeDefinitions(language, Defq);
|
MergeDefinitions(language, Defq);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1177,7 +1035,6 @@ const char *CLangMngr::GetDef(const char *langName, const char *key)
|
|||||||
CLang *lang = GetLangR(langName);
|
CLang *lang = GetLangR(langName);
|
||||||
if (lang)
|
if (lang)
|
||||||
return lang->GetDef(key);
|
return lang->GetDef(key);
|
||||||
|
|
||||||
return "ML_NOTFOUND(LANG)";
|
return "ML_NOTFOUND(LANG)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1306,6 +1163,7 @@ bool CLangMngr::LoadCache(const char *filename)
|
|||||||
fread((void*)&dictCount, sizeof(short), 1, fp);
|
fread((void*)&dictCount, sizeof(short), 1, fp);
|
||||||
md5Pair *p = 0;
|
md5Pair *p = 0;
|
||||||
|
|
||||||
|
|
||||||
for (int i=1; i<=dictCount; i++)
|
for (int i=1; i<=dictCount; i++)
|
||||||
{
|
{
|
||||||
fread((void*)&len, sizeof(char), 1, fp);
|
fread((void*)&len, sizeof(char), 1, fp);
|
||||||
@ -1352,7 +1210,6 @@ bool CLangMngr::Load(const char *filename)
|
|||||||
|
|
||||||
uint32_t *LangOffsets = new uint32_t[langCount];
|
uint32_t *LangOffsets = new uint32_t[langCount];
|
||||||
char langname[3];
|
char langname[3];
|
||||||
|
|
||||||
for (unsigned int i=0; i<langCount; i++)
|
for (unsigned int i=0; i<langCount; i++)
|
||||||
{
|
{
|
||||||
fread(langname, sizeof(char), 2, fp);
|
fread(langname, sizeof(char), 2, fp);
|
||||||
@ -1366,7 +1223,6 @@ bool CLangMngr::Load(const char *filename)
|
|||||||
keyEntry *e = 0;
|
keyEntry *e = 0;
|
||||||
unsigned char keylen;
|
unsigned char keylen;
|
||||||
uint32_t keyoffset, save;
|
uint32_t keyoffset, save;
|
||||||
|
|
||||||
for (unsigned i=0; i<keycount; i++)
|
for (unsigned i=0; i<keycount; i++)
|
||||||
{
|
{
|
||||||
e = new keyEntry;
|
e = new keyEntry;
|
||||||
@ -1390,11 +1246,9 @@ bool CLangMngr::Load(const char *filename)
|
|||||||
uint32_t defhash;
|
uint32_t defhash;
|
||||||
uint32_t defoffset;
|
uint32_t defoffset;
|
||||||
unsigned short deflen;
|
unsigned short deflen;
|
||||||
|
|
||||||
for (unsigned int i=0; i<langCount; i++)
|
for (unsigned int i=0; i<langCount; i++)
|
||||||
{
|
{
|
||||||
fread((void*)&numentries, sizeof(uint32_t), 1, fp);
|
fread((void*)&numentries, sizeof(uint32_t), 1, fp);
|
||||||
|
|
||||||
for (unsigned int j=0; j<numentries; j++)
|
for (unsigned int j=0; j<numentries; j++)
|
||||||
{
|
{
|
||||||
fread((void *)&keynum, sizeof(uint32_t), 1, fp);
|
fread((void *)&keynum, sizeof(uint32_t), 1, fp);
|
||||||
@ -1428,7 +1282,6 @@ CLangMngr::~CLangMngr()
|
|||||||
void CLangMngr::Clear()
|
void CLangMngr::Clear()
|
||||||
{
|
{
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
for (i=0; i<m_Languages.size(); i++)
|
for (i=0; i<m_Languages.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_Languages[i])
|
if (m_Languages[i])
|
||||||
@ -1461,7 +1314,6 @@ const char *CLangMngr::GetLangName(int langId)
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
LangVecIter iter;
|
LangVecIter iter;
|
||||||
|
|
||||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (i == langId)
|
if (i == langId)
|
||||||
@ -1470,7 +1322,6 @@ const char *CLangMngr::GetLangName(int langId)
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1478,7 +1329,6 @@ bool CLangMngr::LangExists(const char *langName)
|
|||||||
{
|
{
|
||||||
char buf[3] = { 0 };
|
char buf[3] = { 0 };
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (buf[i] = tolower(*langName++))
|
while (buf[i] = tolower(*langName++))
|
||||||
{
|
{
|
||||||
if (++i == 2)
|
if (++i == 2)
|
||||||
@ -1486,13 +1336,11 @@ bool CLangMngr::LangExists(const char *langName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LangVecIter iter;
|
LangVecIter iter;
|
||||||
|
|
||||||
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
|
||||||
{
|
{
|
||||||
if ( strcmp((*iter)->GetName(), buf)==0 )
|
if ( strcmp((*iter)->GetName(), buf)==0 )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ struct sKeyDef
|
|||||||
{
|
{
|
||||||
sKeyDef() { key = -1; def = 0; }
|
sKeyDef() { key = -1; def = 0; }
|
||||||
~sKeyDef() { if (def) delete def; }
|
~sKeyDef() { if (def) delete def; }
|
||||||
|
|
||||||
int key;
|
int key;
|
||||||
String *def;
|
String *def;
|
||||||
};
|
};
|
||||||
@ -80,7 +79,6 @@ class CLangMngr
|
|||||||
{
|
{
|
||||||
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
|
// Save to file
|
||||||
@ -93,8 +91,8 @@ class CLangMngr
|
|||||||
int Entries() { return m_LookUpTable.size(); }
|
int Entries() { return m_LookUpTable.size(); }
|
||||||
// Make a hash from a string; convert to lowercase first if needed
|
// Make a hash from a string; convert to lowercase first if needed
|
||||||
static uint32_t MakeHash(const char *src, bool makeLower = false);
|
static uint32_t MakeHash(const char *src, bool makeLower = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// An entry in the language
|
// An entry in the language
|
||||||
class LangEntry
|
class LangEntry
|
||||||
{
|
{
|
||||||
@ -173,7 +171,6 @@ public:
|
|||||||
const char *Format(const char *src, ...);
|
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);
|
||||||
char *FormatString(const char *fmt, va_list &ap);
|
|
||||||
// Save
|
// Save
|
||||||
bool Save(const char *filename);
|
bool Save(const char *filename);
|
||||||
// Load
|
// Load
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -113,7 +110,6 @@ public:
|
|||||||
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:
|
||||||
@ -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,7 +176,6 @@ 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);
|
||||||
@ -193,7 +187,6 @@ public:
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +289,6 @@ public:
|
|||||||
break;
|
break;
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,15 +301,13 @@ public:
|
|||||||
{
|
{
|
||||||
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,149 +35,102 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class LogEventsMngr
|
// class LogEventsMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
LogEventsMngr::LogEventsMngr() {
|
||||||
LogEventsMngr::LogEventsMngr()
|
|
||||||
{
|
|
||||||
logCurrent = logCounter = 0;
|
logCurrent = logCounter = 0;
|
||||||
logcmplist = 0;
|
logcmplist = 0;
|
||||||
arelogevents = false;
|
arelogevents = false;
|
||||||
memset( logevents, 0, sizeof(logevents) );
|
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;
|
logid = parent->logCounter;
|
||||||
|
if ( in ) return result = strstr( string , text.c_str() ) ? 0 : 1;
|
||||||
if (in)
|
|
||||||
return result = strstr(string, text.c_str()) ? 0 : 1;
|
|
||||||
|
|
||||||
return result = strcmp(string,text.c_str());
|
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){
|
||||||
for (LogCond* c = filters; c; c = c->next)
|
if ( c->argnum == cmp->pos ){
|
||||||
{
|
|
||||||
if (c->argnum == cmp->pos)
|
|
||||||
{
|
|
||||||
c->list = new LogCondEle( cmp , c->list );
|
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;
|
||||||
if (aa == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
filters = new LogCond( cmp->pos , aa , filters );
|
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 ){
|
||||||
while (*b && logArgc < MAX_LOGARGS)
|
|
||||||
{
|
|
||||||
a = 0;
|
a = 0;
|
||||||
|
if ( *b == '"' ) {
|
||||||
if (*b == '"')
|
|
||||||
{
|
|
||||||
++b;
|
++b;
|
||||||
|
|
||||||
while ( *b && *b != '"' && a < 127 )
|
while ( *b && *b != '"' && a < 127 )
|
||||||
logArgs[logArgc][a++] = *b++;
|
logArgs[logArgc][a++] = *b++;
|
||||||
|
|
||||||
logArgs[logArgc++][a] = 0;
|
logArgs[logArgc++][a] = 0;
|
||||||
if ( *b) b+=2; // thanks to double terminator
|
if ( *b) b+=2; // thanks to double terminator
|
||||||
}
|
}
|
||||||
else if (*b == '(')
|
else if ( *b == '(' ) {
|
||||||
{
|
|
||||||
++b;
|
++b;
|
||||||
|
|
||||||
while ( *b && *b != ')' && a < 127 )
|
while ( *b && *b != ')' && a < 127 )
|
||||||
logArgs[logArgc][a++] = *b++;
|
logArgs[logArgc][a++] = *b++;
|
||||||
|
|
||||||
logArgs[logArgc++][a] = 0;
|
logArgs[logArgc++][a] = 0;
|
||||||
if ( *b) b+=2;
|
if ( *b) b+=2;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
while ( *b && *b != '(' && *b != '"' && a < 127 )
|
while ( *b && *b != '(' && *b != '"' && a < 127 )
|
||||||
logArgs[logArgc][a++] = *b++;
|
logArgs[logArgc][a++] = *b++;
|
||||||
if ( *b ) --a;
|
if ( *b ) --a;
|
||||||
@ -190,91 +143,83 @@ LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent(CPluginMngr::CPlugin*
|
|||||||
{
|
{
|
||||||
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;
|
||||||
while (*d)
|
|
||||||
d = &(*d)->next;
|
|
||||||
|
|
||||||
return *d = new CLogEvent( plugin , func, this );
|
return *d = new CLogEvent( plugin , func, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::executeLogEvents()
|
void LogEventsMngr::executeLogEvents()
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next){
|
||||||
for (CLogEvent* a = logevents[logArgc]; a; a = a->next)
|
|
||||||
{
|
|
||||||
valid = true;
|
valid = true;
|
||||||
|
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||||
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
|
|
||||||
{
|
|
||||||
valid = false;
|
valid = false;
|
||||||
|
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||||
{
|
|
||||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
|
||||||
{
|
|
||||||
valid = true;
|
valid = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!valid) 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( ... )
|
||||||
|
{
|
||||||
|
AMXXLOG_Log( "[AMXX] fatal error at log forward function execution");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::clearLogEvents()
|
void LogEventsMngr::clearLogEvents(){
|
||||||
{
|
|
||||||
logCurrent = logCounter = 0;
|
logCurrent = logCounter = 0;
|
||||||
arelogevents = false;
|
arelogevents = false;
|
||||||
|
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
|
||||||
for (int i = 0; i < MAX_LOGARGS + 1; ++i)
|
|
||||||
{
|
|
||||||
CLogEvent **a = &logevents[i];
|
CLogEvent **a = &logevents[i];
|
||||||
while (*a)
|
while(*a){
|
||||||
{
|
|
||||||
CLogEvent* bb = (*a)->next;
|
CLogEvent* bb = (*a)->next;
|
||||||
delete *a;
|
delete *a;
|
||||||
*a = bb;
|
*a = bb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clearConditions();
|
clearConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogEventsMngr::clearConditions()
|
void LogEventsMngr::clearConditions() {
|
||||||
{
|
while (logcmplist){
|
||||||
while (logcmplist)
|
|
||||||
{
|
|
||||||
CLogCmp* a = logcmplist->next;
|
CLogCmp* a = logcmplist->next;
|
||||||
delete logcmplist;
|
delete logcmplist;
|
||||||
logcmplist = a;
|
logcmplist = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent::LogCond::~LogCond()
|
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
|
||||||
{
|
while( list ) {
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
LogCondEle* cc = list->next;
|
LogCondEle* cc = list->next;
|
||||||
delete list;
|
delete list;
|
||||||
list = cc;
|
list = cc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsMngr::CLogEvent::~CLogEvent()
|
LogEventsMngr::CLogEvent::~CLogEvent() {
|
||||||
{
|
while( filters ) {
|
||||||
while (filters)
|
|
||||||
{
|
|
||||||
LogCond* cc = filters->next;
|
LogCond* cc = filters->next;
|
||||||
delete filters;
|
delete filters;
|
||||||
filters = cc;
|
filters = cc;
|
||||||
@ -284,35 +229,23 @@ LogEventsMngr::CLogEvent::~CLogEvent()
|
|||||||
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,8 +40,8 @@
|
|||||||
// 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;
|
||||||
@ -53,6 +53,7 @@ public:
|
|||||||
class CLogCmp;
|
class CLogCmp;
|
||||||
class iterator;
|
class iterator;
|
||||||
class CLogEvent;
|
class CLogEvent;
|
||||||
|
|
||||||
friend class CLogEvent;
|
friend class CLogEvent;
|
||||||
friend class CLogCmp;
|
friend class CLogCmp;
|
||||||
friend class iterator;
|
friend class iterator;
|
||||||
@ -61,63 +62,50 @@ public:
|
|||||||
{
|
{
|
||||||
friend class LogEventsMngr;
|
friend class LogEventsMngr;
|
||||||
friend class CLogEvent;
|
friend class CLogEvent;
|
||||||
|
|
||||||
LogEventsMngr* parent;
|
LogEventsMngr* parent;
|
||||||
String text;
|
String text;
|
||||||
|
|
||||||
int logid;
|
int logid;
|
||||||
int pos;
|
int pos;
|
||||||
int result;
|
int result;
|
||||||
bool in;
|
bool in;
|
||||||
|
|
||||||
CLogCmp *next;
|
CLogCmp *next;
|
||||||
|
CLogCmp( const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg ) : text(s) {
|
||||||
CLogCmp(const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg) : text(s)
|
|
||||||
{
|
|
||||||
logid = result = 0;
|
logid = result = 0;
|
||||||
pos = p;
|
pos = p;
|
||||||
parent = mg;
|
parent = mg;
|
||||||
in = r;
|
in = r;
|
||||||
next = n;
|
next = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
int compareCondition(const char* string);
|
int compareCondition(const char* string);
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CLogCmp *logcmplist;
|
CLogCmp *logcmplist;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class CLogEvent
|
class CLogEvent {
|
||||||
{
|
|
||||||
friend class LogEventsMngr;
|
friend class LogEventsMngr;
|
||||||
friend class iterator;
|
friend class iterator;
|
||||||
|
struct LogCondEle {
|
||||||
struct LogCondEle
|
|
||||||
{
|
|
||||||
CLogCmp *cmp;
|
CLogCmp *cmp;
|
||||||
LogCondEle *next;
|
LogCondEle *next;
|
||||||
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
|
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
|
||||||
};
|
};
|
||||||
|
struct LogCond {
|
||||||
struct LogCond
|
|
||||||
{
|
|
||||||
int argnum;
|
int argnum;
|
||||||
|
|
||||||
LogCondEle *list;
|
LogCondEle *list;
|
||||||
LogCond *next;
|
LogCond *next;
|
||||||
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
|
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
|
||||||
~LogCond();
|
~LogCond();
|
||||||
};
|
};
|
||||||
|
|
||||||
CPluginMngr::CPlugin *plugin;
|
CPluginMngr::CPlugin *plugin;
|
||||||
|
|
||||||
int func;
|
int func;
|
||||||
|
|
||||||
LogCond *filters;
|
LogCond *filters;
|
||||||
LogEventsMngr* parent;
|
LogEventsMngr* parent;
|
||||||
|
|
||||||
CLogEvent *next;
|
CLogEvent *next;
|
||||||
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
|
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
|
||||||
~CLogEvent();
|
~CLogEvent();
|
||||||
@ -128,51 +116,50 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CLogEvent *logevents[MAX_LOGARGS+1];
|
CLogEvent *logevents[MAX_LOGARGS+1];
|
||||||
CLogEvent *getValidLogEvent( CLogEvent * a );
|
CLogEvent *getValidLogEvent( CLogEvent * a );
|
||||||
CLogCmp* registerCondition(char* filter);
|
CLogCmp* registerCondition(char* filter);
|
||||||
|
|
||||||
void clearConditions();
|
void clearConditions();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LogEventsMngr();
|
LogEventsMngr();
|
||||||
~LogEventsMngr();
|
~LogEventsMngr();
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
|
|
||||||
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
|
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
|
||||||
inline bool logEventsExist() { return arelogevents; }
|
inline bool logEventsExist() { return arelogevents; }
|
||||||
|
|
||||||
void setLogString( char* frmt, va_list& vaptr );
|
void setLogString( char* frmt, va_list& vaptr );
|
||||||
void setLogString( char* frmt , ... );
|
void setLogString( char* frmt , ... );
|
||||||
void parseLogString( );
|
void parseLogString( );
|
||||||
void executeLogEvents();
|
void executeLogEvents();
|
||||||
|
|
||||||
inline const char* getLogString() { return logString; }
|
inline const char* getLogString() { return logString; }
|
||||||
inline int getLogArgNum() { return logArgc; }
|
inline int getLogArgNum() { return logArgc; }
|
||||||
inline const char* getLogArg( int i ) { return ( i < 0 || i >= logArgc ) ? "" : logArgs[ i ]; }
|
inline const char* getLogArg( int i ) { return ( i < 0 || i >= logArgc ) ? "" : logArgs[ i ]; }
|
||||||
void clearLogEvents();
|
void clearLogEvents();
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
class iterator {
|
||||||
CLogEvent* a;
|
CLogEvent* a;
|
||||||
LogEventsMngr* b;
|
LogEventsMngr* b;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
|
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
|
||||||
|
inline iterator& operator++() {
|
||||||
inline iterator& operator++()
|
|
||||||
{
|
|
||||||
a = b->getValidLogEvent( a->next );
|
a = b->getValidLogEvent( a->next );
|
||||||
return *this;
|
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,8 +35,7 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class MenuMngr
|
// class MenuMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
|
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
|
||||||
{
|
|
||||||
plugin = a;
|
plugin = a;
|
||||||
keys = k;
|
keys = k;
|
||||||
menuid = mi;
|
menuid = mi;
|
||||||
@ -51,27 +50,20 @@ MenuMngr::~MenuMngr()
|
|||||||
|
|
||||||
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)
|
|
||||||
return id;
|
|
||||||
|
|
||||||
headid = new MenuIdEle( n, a , headid );
|
headid = new MenuIdEle( n, a , headid );
|
||||||
|
|
||||||
if (!headid)
|
if (!headid)
|
||||||
return 0; // :TODO: Better error report
|
return 0; // :TODO: Better error report
|
||||||
|
|
||||||
return headid->id;
|
return headid->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,20 +43,17 @@ class MenuMngr
|
|||||||
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 ) {
|
||||||
MenuIdEle(const char* n, AMX* a, MenuIdEle* m) : name(n), amx(a), next(m)
|
|
||||||
{
|
|
||||||
id = ++uniqueid;
|
id = ++uniqueid;
|
||||||
}
|
}
|
||||||
|
|
||||||
~MenuIdEle() { --uniqueid; }
|
~MenuIdEle() { --uniqueid; }
|
||||||
} *headid;
|
} *headid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class iterator;
|
class iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class MenuCommand
|
class MenuCommand
|
||||||
@ -68,7 +65,6 @@ private:
|
|||||||
int menuid;
|
int menuid;
|
||||||
int keys;
|
int keys;
|
||||||
int function;
|
int function;
|
||||||
|
|
||||||
MenuCommand* next;
|
MenuCommand* next;
|
||||||
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
|
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
|
||||||
public:
|
public:
|
||||||
@ -78,18 +74,19 @@ private:
|
|||||||
} *headcmd;
|
} *headcmd;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MenuMngr() { headid = 0; headcmd = 0; }
|
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 );
|
void registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f );
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
class iterator
|
class iterator {
|
||||||
{
|
|
||||||
MenuCommand* a;
|
MenuCommand* a;
|
||||||
public:
|
public:
|
||||||
iterator(MenuCommand*aa) : a(aa) {}
|
iterator(MenuCommand*aa) : a(aa) {}
|
||||||
@ -99,9 +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); }
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //MENUS_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,59 +55,42 @@ 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;
|
||||||
|
|
||||||
while (!cvarQueryQueue.empty())
|
|
||||||
{
|
|
||||||
ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
|
|
||||||
unregisterSPForward(pQuery->resultFwd);
|
|
||||||
|
|
||||||
if (pQuery->params)
|
|
||||||
delete [] pQuery->params;
|
|
||||||
|
|
||||||
delete pQuery;
|
|
||||||
cvarQueryQueue.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
bot = 0;
|
bot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
|
||||||
{
|
|
||||||
name.assign(connectname);
|
name.assign(connectname);
|
||||||
ip.assign(ipaddress);
|
ip.assign(ipaddress);
|
||||||
time = gpGlobals->time;
|
time = gpGlobals->time;
|
||||||
bot = IsBot();
|
bot = IsBot();
|
||||||
death_killer = 0;
|
death_killer = 0;
|
||||||
|
|
||||||
memset(flags,0,sizeof(flags));
|
memset(flags,0,sizeof(flags));
|
||||||
memset(weapons,0,sizeof(weapons));
|
memset(weapons,0,sizeof(weapons));
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
authorized = false;
|
authorized = false;
|
||||||
|
|
||||||
const char* authid = GETPLAYERAUTHID( pEdict );
|
const char* authid = GETPLAYERAUTHID( pEdict );
|
||||||
|
|
||||||
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
|
if ( (authid == 0) || (*authid == 0)
|
||||||
|
|| (strcmp( authid , "STEAM_ID_PENDING") == 0) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
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;
|
||||||
@ -124,33 +107,30 @@ bool Grenades::find(edict_t* enemy, CPlayer** p, int& type)
|
|||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
Obj** a = &head;
|
Obj** a = &head;
|
||||||
|
while ( *a ){
|
||||||
while (*a)
|
if ( (*a)->time > gpGlobals->time ) {
|
||||||
{
|
if ( (*a)->grenade == enemy ) {
|
||||||
if ((*a)->time > gpGlobals->time)
|
|
||||||
{
|
|
||||||
if ((*a)->grenade == enemy)
|
|
||||||
{
|
|
||||||
found = true;
|
found = true;
|
||||||
(*p) = (*a)->player;
|
(*p) = (*a)->player;
|
||||||
type = (*a)->type;
|
type = (*a)->type;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Obj* b = (*a)->next;
|
Obj* b = (*a)->next;
|
||||||
delete *a;
|
delete *a;
|
||||||
*a = b;
|
*a = b;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
a = &(*a)->next;
|
a = &(*a)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Grenades::clear()
|
void Grenades::clear()
|
||||||
{
|
{
|
||||||
while (head)
|
while(head){
|
||||||
{
|
|
||||||
Obj* a = head->next;
|
Obj* a = head->next;
|
||||||
delete head;
|
delete head;
|
||||||
head = a;
|
head = a;
|
||||||
@ -160,9 +140,7 @@ void Grenades::clear()
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class XVars
|
// class XVars
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
void XVars::clear() {
|
||||||
void XVars::clear()
|
|
||||||
{
|
|
||||||
delete[] head;
|
delete[] head;
|
||||||
head = 0;
|
head = 0;
|
||||||
num = 0;
|
num = 0;
|
||||||
@ -171,8 +149,7 @@ void XVars::clear()
|
|||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
@ -182,38 +159,29 @@ int XVars::put(AMX* p, cell* v)
|
|||||||
|
|
||||||
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;
|
||||||
@ -223,56 +191,42 @@ TeamIds::~TeamIds()
|
|||||||
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;
|
||||||
if (*a == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
newTeam |= (1<<(*a)->tid);
|
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;
|
||||||
|
|
||||||
|
@ -37,44 +37,34 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CPlayer
|
// class CPlayer
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
struct ClientCvarQuery_Info
|
|
||||||
{
|
|
||||||
bool querying; // Are we actually waiting for a response at the moment?
|
|
||||||
String cvarName;
|
|
||||||
int resultFwd;
|
|
||||||
|
|
||||||
int paramLen;
|
|
||||||
cell *params;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CPlayer
|
class CPlayer
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
edict_t* pEdict;
|
edict_t* pEdict;
|
||||||
|
|
||||||
@ -90,8 +80,7 @@ public:
|
|||||||
float time;
|
float time;
|
||||||
float playtime;
|
float playtime;
|
||||||
|
|
||||||
struct
|
struct {
|
||||||
{
|
|
||||||
int ammo;
|
int ammo;
|
||||||
int clip;
|
int clip;
|
||||||
} weapons[MAX_WEAPONS];
|
} weapons[MAX_WEAPONS];
|
||||||
@ -110,28 +99,21 @@ public:
|
|||||||
int death_victim;
|
int death_victim;
|
||||||
bool death_tk;
|
bool death_tk;
|
||||||
String death_weapon;
|
String death_weapon;
|
||||||
int newmenu;
|
|
||||||
int page;
|
|
||||||
|
|
||||||
Vector lastTrace;
|
Vector lastTrace;
|
||||||
Vector thisTrace;
|
Vector thisTrace;
|
||||||
Vector lastHit;
|
Vector lastHit;
|
||||||
|
|
||||||
CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
|
|
||||||
|
|
||||||
void Init( edict_t* e , int i );
|
void Init( edict_t* e , int i );
|
||||||
void Disconnect();
|
void Disconnect();
|
||||||
void PutInServer();
|
void PutInServer();
|
||||||
|
|
||||||
bool Connect(const char* connectname,const char* ipaddress);
|
bool Connect(const char* connectname,const char* ipaddress);
|
||||||
|
|
||||||
inline bool IsBot()
|
inline bool IsBot(){
|
||||||
{
|
|
||||||
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
|
return ((pEdict->v.flags & FL_FAKECLIENT)?true: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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,10 +136,10 @@ class Grenades
|
|||||||
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();
|
||||||
@ -166,23 +148,19 @@ public:
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class ForceObject
|
// class ForceObject
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
class ForceObject {
|
||||||
class ForceObject
|
|
||||||
{
|
|
||||||
String filename;
|
String filename;
|
||||||
FORCE_TYPE type;
|
FORCE_TYPE type;
|
||||||
Vector mins;
|
Vector mins;
|
||||||
Vector maxs;
|
Vector maxs;
|
||||||
AMX* amx;
|
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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,38 +170,30 @@ public:
|
|||||||
|
|
||||||
class XVars
|
class XVars
|
||||||
{
|
{
|
||||||
struct XVarEle
|
struct XVarEle {
|
||||||
{
|
|
||||||
AMX* amx;
|
AMX* amx;
|
||||||
cell* value;
|
cell* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
XVarEle* head;
|
XVarEle* head;
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
int realloc_array( int nsize );
|
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 ) {
|
||||||
inline cell getValue(int a)
|
|
||||||
{
|
|
||||||
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
|
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
|
||||||
}
|
}
|
||||||
|
inline int setValue( int a, cell v ) {
|
||||||
inline int setValue(int a, cell v)
|
if ( a >= 0 && a < num ){
|
||||||
{
|
|
||||||
if (a >= 0 && a < num)
|
|
||||||
{
|
|
||||||
*(head[a].value) = v;
|
*(head[a].value) = v;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -231,7 +201,6 @@ public:
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CScript
|
// class CScript
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
class CScript
|
class CScript
|
||||||
{
|
{
|
||||||
String filename;
|
String filename;
|
||||||
@ -239,7 +208,6 @@ class CScript
|
|||||||
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); }
|
||||||
@ -249,22 +217,17 @@ public:
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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) {
|
||||||
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
|
|
||||||
{
|
|
||||||
tid = uid++;
|
tid = uid++;
|
||||||
}
|
};
|
||||||
|
|
||||||
~TeamEle(){ --uid; }
|
~TeamEle(){ --uid; }
|
||||||
} *head;
|
} *head;
|
||||||
|
|
||||||
@ -273,11 +236,15 @@ class TeamIds
|
|||||||
public:
|
public:
|
||||||
TeamIds();
|
TeamIds();
|
||||||
~TeamIds();
|
~TeamIds();
|
||||||
|
|
||||||
void registerTeam( const char* n ,int s );
|
void registerTeam( const char* n ,int s );
|
||||||
int findTeamId( const char* n);
|
int findTeamId( const char* n);
|
||||||
int findTeamIdCase( const char* n);
|
int findTeamIdCase( const char* n);
|
||||||
inline bool isNewTeam() { return newTeam ? true : false; }
|
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CMISC_H
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,11 @@
|
|||||||
#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*/);
|
||||||
@ -42,13 +47,87 @@ 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);
|
||||||
|
|
||||||
|
// 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
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
CModule::CModule(const char* fname)
|
CModule::CModule(const char* fname) : m_Filename(fname)
|
||||||
{
|
{
|
||||||
m_Filename.assign(fname);
|
|
||||||
clear(false);
|
clear(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,10 +146,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";
|
||||||
@ -82,26 +162,6 @@ void CModule::clear(bool clearFilename)
|
|||||||
m_Natives.clear();
|
m_Natives.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CModule::attachModule()
|
bool CModule::attachModule()
|
||||||
{
|
{
|
||||||
// old & new
|
// old & new
|
||||||
@ -115,7 +175,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);
|
||||||
@ -140,11 +199,17 @@ bool CModule::attachModule()
|
|||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
m_Status = MODULE_BADLOAD;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// old
|
||||||
|
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
|
||||||
|
|
||||||
return false;
|
if (AttachFunc)
|
||||||
|
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
|
||||||
|
m_Status = MODULE_LOADED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CModule::queryModule()
|
bool CModule::queryModule()
|
||||||
@ -165,7 +230,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;
|
||||||
@ -175,7 +239,6 @@ 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:
|
||||||
@ -205,10 +268,47 @@ bool CModule::queryModule()
|
|||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +320,6 @@ bool CModule::detachModule()
|
|||||||
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;
|
||||||
@ -230,17 +329,14 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,10 +349,8 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +372,5 @@ const char* CModule::getStatus() const
|
|||||||
case MODULE_NOT64BIT: return "not 64bit";
|
case MODULE_NOT64BIT: return "not 64bit";
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,7 @@
|
|||||||
#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 ;]
|
||||||
@ -58,23 +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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define AMXX_OK 0 /* no error */
|
#define AMXX_OK 0 /* no error */
|
||||||
#define AMXX_IFVERS 1 /* interface version */
|
#define AMXX_IFVERS 1 /* interface version */
|
||||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||||
|
|
||||||
#define AMXX_INTERFACE_VERSION 3
|
#define AMXX_INTERFACE_VERSION 1
|
||||||
|
|
||||||
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
|
||||||
@ -86,32 +84,30 @@ public:
|
|||||||
~CModule();
|
~CModule();
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
bool attachModule();
|
bool attachModule();
|
||||||
bool queryModule();
|
bool queryModule();
|
||||||
bool detachModule();
|
bool detachModule();
|
||||||
|
|
||||||
#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==( void* fname ) { return !strcmp( m_Filename.c_str() , (char*)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 CModule::CallPluginsLoaded();
|
||||||
|
|
||||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //CMODULE_H
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,57 +33,24 @@
|
|||||||
#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"
|
|
||||||
|
|
||||||
extern const char *no_function;
|
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error) {
|
||||||
|
|
||||||
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);
|
||||||
a = &(*a)->next;
|
return *error ? 0 : *a;
|
||||||
|
|
||||||
*a = new CPlugin(pCounter++, path, name, error, debug);
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
if (m_Finalized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pNatives = BuildNativeTable();
|
|
||||||
CPlugin *a = head;
|
|
||||||
|
|
||||||
while (a)
|
|
||||||
{
|
|
||||||
if (a->getStatusCode() == ps_running)
|
|
||||||
{
|
|
||||||
amx_Register(a->getAMX(), pNatives, -1);
|
|
||||||
a->Finalize();
|
|
||||||
}
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Finalized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||||
{
|
{
|
||||||
char file[256];
|
File fp( build_pathname("%s",filename) , "r" );
|
||||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
|
|
||||||
|
|
||||||
if ( !fp )
|
if ( !fp )
|
||||||
{
|
{
|
||||||
@ -92,271 +59,109 @@ int CPluginMngr::loadPluginsFromFile(const char* filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find now folder
|
// Find now folder
|
||||||
char pluginName[256], error[256], debug[256];
|
char pluginName[256], line[256], error[256];
|
||||||
int debugFlag = 0;
|
const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxx/plugins");
|
||||||
const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins");
|
|
||||||
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while (!feof(fp))
|
while ( fp.getline(line , 255 ) )
|
||||||
{
|
{
|
||||||
pluginName[0] = '\0';
|
*pluginName = 0;
|
||||||
|
sscanf(line,"%s",pluginName);
|
||||||
|
if (!isalnum(*pluginName)) continue;
|
||||||
|
|
||||||
debug[0] = '\0';
|
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error );
|
||||||
debugFlag = 0;
|
|
||||||
|
|
||||||
line.clear();
|
if (!plugin)
|
||||||
line._fread(fp);
|
AMXXLOG_Log("[AMXX] %s (plugin \"%s\")", error, pluginName );
|
||||||
sscanf(line.c_str(), "%s %s", pluginName, debug);
|
|
||||||
|
|
||||||
if (!isalnum(*pluginName))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
|
||||||
{
|
|
||||||
debugFlag = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
|
|
||||||
|
|
||||||
if (plugin->getStatusCode() == ps_bad_load)
|
|
||||||
{
|
|
||||||
char errorMsg[255];
|
|
||||||
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
|
|
||||||
plugin->setError(errorMsg);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||||
{
|
{
|
||||||
return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
|
return (CPlugin*)(amx->userdata[3]);
|
||||||
}
|
/*CPlugin*a = head;
|
||||||
|
|
||||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
|
|
||||||
{
|
|
||||||
CPlugin*a = head;
|
|
||||||
|
|
||||||
while ( a && &a->amx != amx )
|
while ( a && &a->amx != amx )
|
||||||
a=a->next;
|
a=a->next;
|
||||||
|
return a;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
|
||||||
|
CPlugin*a = head;
|
||||||
|
while ( a && &a->amx != amx )
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* CPluginMngr::CPlugin::getStatus() const
|
const char* CPluginMngr::CPlugin::getStatus() const {
|
||||||
{
|
switch(status){
|
||||||
switch (status)
|
case ps_running: return "running";
|
||||||
{
|
|
||||||
case ps_running:
|
|
||||||
{
|
|
||||||
if (m_Debug)
|
|
||||||
{
|
|
||||||
return "debug";
|
|
||||||
} else {
|
|
||||||
return "running";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ps_paused: return "paused";
|
case ps_paused: return "paused";
|
||||||
case ps_bad_load: return "bad load";
|
case ps_bad_load: return "bad load";
|
||||||
case ps_stopped: return "stopped";
|
case ps_stopped: return "stopped";
|
||||||
case ps_locked: return "locked";
|
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) : name(n), title(n) {
|
||||||
{
|
|
||||||
const char* unk = "unknown";
|
const char* unk = "unknown";
|
||||||
|
|
||||||
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 );
|
||||||
int err = load_amxscript(&amx, &code, path, e, d);
|
if ( err == AMX_ERR_NONE ) status = ps_running;
|
||||||
|
else status = ps_bad_load;
|
||||||
if (err == AMX_ERR_NONE)
|
amx.userdata[3] = this;
|
||||||
{
|
|
||||||
status = ps_running;
|
|
||||||
} else {
|
|
||||||
status = ps_bad_load;
|
|
||||||
}
|
|
||||||
|
|
||||||
amx.userdata[UD_FINDPLUGIN] = this;
|
|
||||||
paused_fun = 0;
|
paused_fun = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
id = i;
|
id = i;
|
||||||
|
|
||||||
if (status == ps_running)
|
|
||||||
{
|
|
||||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
|
||||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
|
||||||
|
|
||||||
if (amx.flags & AMX_FLAG_DEBUG)
|
|
||||||
{
|
|
||||||
m_Debug = true;
|
|
||||||
} else {
|
|
||||||
m_Debug = false;
|
|
||||||
}
|
}
|
||||||
}
|
CPluginMngr::CPlugin::~CPlugin( ){
|
||||||
}
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin::~CPlugin()
|
|
||||||
{
|
|
||||||
unload_amxscript( &amx, &code );
|
unload_amxscript( &amx, &code );
|
||||||
}
|
}
|
||||||
|
|
||||||
int AMXAPI native_handler(AMX *amx, int index)
|
void CPluginMngr::CPlugin::pauseFunction( int id ) {
|
||||||
{
|
if (isValid()){
|
||||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
paused_fun |= (1<<id);
|
||||||
|
g_commands.clearBufforedInfo();
|
||||||
char name[sNAMEMAX + 1];
|
|
||||||
amx_GetNative(amx, index, name);
|
|
||||||
|
|
||||||
return pHandler->HandleNative(name, index, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
//A script has accidentally called an invalid native! give them a
|
|
||||||
// first chance to block the resulting error.
|
|
||||||
|
|
||||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
|
||||||
|
|
||||||
//this should never happen
|
|
||||||
if (!pHandler)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this should never happen because this native won't be called
|
|
||||||
// if the plugin isn't filtering.
|
|
||||||
if (!pHandler->IsNativeFiltering())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char name[sNAMEMAX + 1];
|
|
||||||
int native = amx->usertags[UT_NATIVE];
|
|
||||||
int err = amx_GetNative(amx, native, name);
|
|
||||||
|
|
||||||
if (err != AMX_ERR_NONE)
|
|
||||||
name[0] = '\0';
|
|
||||||
|
|
||||||
//1 - because we're trapping usage
|
|
||||||
if (!pHandler->HandleNative(name, native, 1))
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_INVNATIVE, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Someday maybe allow native filters to write their own return value?
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::Finalize()
|
|
||||||
{
|
|
||||||
char buffer[128];
|
|
||||||
int old_status = status;
|
|
||||||
|
|
||||||
if (CheckModules(&amx, buffer))
|
|
||||||
{
|
|
||||||
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
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::unpauseFunction( int id ) {
|
||||||
{
|
if (isValid()) {
|
||||||
|
paused_fun &= ~(1<<id);
|
||||||
|
g_commands.clearBufforedInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::unpauseFunction(int id)
|
void CPluginMngr::CPlugin::setStatus( int a ) {
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPluginMngr::CPlugin::setStatus(int a)
|
|
||||||
{
|
|
||||||
status = a;
|
status = a;
|
||||||
g_commands.clearBufforedInfo(); // ugly way
|
g_commands.clearBufforedInfo(); // ugly way
|
||||||
}
|
}
|
||||||
@ -367,8 +172,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);
|
||||||
}
|
}
|
||||||
@ -380,10 +193,17 @@ void CPluginMngr::CPlugin::unpausePlugin()
|
|||||||
if (isValid())
|
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;
|
||||||
executeForwards(m_UnpauseFwd);
|
cell retval;
|
||||||
|
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
if (isExecutable(func))
|
||||||
|
{
|
||||||
|
amx_Exec(&amx, &retval, func, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,18 +36,18 @@
|
|||||||
// class CPluginMngr
|
// class CPluginMngr
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
ps_bad_load,
|
ps_bad_load,
|
||||||
ps_error,
|
ps_error,
|
||||||
ps_locked,
|
|
||||||
ps_paused,
|
ps_paused,
|
||||||
ps_stopped,
|
|
||||||
ps_running,
|
ps_running,
|
||||||
|
ps_stopped,
|
||||||
|
ps_locked
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPluginMngr
|
class CPluginMngr
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class iterator;
|
class iterator;
|
||||||
@ -59,80 +59,62 @@ 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;
|
|
||||||
|
|
||||||
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);
|
||||||
CPlugin(int i, const char* p, const char* n, char* e, int d);
|
|
||||||
~CPlugin( );
|
~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();}
|
||||||
inline const char* getAuthor() { return author.c_str();}
|
inline const char* getAuthor() { return author.c_str();}
|
||||||
inline const char* getError() { return errorMsg.c_str();}
|
|
||||||
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 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 isExecutable(int id) const { return (isValid() && !isPaused()); }
|
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
|
||||||
|
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
|
||||||
void Finalize();
|
|
||||||
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(); }
|
|
||||||
|
|
||||||
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);
|
||||||
void unloadPlugin( CPlugin** a );
|
void unloadPlugin( CPlugin** a );
|
||||||
int loadPluginsFromFile( const char* filename );
|
int loadPluginsFromFile( const char* filename );
|
||||||
|
|
||||||
CPlugin* findPluginFast(AMX *amx);
|
CPlugin* findPluginFast(AMX *amx);
|
||||||
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) {}
|
||||||
@ -142,9 +124,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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#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;
|
||||||
@ -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
|
||||||
|
|
||||||
|
105
amxmodx/CStack.h
105
amxmodx/CStack.h
@ -1,105 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//by David "BAILOPAN" Anderson
|
|
||||||
#ifndef _INCLUDE_CSTACK_H
|
|
||||||
#define _INCLUDE_CSTACK_H
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
class CStack
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct CStackItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
T item;
|
|
||||||
CStackItem *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
CStack()
|
|
||||||
{
|
|
||||||
mSize = 0;
|
|
||||||
mStack = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
~CStack()
|
|
||||||
{
|
|
||||||
CStackItem *p, *t;
|
|
||||||
p = mStack;
|
|
||||||
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
t = p->prev;
|
|
||||||
delete p;
|
|
||||||
p = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
mStack = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
return (mSize == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void push(const T & v)
|
|
||||||
{
|
|
||||||
CStackItem *p = new CStackItem;
|
|
||||||
p->item = v;
|
|
||||||
p->prev = mStack;
|
|
||||||
mStack = p;
|
|
||||||
mSize++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop()
|
|
||||||
{
|
|
||||||
CStackItem *p = mStack;
|
|
||||||
mStack = p->prev;
|
|
||||||
delete p;
|
|
||||||
mSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
T & top()
|
|
||||||
{
|
|
||||||
return mStack->item;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size()
|
|
||||||
{
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
CStackItem *mStack;
|
|
||||||
size_t mSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_INCLUDE_CQUEUE_H
|
|
@ -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)
|
|
||||||
{
|
|
||||||
Grow(512, false);
|
|
||||||
char *ret = fgets(v, 511, fp);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String(String &src)
|
String(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));
|
||||||
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,56 +100,79 @@ public:
|
|||||||
{
|
{
|
||||||
if (!d)
|
if (!d)
|
||||||
{
|
{
|
||||||
clear();
|
Grow(1);
|
||||||
} else {
|
cSize = 0;
|
||||||
Grow(strlen(d) + 1, false);
|
strcpy(v, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Grow(strlen(d));
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
strcpy(v, d);
|
strcpy(v, d);
|
||||||
|
cSize = strlen(v);
|
||||||
|
} else {
|
||||||
|
cSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (v)
|
if (v)
|
||||||
v[0] = '\0';
|
{
|
||||||
|
v[0] = 0;
|
||||||
|
cSize = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare (const char *d)
|
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()
|
bool empty()
|
||||||
{
|
{
|
||||||
if (!v)
|
if (!v || !cSize)
|
||||||
return true;
|
|
||||||
|
|
||||||
if (v[0] == '\0')
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size()
|
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)
|
||||||
{
|
{
|
||||||
size_t len = size();
|
if (!v)
|
||||||
if (len < 1)
|
|
||||||
return npos;
|
return npos;
|
||||||
if (index >= (int)len || index < 0)
|
if (index >= (int)cSize || index < 0)
|
||||||
return npos;
|
return npos;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for (i=index; i<(int)len; i++)
|
for (i=index; i<cSize; i++)
|
||||||
{
|
{
|
||||||
if (v[i] == c)
|
if (v[i] == c)
|
||||||
{
|
{
|
||||||
@ -169,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;
|
||||||
}
|
}
|
||||||
@ -181,12 +199,10 @@ public:
|
|||||||
{
|
{
|
||||||
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]))
|
||||||
{
|
{
|
||||||
@ -199,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;
|
||||||
@ -209,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))
|
||||||
@ -230,7 +246,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 1)
|
if (cSize == 1)
|
||||||
{
|
{
|
||||||
if (is_space(v[0]))
|
if (is_space(v[0]))
|
||||||
{
|
{
|
||||||
@ -240,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-num+1)
|
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 {
|
||||||
@ -263,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 {
|
||||||
@ -271,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, j=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;
|
||||||
}
|
}
|
||||||
@ -313,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,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 {
|
||||||
@ -346,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];
|
||||||
@ -354,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;
|
||||||
@ -363,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];
|
||||||
|
if (v) {
|
||||||
|
strcpy(t, v);
|
||||||
|
t[cSize] = 0;
|
||||||
delete [] v;
|
delete [] v;
|
||||||
else
|
}
|
||||||
strcpy(n, "");
|
v = t;
|
||||||
v = n;
|
mSize = d;
|
||||||
a_size = d + 1;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,7 +33,6 @@
|
|||||||
#include "CTask.h"
|
#include "CTask.h"
|
||||||
|
|
||||||
/*********************** CTask ***********************/
|
/*********************** CTask ***********************/
|
||||||
|
|
||||||
int CTaskMngr::CTask::getTaskId() const
|
int CTaskMngr::CTask::getTaskId() const
|
||||||
{
|
{
|
||||||
return m_iId;
|
return m_iId;
|
||||||
@ -46,7 +45,6 @@ CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
|
|||||||
|
|
||||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
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;
|
||||||
@ -54,17 +52,8 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
|||||||
m_iId = iId;
|
m_iId = iId;
|
||||||
m_fBase = fBase;
|
m_fBase = fBase;
|
||||||
|
|
||||||
if (iFlags & 2)
|
m_iRepeat = (iFlags & 1) ? iRepeat : 0;
|
||||||
{
|
m_bLoop = (iFlags & 2) ? true : false;
|
||||||
m_bLoop = true;
|
|
||||||
m_iRepeat = -1;
|
|
||||||
}
|
|
||||||
else if (iFlags & 1)
|
|
||||||
{
|
|
||||||
m_bLoop = true;
|
|
||||||
m_iRepeat = iRepeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bAfterStart = (iFlags & 4) ? true : false;
|
m_bAfterStart = (iFlags & 4) ? true : false;
|
||||||
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
||||||
|
|
||||||
@ -72,11 +61,14 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
|||||||
|
|
||||||
if (iParamsLen)
|
if (iParamsLen)
|
||||||
{
|
{
|
||||||
|
// also add a cell to the back with the value 0
|
||||||
m_iParamLen = iParamsLen + 1;
|
m_iParamLen = iParamsLen + 1;
|
||||||
m_pParams = new cell[m_iParamLen];
|
m_pParams = new cell[m_iParamLen];
|
||||||
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
|
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
|
||||||
m_pParams[iParamsLen] = 0;
|
m_pParams[iParamsLen] = 0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
m_iParamLen = 0;
|
m_iParamLen = 0;
|
||||||
m_pParams = NULL;
|
m_pParams = NULL;
|
||||||
}
|
}
|
||||||
@ -85,29 +77,8 @@ 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_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
|
||||||
@ -128,8 +99,6 @@ 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)
|
||||||
@ -141,63 +110,49 @@ 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_pPlugin->isExecutable(m_iFunc))
|
||||||
if (!(m_bLoop && !m_iRepeat))
|
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
if (m_iParamLen) // call with parameters
|
if (m_iParamLen) // call with parameters
|
||||||
{
|
{
|
||||||
cell arr = prepareCellArray(m_pParams, m_iParamLen);
|
cell amx_addr, *phys_addr;
|
||||||
executeForwards(m_iFunc, arr, m_iId);
|
if (amx_Allot(m_pPlugin->getAMX(), m_iParamLen, &amx_addr, &phys_addr) != AMX_ERR_NONE)
|
||||||
} else {
|
AMXXLOG_Log("[AMXX] Failed to allocate AMX memory (task \"%d\") (plugin \"%s\")", m_iId, m_pPlugin->getName());
|
||||||
executeForwards(m_iFunc, m_iId);
|
else
|
||||||
}
|
{
|
||||||
}
|
copy_amxmemory(phys_addr, m_pParams, m_iParamLen);
|
||||||
|
if ((err = amx_Exec(m_pPlugin->getAMX(), NULL, m_iFunc, 2, amx_addr, m_iId)) != AMX_ERR_NONE)
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (task \"%d\") (plugin \"%s\")", err, m_pPlugin->getAMX()->curline, m_iId, m_pPlugin->getName());
|
||||||
|
|
||||||
if (isFree())
|
amx_Release(m_pPlugin->getAMX(), amx_addr);
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((err = amx_Exec(m_pPlugin->getAMX(), NULL, m_iFunc, 1, m_iId)) != AMX_ERR_NONE)
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (task \"%d\") (plugin \"%s\")", err, m_pPlugin->getAMX()->curline, m_iId, m_pPlugin->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
{
|
||||||
|
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_fNextExecTime = 0.0f;
|
|
||||||
|
|
||||||
m_iParamLen = 0;
|
|
||||||
m_pParams = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CTaskMngr::CTask::~CTask()
|
CTaskMngr::CTask::~CTask()
|
||||||
@ -206,7 +161,6 @@ CTaskMngr::CTask::~CTask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*********************** CTaskMngr ***********************/
|
/*********************** CTaskMngr ***********************/
|
||||||
|
|
||||||
CTaskMngr::CTaskMngr()
|
CTaskMngr::CTaskMngr()
|
||||||
{
|
{
|
||||||
m_pTmr_CurrentTime = NULL;
|
m_pTmr_CurrentTime = NULL;
|
||||||
@ -214,11 +168,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;
|
||||||
@ -230,18 +179,17 @@ void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlag
|
|||||||
{
|
{
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
@ -252,14 +200,12 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +214,6 @@ 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);
|
||||||
@ -276,7 +221,6 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
|
|||||||
++i;
|
++i;
|
||||||
iter = m_Tasks.find(++iter, descriptor);
|
iter = m_Tasks.find(++iter, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,37 +39,34 @@ private:
|
|||||||
class CTask
|
class CTask
|
||||||
{
|
{
|
||||||
// task settings
|
// task settings
|
||||||
|
|
||||||
CPluginMngr::CPlugin *m_pPlugin;
|
CPluginMngr::CPlugin *m_pPlugin;
|
||||||
int m_iId;
|
int m_iId;
|
||||||
int m_iFunc;
|
int m_iFunc;
|
||||||
int m_iRepeat;
|
int m_iRepeat;
|
||||||
|
|
||||||
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, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
inline void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||||
void clear();
|
inline void clear();
|
||||||
bool isFree() const;
|
inline bool isFree() const;
|
||||||
|
|
||||||
CPluginMngr::CPlugin *getPlugin() const;
|
inline CPluginMngr::CPlugin *getPlugin() const;
|
||||||
int getTaskId() const;
|
inline int getTaskId() const;
|
||||||
|
|
||||||
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
inline void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
||||||
|
|
||||||
void changeBase(float fNewBase);
|
inline void changeBase(float fNewBase);
|
||||||
void resetNextExecTime(float fCurrentTime);
|
inline void resetNextExecTime(float fCurrentTime);
|
||||||
|
|
||||||
bool shouldRepeat();
|
inline bool shouldRepeat();
|
||||||
|
|
||||||
CTask();
|
CTask();
|
||||||
~CTask();
|
~CTask();
|
||||||
@ -94,32 +91,31 @@ private:
|
|||||||
if (right.m_bFree)
|
if (right.m_bFree)
|
||||||
return left.isFree();
|
return left.isFree();
|
||||||
|
|
||||||
return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
|
return !left.isFree() &&
|
||||||
|
(right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) &&
|
||||||
|
left.getTaskId() == right.m_iId;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*** CTaskMngr priv members ***/
|
/*** 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, int 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,7 +39,6 @@
|
|||||||
// *****************************************************
|
// *****************************************************
|
||||||
// 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;
|
||||||
@ -66,10 +65,10 @@ void Vault::put(const char* k, const char* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +136,7 @@ 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;
|
||||||
|
@ -45,7 +45,6 @@ class Vault
|
|||||||
{
|
{
|
||||||
String key;
|
String key;
|
||||||
String value;
|
String value;
|
||||||
|
|
||||||
int number;
|
int number;
|
||||||
Obj *next;
|
Obj *next;
|
||||||
Obj( const char* k, const char* v);
|
Obj( const char* k, const char* v);
|
||||||
@ -63,21 +62,17 @@ public:
|
|||||||
// Interface
|
// Interface
|
||||||
|
|
||||||
bool exists( const char* k );
|
bool exists( const char* k );
|
||||||
|
|
||||||
void put(const char* k, const char* v);
|
void put(const char* k, const char* v);
|
||||||
void remove( const char* k );
|
void remove( const char* k );
|
||||||
|
|
||||||
const char* get( const char* n );
|
const char* get( const char* n );
|
||||||
int get_number( const char* n );
|
int get_number( const char* n );
|
||||||
void setSource( const char* n );
|
void setSource( const char* n );
|
||||||
|
|
||||||
bool loadVault( );
|
bool loadVault( );
|
||||||
bool saveVault( );
|
bool saveVault( );
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
class iterator {
|
||||||
Obj * a;
|
Obj * a;
|
||||||
public:
|
public:
|
||||||
iterator(Obj*aa) : a(aa) {}
|
iterator(Obj*aa) : a(aa) {}
|
||||||
@ -92,4 +87,7 @@ public:
|
|||||||
inline iterator end() const { return iterator(0); }
|
inline iterator end() const { return iterator(0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //VAULT_CUSTOM_H
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,8 +32,6 @@
|
|||||||
#ifndef __CVECTOR_H__
|
#ifndef __CVECTOR_H__
|
||||||
#define __CVECTOR_H__
|
#define __CVECTOR_H__
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
// Vector
|
// Vector
|
||||||
template <class T> class CVector
|
template <class T> class CVector
|
||||||
{
|
{
|
||||||
@ -48,8 +46,7 @@ template <class T> class CVector
|
|||||||
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;
|
||||||
@ -70,58 +67,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
|
||||||
{
|
{
|
||||||
@ -215,7 +184,7 @@ public:
|
|||||||
|
|
||||||
iterator & operator-=(size_t offset)
|
iterator & operator-=(size_t offset)
|
||||||
{
|
{
|
||||||
m_Ptr -= offset;
|
m_Ptr += offset;
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +198,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,11 +249,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>()
|
||||||
@ -303,12 +271,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);
|
||||||
}
|
}
|
||||||
@ -316,15 +284,13 @@ public:
|
|||||||
iterator iterAt(size_t pos)
|
iterator iterAt(size_t pos)
|
||||||
{
|
{
|
||||||
if (pos > m_CurrentUsedSize)
|
if (pos > m_CurrentUsedSize)
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
return iterator(m_Data + pos);
|
return iterator(m_Data + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reserve(size_t newSize)
|
bool reserve(size_t newSize)
|
||||||
{
|
{
|
||||||
if (newSize > m_Size)
|
|
||||||
return ChangeSize(newSize);
|
return ChangeSize(newSize);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool push_back(const T & elem)
|
bool push_back(const T & elem)
|
||||||
@ -345,15 +311,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +331,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (pos > m_CurrentUsedSize)
|
if (pos > m_CurrentUsedSize)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[pos];
|
return m_Data[pos];
|
||||||
}
|
}
|
||||||
@ -375,7 +340,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (pos > m_CurrentUsedSize)
|
if (pos > m_CurrentUsedSize)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[pos];
|
return m_Data[pos];
|
||||||
}
|
}
|
||||||
@ -394,7 +359,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_CurrentUsedSize < 1)
|
if (m_CurrentUsedSize < 1)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[0];
|
return m_Data[0];
|
||||||
}
|
}
|
||||||
@ -403,7 +368,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_CurrentUsedSize < 1)
|
if (m_CurrentUsedSize < 1)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[0];
|
return m_Data[0];
|
||||||
}
|
}
|
||||||
@ -412,7 +377,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_CurrentUsedSize < 1)
|
if (m_CurrentUsedSize < 1)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[m_CurrentUsedSize - 1];
|
return m_Data[m_CurrentUsedSize - 1];
|
||||||
}
|
}
|
||||||
@ -421,18 +386,20 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_CurrentUsedSize < 1)
|
if (m_CurrentUsedSize < 1)
|
||||||
{
|
{
|
||||||
assert(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
return m_Data[m_CurrentUsedSize - 1];
|
return m_Data[m_CurrentUsedSize - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(iterator where, const T & value)
|
bool insert(iterator where, const T & value)
|
||||||
{
|
{
|
||||||
|
// we have to insert before
|
||||||
|
// if it is begin, don't decrement
|
||||||
|
if (where != m_Data)
|
||||||
|
--where;
|
||||||
// validate iter
|
// validate iter
|
||||||
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
|
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||||
return iterator(0);
|
return false;
|
||||||
|
|
||||||
size_t ofs = where - begin();
|
|
||||||
|
|
||||||
++m_CurrentUsedSize;
|
++m_CurrentUsedSize;
|
||||||
if (!GrowIfNeeded())
|
if (!GrowIfNeeded())
|
||||||
@ -441,50 +408,34 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
where = begin() + ofs;
|
memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data));
|
||||||
|
memcpy(where.base(), &value, sizeof(T));
|
||||||
// Move subsequent entries
|
return true;
|
||||||
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
|
|
||||||
*(ptr + 1) = *ptr;
|
|
||||||
|
|
||||||
*where.base() = value;
|
|
||||||
|
|
||||||
return where;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator erase(iterator where)
|
void erase(iterator where)
|
||||||
{
|
{
|
||||||
// validate iter
|
// validate iter
|
||||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||||
return iterator(0);
|
return false;
|
||||||
|
|
||||||
size_t ofs = where - begin();
|
|
||||||
|
|
||||||
if (m_CurrentUsedSize > 1)
|
if (m_CurrentUsedSize > 1)
|
||||||
{
|
{
|
||||||
// move
|
// move
|
||||||
T *theend = m_Data + m_CurrentUsedSize;
|
memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1);
|
||||||
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
|
|
||||||
*(ptr - 1) = *ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--m_CurrentUsedSize;
|
--m_CurrentUsedSize;
|
||||||
|
// :TODO: free memory sometimes
|
||||||
FreeMemIfPossible();
|
|
||||||
|
|
||||||
return begin() + ofs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
m_Size = 0;
|
m_Size = 0;
|
||||||
m_CurrentUsedSize = 0;
|
m_CurrentUsedSize = 0;
|
||||||
if (m_Data)
|
|
||||||
{
|
|
||||||
delete [] m_Data;
|
delete [] m_Data;
|
||||||
m_Data = NULL;
|
m_Data = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __CVECTOR_H__
|
#endif // __CVECTOR_H__
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,4 @@
|
|||||||
; AMXJITSN.ASM: Just-In-Time compiler for the Abstract Machine of the "Pawn"
|
; JIT.ASM: Just-In-Time compiler for the Abstract Machine of the "Small"language
|
||||||
; scripting language
|
|
||||||
; (C) 1999-2000, Marc Peter; beta version; provided AS IS WITHOUT ANY WARRANTIES
|
; (C) 1999-2000, Marc Peter; beta version; provided AS IS WITHOUT ANY WARRANTIES
|
||||||
|
|
||||||
; I reached >155 million instr./sec on my AMD K6-2/366 with the Hanoi "bench"
|
; I reached >155 million instr./sec on my AMD K6-2/366 with the Hanoi "bench"
|
||||||
@ -21,64 +20,18 @@
|
|||||||
; step.
|
; step.
|
||||||
|
|
||||||
; NOTE 3:
|
; NOTE 3:
|
||||||
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
; During execution of the compiled code with amx_exec_asm() the x86 processor's
|
||||||
|
; stack is switched into the data section of the abstract machine. This means
|
||||||
|
; that there should always be enough memory left between HEA and STK to provide
|
||||||
|
; stack space for occurring interrupts! (see the STACKRESERVE variable)
|
||||||
|
|
||||||
|
; NOTE 4:
|
||||||
|
; Although the Small compiler doesn't generate the LCTRL, SCTRL and CALL.I
|
||||||
; instructions, I have to tell that they don't work as expected in a JIT
|
; instructions, I have to tell that they don't work as expected in a JIT
|
||||||
; compiled program, because there is no easy way of transforming AMX code
|
; compiled program, because there is no easy way of transforming AMX code
|
||||||
; addresses and JIT translated ones. This might be fixed in a future version.
|
; addresses and JIT translated ones. This might be fixed in a future version.
|
||||||
|
|
||||||
; NOTE 4:
|
|
||||||
; Stack Pointer issues (by David Anderson)
|
|
||||||
; The JIT was changed recently so it no longer uses ESP as a general purpose
|
|
||||||
; register (GRP), because it can conflict with threading/signal systems which
|
|
||||||
; rely on the stack pointer being in-tact to find thread-ids. My fix for this
|
|
||||||
; was to keep esp safe, but save the stack pointer in 'ecx'. As such, ecx is no
|
|
||||||
; longer the CIP or scratch register, it is the save point for pieces of the AMX
|
|
||||||
; structure on the x86 stack.
|
|
||||||
; This means that the optimization of the JIT has changed, as every amx stack
|
|
||||||
; push call now takes two operations instead of one (same for pop), and pushing
|
|
||||||
; addresses is 4 instructions instead of 1.
|
|
||||||
; As of this moment I don't see a better way around it, but the sacrifice for
|
|
||||||
; having pthread-safe code was deemed to be necessary.
|
|
||||||
|
|
||||||
; NOTE 5:
|
|
||||||
; NX ("No eXecute") and XD (eXecution Denied) bits
|
|
||||||
; (by Thiadmer Riemersma)
|
|
||||||
;
|
|
||||||
; AMD defined a bit "No eXecute" for the page table entries (for its 64-bit
|
|
||||||
; processors) and Intel came with the same design, but calling it differently.
|
|
||||||
; The purpose is to make "buffer overrun" security holes impossible, or at least
|
|
||||||
; very, very difficult, by marking the stack and the heap as memory regions
|
|
||||||
; such that an attempt to execute processor instructions will cause a processor
|
|
||||||
; exception (of course, a buffer overrun that is not explictly handled will then
|
|
||||||
; crash the application --instead of executing the rogue code).
|
|
||||||
;
|
|
||||||
; For JIT compilers, this has the impact that you are not allowed to execute the
|
|
||||||
; code that the JIT has generated. To do that, you must adjust the attributes
|
|
||||||
; for the memory page. For Microsoft Windows, you can use VirtualAlloc() to
|
|
||||||
; allocate a memory block with the appropriate fags; on Linux (with a recent
|
|
||||||
; kernel), you would use vmalloc_exec(). Microsoft Windows also offers the
|
|
||||||
; function VirtualProtect() to change the page attributes of an existing memory
|
|
||||||
; block, but there are caveats in its use: if the block spans multiple pages,
|
|
||||||
; these pages must be consecutive, and if there are blocks of memory in a page
|
|
||||||
; unrelated to the JIT, their page attributes will change too.
|
|
||||||
;
|
|
||||||
; The JIT compiler itself requires only read-write access (this is the default
|
|
||||||
; for a memory block that you allocate). The execution of the JIT-compiled code
|
|
||||||
; requires full access to the memory block: read, write and execute. It needs
|
|
||||||
; write access, because the SYSREQ.C opcode is patched to SYSREQ.D after the
|
|
||||||
; first lookup (this is an optimization, look up the address of the native
|
|
||||||
; function only once). For processors that do not support the NX/XD bit,
|
|
||||||
; execution of code is implicitly supported if read access is supported.
|
|
||||||
;
|
|
||||||
; During compilation, the JIT compiler requires write-access to its own code
|
|
||||||
; segment: the JIT-compiler patches P-code parameters into its own code segment
|
|
||||||
; during compilation. This is handled in the support code for amx_InitJIT.
|
|
||||||
;
|
|
||||||
|
|
||||||
; NOTE 6:
|
|
||||||
; CALLING CONVENTIONS
|
|
||||||
; (by Thiadmer Riemersma)
|
|
||||||
;
|
;
|
||||||
|
; CALLING CONVENTIONS (by Thiadmer Riemersma)
|
||||||
; This version is the JIT that uses the "stack calling convention". In the
|
; This version is the JIT that uses the "stack calling convention". In the
|
||||||
; original implementation, this meant __cdecl; both for the calling convention
|
; original implementation, this meant __cdecl; both for the calling convention
|
||||||
; for the _asm_runJIT routine itself as for the callback functions.
|
; for the _asm_runJIT routine itself as for the callback functions.
|
||||||
@ -87,23 +40,8 @@
|
|||||||
; a reserved word on the assembler, I had to choose a different name for the
|
; a reserved word on the assembler, I had to choose a different name for the
|
||||||
; macro, hence STDECL.)
|
; macro, hence STDECL.)
|
||||||
|
|
||||||
|
|
||||||
; Revision History
|
; Revision History
|
||||||
; ----------------
|
;------------------
|
||||||
; 16 august 2005 by David "BAILOPAN" Anderson (DA)
|
|
||||||
; Changed JIT to not swap stack pointer during execution. This
|
|
||||||
; is playing with fire, especially with pthreads and signals on linux,
|
|
||||||
; where the stack pointer is used to find the current thread id. If
|
|
||||||
; the stack pointer is altered during a thread/signal switch/interrupt
|
|
||||||
; unexpected behaviour can occur (crashes).
|
|
||||||
; 26 july 2005 by David "BAILOPAN" Anderson (DA)
|
|
||||||
; Fixed a bug where zero casetbl entries would crash the JIT.
|
|
||||||
; 17 february 2005 by Thiadmer Riemersms
|
|
||||||
; Addition of the BREAK opcode, removal of the older debugging opcode
|
|
||||||
; table. There should now be some debug support (if enabled during the
|
|
||||||
; build of the JIT compiler), but not enough to run a debugger: the JIT
|
|
||||||
; compiler does not keep a list that relates the code addresses of the
|
|
||||||
; P-code versus the native code.
|
|
||||||
; 29 June 2004 by G.W.M. Vissers
|
; 29 June 2004 by G.W.M. Vissers
|
||||||
; Translated the thing into NASM. The actual generation of the code is
|
; Translated the thing into NASM. The actual generation of the code is
|
||||||
; put into the data section because the code modifies itself whereas the
|
; put into the data section because the code modifies itself whereas the
|
||||||
@ -150,8 +88,8 @@
|
|||||||
; hanoi bench.
|
; hanoi bench.
|
||||||
; 1999/08/05 MP
|
; 1999/08/05 MP
|
||||||
; * fixed OP_LINE in the case of NODBGCALLS==1, where no compiled address
|
; * fixed OP_LINE in the case of NODBGCALLS==1, where no compiled address
|
||||||
; was stored for the LINE byte code (i.e. SWITCH would jump to totally
|
; was stored for the LINE byte code (I.e. SWITCH would jump to totally
|
||||||
; wrong addresses). The same fix was applied to OP_FILL, OP_FILE and
|
; wrong addresses.) The same fix was applied to OP_FILL, OP_FILE and
|
||||||
; OP_SCTRL (for the no-op case).
|
; OP_SCTRL (for the no-op case).
|
||||||
; 1999/08/04 MP
|
; 1999/08/04 MP
|
||||||
; * updated with 4 new opcodes (SRANGE does nothing at the moment; 2dim.
|
; * updated with 4 new opcodes (SRANGE does nothing at the moment; 2dim.
|
||||||
@ -164,14 +102,13 @@
|
|||||||
; 1999/07/08 MP - initial revision
|
; 1999/07/08 MP - initial revision
|
||||||
|
|
||||||
|
|
||||||
|
; Controls generation of LINE op-codes: 0 - no, all other values - yes
|
||||||
|
; Beware that, if set to 1, this makes the compiled code slower by a factor of
|
||||||
|
; up to 3!
|
||||||
;
|
;
|
||||||
; Support for the BREAK opcode (callback to the debugger): 0 = no, all other
|
; GWMV: to generate LINE opcode, %define ALLOWOPLINE
|
||||||
; values = yes. Beware that the compiled code runs slower when this is enabled,
|
|
||||||
; and that debug support is still fairly minimal.
|
|
||||||
;
|
;
|
||||||
; GWMV: to generate LINE opcode, %define DEBUGSUPPORT
|
%undef ALLOWOPLINE
|
||||||
;
|
|
||||||
%undef DEBUGSUPPORT
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; If this is set to 1 the JIT generates relocatable code for case tables, too.
|
; If this is set to 1 the JIT generates relocatable code for case tables, too.
|
||||||
@ -182,66 +119,151 @@
|
|||||||
;
|
;
|
||||||
%define FORCERELOCATABLE
|
%define FORCERELOCATABLE
|
||||||
|
|
||||||
|
;
|
||||||
|
; Determines how much memory should be reserved for occurring interrupts.
|
||||||
|
; (If my memory serves me right, DOS4/G(W) provides a stack of 512 bytes
|
||||||
|
; for interrupts that occur in real mode and are promoted to protected mode.)
|
||||||
|
; This value _MUST_ be greater than 64 (for AMX needs) and should be at least
|
||||||
|
; 128 (to serve interrupts).
|
||||||
|
;
|
||||||
|
%define STACKRESERVE 256
|
||||||
|
|
||||||
;
|
;
|
||||||
; This variable controls the generation of memory range checks at run-time.
|
; This variable controls the generation of memory range checks at run-time.
|
||||||
; You should set this to 0, only when you are sure that there are no range
|
; You should set this to 0, only when you are sure that there are no range
|
||||||
; violations in your Pawn programs and you really need those 5% speed gain.
|
; violations in your Small programs and you really need those 5% speed gain.
|
||||||
;
|
;
|
||||||
; GWMV: To disable runtime checks, %undef it, instread of setting it to zero
|
; GWMV: To disable runtime checks, %undef it, instread of setting it to zero
|
||||||
;
|
;
|
||||||
%define DORUNTIMECHECKS
|
%define DORUNTIMECHECKS
|
||||||
|
|
||||||
%define JIT 1
|
|
||||||
%include "amxdefn.asm"
|
|
||||||
|
|
||||||
;Registers used for JIT during execution:
|
struc amx_s
|
||||||
; eax - pri
|
_base: resd 1
|
||||||
; ebx - reloc frame
|
_dataseg: resd 1
|
||||||
; ecx - info params
|
_callback: resd 1
|
||||||
; edx - alt
|
_debug: resd 1
|
||||||
; esi - AMX stack
|
_cip: resd 1
|
||||||
; edi - DAT
|
_frm: resd 1
|
||||||
; ebp - scratch
|
_hea: resd 1
|
||||||
|
_hlw: resd 1
|
||||||
|
_stk: resd 1
|
||||||
|
_stp: resd 1
|
||||||
|
_flags: resd 1
|
||||||
|
_curline: resd 1
|
||||||
|
_curfile: resd 1
|
||||||
|
_dbgcode: resd 1
|
||||||
|
_dbgaddr: resd 1
|
||||||
|
_dbgparam: resd 1
|
||||||
|
_dbgname: 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
|
||||||
|
_pri: resd 1
|
||||||
|
_alt: resd 1
|
||||||
|
_reset_stk: resd 1
|
||||||
|
_reset_hea: resd 1
|
||||||
|
_syscall_d: resd 1
|
||||||
|
; 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
|
||||||
|
endstruc
|
||||||
|
|
||||||
;DA:
|
|
||||||
; These are still stored in the stack, but the stack pointer
|
struc amxhead_s
|
||||||
; holding them is now kept in ecx.
|
_size: resd 1 ; size of the "file"
|
||||||
%define stk [ecx+32] ; define some aliases to registers that will
|
_magic: resw 1 ; signature
|
||||||
%define alt [ecx+28] ; be stored on the stack when the code is
|
_file_version: resb 1 ;file format version
|
||||||
%define pri [ecx+24] ; actually beeing executed
|
_amx_version: resb 1 ; required version of the AMX
|
||||||
%define code [ecx+20]
|
_h_flags: resw 1
|
||||||
%define amx [ecx+16]
|
_defsize: resw 1 ; size of one public/native function entry
|
||||||
%define retval [ecx+12]
|
_cod: resd 1 ; initial value of COD - code block
|
||||||
%define stp [ecx+8]
|
_dat: resd 1 ; initial value of DAT - data block
|
||||||
%define hea [ecx+4]
|
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||||
%define frm [ecx] ; FRM is NOT stored in ebp, FRM+DAT is being held
|
_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
|
||||||
|
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 ; MP: added for catching divide errors
|
||||||
|
AMX_ERR_SLEEP equ 12 ; (TR) go into sleep mode
|
||||||
|
|
||||||
|
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
|
||||||
|
DBG_SYMTAG equ 9
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
; GWMV:
|
||||||
|
; Nasm can't do the next as equivalence statements, since the value of
|
||||||
|
; esi is not determined at compile time
|
||||||
|
%define stk [esi+32] ; define some aliases to registers that will
|
||||||
|
%define alt [esi+28] ; be stored on the stack when the code is
|
||||||
|
%define pri [esi+24] ; actually beeing executed
|
||||||
|
%define code [esi+20]
|
||||||
|
%define amx [esi+16]
|
||||||
|
%define retval [esi+12]
|
||||||
|
%define stp [esi+8]
|
||||||
|
%define hea [esi+4]
|
||||||
|
%define frm [esi] ; FRM is NOT stored in ebp, FRM+DAT is being held
|
||||||
; in ebx instead.
|
; in ebx instead.
|
||||||
|
|
||||||
;
|
;
|
||||||
; #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
; #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
|
||||||
;
|
;
|
||||||
%macro _PUSH 1
|
%macro _PUSH 1
|
||||||
lea esi,[esi-4]
|
push dword %1
|
||||||
mov dword [esi], %1
|
|
||||||
%endmacro
|
|
||||||
|
|
||||||
%macro _PUSHMEM 1
|
|
||||||
lea esi,[esi-4]
|
|
||||||
mov ebp, dword %1
|
|
||||||
mov dword [esi], ebp
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
;
|
;
|
||||||
; #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
; #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
|
||||||
;
|
;
|
||||||
%macro _POP 1
|
%macro _POP 1
|
||||||
mov %1, dword [esi]
|
pop dword %1
|
||||||
lea esi,[esi+4]
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
; For determining the biggest native code section generated for ONE Pawn
|
; For determining the biggest native code section generated for ONE Small
|
||||||
; opcode. (See the following macro and the PUBLIC function getMaxCodeSize().)
|
; opcode. (See the following macro and the PUBLIC function getMaxCodeSize().)
|
||||||
;
|
;
|
||||||
; GWMV: Do NOT see the following macro. See CHECKCODESIZE instead.
|
; GWMV: Do NOT see the following macro. See CHECKCODESIZE instead.
|
||||||
@ -264,7 +286,7 @@
|
|||||||
; GWMV:
|
; GWMV:
|
||||||
; Nasm can't handle the determination of the maximum code size as was done
|
; Nasm can't handle the determination of the maximum code size as was done
|
||||||
; in the Masm implementation, since it only does two passes. This macro is
|
; in the Masm implementation, since it only does two passes. This macro is
|
||||||
; called *after* the code for each Pawn instruction.
|
; called *after* the code for each Small instruction.
|
||||||
%macro CHECKCODESIZE 1
|
%macro CHECKCODESIZE 1
|
||||||
%if MAXCODESIZE < $-%1
|
%if MAXCODESIZE < $-%1
|
||||||
%assign MAXCODESIZE $-%1
|
%assign MAXCODESIZE $-%1
|
||||||
@ -272,7 +294,7 @@
|
|||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
;
|
;
|
||||||
; Modify the argument of an x86 instruction with the Pawn opcode's parameter
|
; Modify the argument of an x86 instruction with the Small opcode's parameter
|
||||||
; before copying the code.
|
; before copying the code.
|
||||||
;
|
;
|
||||||
%macro putval 1
|
%macro putval 1
|
||||||
@ -308,7 +330,7 @@ section .text
|
|||||||
|
|
||||||
|
|
||||||
global asm_runJIT, _asm_runJIT
|
global asm_runJIT, _asm_runJIT
|
||||||
global amx_exec_jit, _amx_exec_jit
|
global amx_exec_asm, _amx_exec_asm
|
||||||
global getMaxCodeSize, _getMaxCodeSize
|
global getMaxCodeSize, _getMaxCodeSize
|
||||||
|
|
||||||
|
|
||||||
@ -433,7 +455,7 @@ reloc_done:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
; GWMV:
|
; GWMV:
|
||||||
; The code below modifies itself to store the arguments to the Pawn opcodes
|
; The code below modifies itself to store the arguments to the Small opcodes
|
||||||
; in the compiled code. This is fine, but the .text section in an ELF executable
|
; in the compiled code. This is fine, but the .text section in an ELF executable
|
||||||
; is usually marked read-only, that's why this code is in the .data section.
|
; is usually marked read-only, that's why this code is in the .data section.
|
||||||
|
|
||||||
@ -815,7 +837,7 @@ OP_LCTRL:
|
|||||||
jne lctrl_5
|
jne lctrl_5
|
||||||
GO_ON j_lctrl_4, lctrl_5, 8
|
GO_ON j_lctrl_4, lctrl_5, 8
|
||||||
j_lctrl_4:
|
j_lctrl_4:
|
||||||
mov eax,esi ; 4=STK
|
mov eax,esp ; 4=STK
|
||||||
sub eax,edi
|
sub eax,edi
|
||||||
CHECKCODESIZE j_lctrl_4
|
CHECKCODESIZE j_lctrl_4
|
||||||
lctrl_5:
|
lctrl_5:
|
||||||
@ -849,7 +871,7 @@ OP_SCTRL:
|
|||||||
j_sctrl_4:
|
j_sctrl_4:
|
||||||
;mov esp,eax ; 4=STK
|
;mov esp,eax ; 4=STK
|
||||||
;add esp,edi ; relocate stack
|
;add esp,edi ; relocate stack
|
||||||
lea esi,[eax+edi]
|
lea esp,[eax+edi]
|
||||||
CHECKCODESIZE j_sctrl_4
|
CHECKCODESIZE j_sctrl_4
|
||||||
sctrl_5:
|
sctrl_5:
|
||||||
cmp eax,5
|
cmp eax,5
|
||||||
@ -910,16 +932,14 @@ OP_PUSH_ALT:
|
|||||||
|
|
||||||
OP_PUSH_R_PRI:
|
OP_PUSH_R_PRI:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_r_pri+2
|
putval j_push_r_pri+1
|
||||||
GO_ON j_push_r_pri, OP_PUSH_C, 8
|
GO_ON j_push_r_pri, OP_PUSH_C, 8
|
||||||
|
|
||||||
j_push_r_pri:
|
j_push_r_pri:
|
||||||
push ecx
|
|
||||||
mov ecx,12345678h
|
mov ecx,12345678h
|
||||||
j_push_loop:
|
j_push_loop:
|
||||||
_PUSH eax
|
_PUSH eax
|
||||||
loop j_push_loop
|
loop j_push_loop
|
||||||
pop ecx
|
|
||||||
;dec ecx
|
;dec ecx
|
||||||
;jnz j_push_loop
|
;jnz j_push_loop
|
||||||
CHECKCODESIZE j_push_r_pri
|
CHECKCODESIZE j_push_r_pri
|
||||||
@ -927,33 +947,30 @@ OP_PUSH_R_PRI:
|
|||||||
;good
|
;good
|
||||||
OP_PUSH_C:
|
OP_PUSH_C:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_c_end-4
|
putval j_push_c+1
|
||||||
GO_ON j_push_c, OP_PUSH, 8
|
GO_ON j_push_c, OP_PUSH, 8
|
||||||
|
|
||||||
j_push_c:
|
j_push_c:
|
||||||
_PUSH 12345678h
|
_PUSH 12345678h
|
||||||
j_push_c_end:
|
|
||||||
CHECKCODESIZE j_push_c
|
CHECKCODESIZE j_push_c
|
||||||
|
|
||||||
OP_PUSH:
|
OP_PUSH:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_end-6
|
putval j_push+2
|
||||||
GO_ON j_push, OP_PUSH_S, 8
|
GO_ON j_push, OP_PUSH_S, 8
|
||||||
|
|
||||||
j_push:
|
j_push:
|
||||||
_PUSHMEM [edi+12345678h]
|
_PUSH [edi+12345678h]
|
||||||
j_push_end:
|
|
||||||
CHECKCODESIZE j_push
|
CHECKCODESIZE j_push
|
||||||
|
|
||||||
;good
|
;good
|
||||||
OP_PUSH_S:
|
OP_PUSH_S:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_push_s_end-6
|
putval j_push_s+2
|
||||||
GO_ON j_push_s, OP_POP_PRI, 8
|
GO_ON j_push_s, OP_POP_PRI, 8
|
||||||
|
|
||||||
j_push_s:
|
j_push_s:
|
||||||
_PUSHMEM [ebx+12345678h]
|
_PUSH [ebx+12345678h]
|
||||||
j_push_s_end:
|
|
||||||
CHECKCODESIZE j_push_s
|
CHECKCODESIZE j_push_s
|
||||||
|
|
||||||
OP_POP_PRI:
|
OP_POP_PRI:
|
||||||
@ -980,8 +997,8 @@ OP_STACK:
|
|||||||
GO_ON j_stack, OP_HEAP, 8
|
GO_ON j_stack, OP_HEAP, 8
|
||||||
|
|
||||||
j_stack:
|
j_stack:
|
||||||
mov edx,esi
|
mov edx,esp
|
||||||
add esi,12345678h
|
add esp,12345678h
|
||||||
sub edx,edi
|
sub edx,edi
|
||||||
%ifdef DORUNTIMECHECKS
|
%ifdef DORUNTIMECHECKS
|
||||||
call [chk_marginstack]
|
call [chk_marginstack]
|
||||||
@ -1009,9 +1026,9 @@ OP_PROC:
|
|||||||
GO_ON j_proc, OP_RET
|
GO_ON j_proc, OP_RET
|
||||||
|
|
||||||
j_proc: ;[STK] = FRM, STK = STK - cell size, FRM = STK
|
j_proc: ;[STK] = FRM, STK = STK - cell size, FRM = STK
|
||||||
_PUSHMEM frm ; push old frame (for RET/RETN)
|
_PUSH frm ; push old frame (for RET/RETN)
|
||||||
mov frm,esi ; get new frame
|
mov frm,esp ; get new frame
|
||||||
mov ebx,esi ; already relocated
|
mov ebx,esp ; already relocated
|
||||||
sub frm,edi ; relocate frame
|
sub frm,edi ; relocate frame
|
||||||
CHECKCODESIZE j_proc
|
CHECKCODESIZE j_proc
|
||||||
|
|
||||||
@ -1021,7 +1038,6 @@ OP_RET:
|
|||||||
|
|
||||||
j_ret:
|
j_ret:
|
||||||
_POP ebx ; pop frame
|
_POP ebx ; pop frame
|
||||||
lea esi,[esi+4]
|
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
add ebx,edi
|
add ebx,edi
|
||||||
ret
|
ret
|
||||||
@ -1040,13 +1056,11 @@ OP_RETN:
|
|||||||
;good
|
;good
|
||||||
OP_CALL:
|
OP_CALL:
|
||||||
;nop;
|
;nop;
|
||||||
RELOC j_call_e8-j_call+1
|
RELOC 1
|
||||||
GO_ON j_call, OP_CALL_I, 8
|
GO_ON j_call, OP_CALL_I, 8
|
||||||
|
|
||||||
j_call:
|
j_call:
|
||||||
;call 12345678h ; tasm chokes on this out of a sudden
|
;call 12345678h ; tasm chokes on this out of a sudden
|
||||||
_PUSH 0
|
|
||||||
j_call_e8
|
|
||||||
db 0e8h, 0, 0, 0, 0
|
db 0e8h, 0, 0, 0, 0
|
||||||
CHECKCODESIZE j_call
|
CHECKCODESIZE j_call
|
||||||
|
|
||||||
@ -1055,7 +1069,6 @@ OP_CALL_I:
|
|||||||
GO_ON j_call_i, OP_JUMP
|
GO_ON j_call_i, OP_JUMP
|
||||||
|
|
||||||
j_call_i:
|
j_call_i:
|
||||||
_PUSH 0
|
|
||||||
call eax
|
call eax
|
||||||
CHECKCODESIZE j_call_i
|
CHECKCODESIZE j_call_i
|
||||||
|
|
||||||
@ -1206,30 +1219,24 @@ OP_SHL:
|
|||||||
;nop;
|
;nop;
|
||||||
GO_ON j_shl, OP_SHR
|
GO_ON j_shl, OP_SHR
|
||||||
j_shl:
|
j_shl:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
shl eax,cl
|
shl eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_shl
|
CHECKCODESIZE j_shl
|
||||||
|
|
||||||
OP_SHR:
|
OP_SHR:
|
||||||
;nop;
|
;nop;
|
||||||
GO_ON j_shr, OP_SSHR
|
GO_ON j_shr, OP_SSHR
|
||||||
j_shr:
|
j_shr:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
shr eax,cl
|
shr eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_shr
|
CHECKCODESIZE j_shr
|
||||||
|
|
||||||
OP_SSHR:
|
OP_SSHR:
|
||||||
;nop;
|
;nop;
|
||||||
GO_ON j_sshr, OP_SHL_C_PRI
|
GO_ON j_sshr, OP_SHL_C_PRI
|
||||||
j_sshr:
|
j_sshr:
|
||||||
push ecx
|
mov ecx,edx ; TODO: save ECX if used as special register
|
||||||
mov ecx,edx
|
|
||||||
sar eax,cl
|
sar eax,cl
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_sshr
|
CHECKCODESIZE j_sshr
|
||||||
|
|
||||||
OP_SHL_C_PRI:
|
OP_SHL_C_PRI:
|
||||||
@ -1648,35 +1655,29 @@ OP_DEC_I:
|
|||||||
|
|
||||||
OP_MOVS:
|
OP_MOVS:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_movs+2
|
putval j_movs+1
|
||||||
GO_ON j_movs, OP_CMPS, 8
|
GO_ON j_movs, OP_CMPS, 8
|
||||||
j_movs:
|
j_movs:
|
||||||
push ecx
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
mov ecx,12345678h
|
|
||||||
call [jit_movs]
|
call [jit_movs]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_movs
|
CHECKCODESIZE j_movs
|
||||||
|
|
||||||
OP_CMPS:
|
OP_CMPS:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_cmps+2
|
putval j_cmps+1
|
||||||
GO_ON j_cmps, OP_FILL, 8
|
GO_ON j_cmps, OP_FILL, 8
|
||||||
j_cmps:
|
j_cmps:
|
||||||
push ecx
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
mov ecx,12345678h
|
|
||||||
call [jit_cmps]
|
call [jit_cmps]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_cmps
|
CHECKCODESIZE j_cmps
|
||||||
|
|
||||||
OP_FILL:
|
OP_FILL:
|
||||||
;nop;
|
;nop;
|
||||||
putval j_fill+2
|
putval j_fill+1
|
||||||
GO_ON j_fill, OP_HALT, 8
|
GO_ON j_fill, OP_HALT, 8
|
||||||
j_fill:
|
j_fill:
|
||||||
push ecx
|
|
||||||
mov ecx,12345678h ;TODO: save ECX if used as special register
|
mov ecx,12345678h ;TODO: save ECX if used as special register
|
||||||
call [jit_fill]
|
call [jit_fill]
|
||||||
pop ecx
|
|
||||||
CHECKCODESIZE j_fill
|
CHECKCODESIZE j_fill
|
||||||
|
|
||||||
;good
|
;good
|
||||||
@ -1733,11 +1734,23 @@ OP_FILE: ;opcode is simply ignored
|
|||||||
|
|
||||||
OP_LINE:
|
OP_LINE:
|
||||||
;nop;
|
;nop;
|
||||||
|
%ifndef ALLOWOPLINE
|
||||||
mov [ebx],edi ; no line number support: ignore opcode
|
mov [ebx],edi ; no line number support: ignore opcode
|
||||||
add ebx,12 ; move on to next opcode
|
add ebx,12 ; move on to next opcode
|
||||||
cmp ebx,[end_code]
|
cmp ebx,[end_code]
|
||||||
jae code_gen_done
|
jae code_gen_done
|
||||||
jmp dword [ebx] ; go on with the next opcode
|
jmp dword [ebx] ; go on with the next opcode
|
||||||
|
%else
|
||||||
|
putval j_line+6
|
||||||
|
mov eax,[ebx+8]
|
||||||
|
mov [j_line_sm],eax
|
||||||
|
GO_ON j_line, OP_SYMBOL, 12
|
||||||
|
j_line:
|
||||||
|
call [jit_line]
|
||||||
|
DD 0 ; space for curline
|
||||||
|
j_line_sm DD 0 ; space for curfile
|
||||||
|
CHECKCODESIZE j_line
|
||||||
|
%endif
|
||||||
|
|
||||||
OP_SYMBOL: ;ignored
|
OP_SYMBOL: ;ignored
|
||||||
mov [ebx],edi
|
mov [ebx],edi
|
||||||
@ -1868,23 +1881,6 @@ OP_SYMTAG: ;ignored (TR)
|
|||||||
jmp dword [ebx] ; go on with the next opcode
|
jmp dword [ebx] ; go on with the next opcode
|
||||||
|
|
||||||
|
|
||||||
OP_BREAK:
|
|
||||||
%ifndef DEBUGSUPPORT
|
|
||||||
mov [ebx],edi ; no line number support: ignore opcode
|
|
||||||
add ebx,4 ; move on to next opcode
|
|
||||||
cmp ebx,[end_code]
|
|
||||||
jae code_gen_done
|
|
||||||
jmp DWORD [ebx] ; go on with the next opcode
|
|
||||||
%else
|
|
||||||
GO_ON j_break, OP_INVALID
|
|
||||||
j_break:
|
|
||||||
mov ebp,amx
|
|
||||||
cmp DWORD [ebp+_debug], 0
|
|
||||||
je $+4 ; jump around the "call" statement
|
|
||||||
call [jit_break]
|
|
||||||
CHECKCODESIZE j_break
|
|
||||||
%endif
|
|
||||||
|
|
||||||
OP_INVALID: ; break from the compiler with an error code
|
OP_INVALID: ; break from the compiler with an error code
|
||||||
mov eax,AMX_ERR_INVINSTR
|
mov eax,AMX_ERR_INVINSTR
|
||||||
pop esi
|
pop esi
|
||||||
@ -1898,12 +1894,12 @@ section .text
|
|||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; ;
|
; ;
|
||||||
;cell amx_exec( cell *regs, cell *retval, cell stp, cell hea );
|
;cell asm_exec( cell *regs, cell *retval, cell stp, cell hea );
|
||||||
; eax edx ebx ecx ;
|
; eax edx ebx ecx ;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
amx_exec_jit:
|
amx_exec_asm:
|
||||||
_amx_exec_jit:
|
_amx_exec_asm:
|
||||||
push edi
|
push edi
|
||||||
push esi
|
push esi
|
||||||
push ebp
|
push ebp
|
||||||
@ -1925,7 +1921,7 @@ _amx_exec_jit:
|
|||||||
push dword [eax+20]; store FRM
|
push dword [eax+20]; store FRM
|
||||||
|
|
||||||
mov edx,[eax+4] ; get ALT
|
mov edx,[eax+4] ; get ALT
|
||||||
mov ebp,[eax+8] ; get CIP
|
mov ecx,[eax+8] ; get CIP
|
||||||
mov edi,[eax+12] ; get pointer to data segment
|
mov edi,[eax+12] ; get pointer to data segment
|
||||||
mov esi,[eax+16] ; get STK !!changed, now ECX free as counter!!
|
mov esi,[eax+16] ; get STK !!changed, now ECX free as counter!!
|
||||||
mov ebx,[eax+20] ; get FRM
|
mov ebx,[eax+20] ; get FRM
|
||||||
@ -1933,14 +1929,13 @@ _amx_exec_jit:
|
|||||||
add ebx,edi ; relocate frame
|
add ebx,edi ; relocate frame
|
||||||
|
|
||||||
add esi,edi ; ESP will contain DAT+STK
|
add esi,edi ; ESP will contain DAT+STK
|
||||||
|
xchg esp,esi ; switch to AMX stack
|
||||||
|
|
||||||
add [esp+8],edi ; make STP absolute address for run-time checks
|
add stp,edi ; make STP absolute address for run-time checks
|
||||||
|
|
||||||
mov dword [esi], 0 ; zero this out, but we need to keep it so
|
_POP ebp ; AMX pseudo-return address, ignored
|
||||||
; the stack frame is in tact
|
|
||||||
mov ecx,esp ; copy stack pointer
|
|
||||||
; Call compiled code via CALL NEAR <address>
|
; Call compiled code via CALL NEAR <address>
|
||||||
call ebp
|
call ecx
|
||||||
|
|
||||||
return_to_caller:
|
return_to_caller:
|
||||||
cmp dword retval,0
|
cmp dword retval,0
|
||||||
@ -1953,17 +1948,15 @@ return_to_caller:
|
|||||||
jmp _return
|
jmp _return
|
||||||
|
|
||||||
_return_popstack:
|
_return_popstack:
|
||||||
mov esp,ecx ; get our old stack pointer
|
add esp,4 ; Correct ESP, because we just come from a
|
||||||
|
; runtime error checking routine.
|
||||||
_return:
|
_return:
|
||||||
; store machine state
|
; store machine state
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push ecx
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
mov ecx,esi ; get STK into ECX
|
|
||||||
|
|
||||||
sub ecx,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov [ebp+_stk],ecx ; store values in AMX structure: STK, ...
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK, ...
|
||||||
pop ecx ; get orig value
|
|
||||||
mov ecx,hea ; ... HEA, ...
|
mov ecx,hea ; ... HEA, ...
|
||||||
mov [ebp+_hea],ecx
|
mov [ebp+_hea],ecx
|
||||||
mov ecx,ebx ; ... and FRM
|
mov ecx,ebx ; ... and FRM
|
||||||
@ -1973,8 +1966,8 @@ _return:
|
|||||||
mov [ebp+_alt],edx ; ... and ALT
|
mov [ebp+_alt],edx ; ... and ALT
|
||||||
|
|
||||||
; return
|
; return
|
||||||
pop ecx
|
|
||||||
sub stp,edi ; make STP relative to DAT again
|
sub stp,edi ; make STP relative to DAT again
|
||||||
|
xchg esp,esi ; switch back to caller's stack
|
||||||
|
|
||||||
add esp,4*9 ; remove temporary data
|
add esp,4*9 ; remove temporary data
|
||||||
|
|
||||||
@ -1995,8 +1988,12 @@ err_stacklow:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
_CHKMARGIN_STACK: ; some run-time check routines
|
_CHKMARGIN_STACK: ; some run-time check routines
|
||||||
cmp esi,stp
|
cmp esp,stp
|
||||||
|
lea ebp,[esp-STACKRESERVE]
|
||||||
jg err_stacklow
|
jg err_stacklow
|
||||||
|
sub ebp,edi
|
||||||
|
cmp hea,ebp
|
||||||
|
jg err_stack
|
||||||
ret
|
ret
|
||||||
|
|
||||||
err_heaplow:
|
err_heaplow:
|
||||||
@ -2004,7 +2001,7 @@ err_heaplow:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
_CHKMARGIN_HEAP:
|
_CHKMARGIN_HEAP:
|
||||||
cmp esi,stp
|
cmp esp,stp
|
||||||
jg err_stacklow
|
jg err_stacklow
|
||||||
cmp dword hea,0
|
cmp dword hea,0
|
||||||
jl err_heaplow
|
jl err_heaplow
|
||||||
@ -2020,7 +2017,7 @@ _VERIFYADDRESS_eax: ; used in load.i, store.i & lidx
|
|||||||
cmp eax,hea
|
cmp eax,hea
|
||||||
jb veax1
|
jb veax1
|
||||||
lea ebp,[eax+edi]
|
lea ebp,[eax+edi]
|
||||||
cmp ebp,esi
|
cmp ebp,esp
|
||||||
jb err_memaccess
|
jb err_memaccess
|
||||||
veax1:
|
veax1:
|
||||||
ret
|
ret
|
||||||
@ -2031,7 +2028,7 @@ _VERIFYADDRESS_edx: ; used in load.i, store.i & lidx
|
|||||||
cmp edx,hea
|
cmp edx,hea
|
||||||
jb vedx1
|
jb vedx1
|
||||||
lea ebp,[edx+edi]
|
lea ebp,[edx+edi]
|
||||||
cmp ebp,esi
|
cmp ebp,esp
|
||||||
jb err_memaccess
|
jb err_memaccess
|
||||||
vedx1:
|
vedx1:
|
||||||
ret
|
ret
|
||||||
@ -2063,15 +2060,15 @@ JIT_OP_SDIV:
|
|||||||
|
|
||||||
JIT_OP_RETN:
|
JIT_OP_RETN:
|
||||||
_POP ebx ; pop frame
|
_POP ebx ; pop frame
|
||||||
add esi,4 ; get rid of the extra parameter from call
|
_POP ecx ; get return address
|
||||||
|
|
||||||
mov frm,ebx
|
mov frm,ebx
|
||||||
_POP ebp
|
_POP ebp
|
||||||
|
|
||||||
add ebx,edi
|
add ebx,edi
|
||||||
add esi,ebp ; remove data from stack
|
add esp,ebp ; remove data from stack
|
||||||
|
|
||||||
ret
|
jmp ecx
|
||||||
|
|
||||||
|
|
||||||
JIT_OP_MOVS: ;length of block to copy is already in ECX
|
JIT_OP_MOVS: ;length of block to copy is already in ECX
|
||||||
@ -2137,33 +2134,34 @@ err_divide:
|
|||||||
jmp _return_popstack
|
jmp _return_popstack
|
||||||
|
|
||||||
JIT_OP_SYSREQ:
|
JIT_OP_SYSREQ:
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push esi
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov alt,edx ; save ALT
|
mov alt,edx ; save ALT
|
||||||
|
|
||||||
mov [ebp+_stk],esi ; store values in AMX structure: STK,
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
|
||||||
mov esi,hea ; HEA,
|
mov ecx,hea ; HEA,
|
||||||
mov ebx,frm ; and FRM
|
mov ebx,frm ; and FRM
|
||||||
mov [ebp+_hea],esi
|
mov [ebp+_hea],ecx
|
||||||
mov [ebp+_frm],ebx
|
mov [ebp+_frm],ebx
|
||||||
|
|
||||||
lea ebx,pri ; 3rd param: addr. of retval
|
lea ebx,pri ; 3rd param: addr. of retval
|
||||||
|
lea ecx,[esp+4] ; 4th param: parameter array
|
||||||
|
|
||||||
;Our original esi is still pushed!
|
xchg esp,esi ; switch to caller stack
|
||||||
|
|
||||||
|
push ecx
|
||||||
push ebx
|
push ebx
|
||||||
push eax ; 2nd param: function number
|
push eax ; 2nd param: function number
|
||||||
push ebp ; 1st param: amx
|
push ebp ; 1st param: amx
|
||||||
call [ebp+_callback]
|
call [ebp+_callback]
|
||||||
_DROPARGS 12 ; remove args from stack
|
_DROPARGS 16 ; remove args from stack
|
||||||
|
|
||||||
pop esi
|
xchg esp,esi ; switch back to AMX stack
|
||||||
pop ecx
|
|
||||||
cmp eax,AMX_ERR_NONE
|
cmp eax,AMX_ERR_NONE
|
||||||
jne _return_popstack
|
jne _return_popstack; return error code, if any
|
||||||
.continue:
|
|
||||||
mov eax,pri ; get retval into eax (PRI)
|
mov eax,pri ; get retval into eax (PRI)
|
||||||
mov edx,alt ; restore ALT
|
mov edx,alt ; restore ALT
|
||||||
mov ebx,frm ; restore FRM
|
mov ebx,frm ; restore FRM
|
||||||
@ -2172,25 +2170,25 @@ JIT_OP_SYSREQ:
|
|||||||
|
|
||||||
|
|
||||||
JIT_OP_SYSREQ_D: ; (TR)
|
JIT_OP_SYSREQ_D: ; (TR)
|
||||||
push ecx
|
mov ecx,esp ; get STK into ECX
|
||||||
push esi
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
sub ecx,edi ; correct STK
|
||||||
mov alt,edx ; save ALT
|
mov alt,edx ; save ALT
|
||||||
|
|
||||||
mov [ebp+_stk],esi ; store values in AMX structure: STK,
|
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
|
||||||
mov esi,hea ; HEA,
|
mov ecx,hea ; HEA,
|
||||||
mov eax,frm ; and FRM
|
mov eax,frm ; and FRM
|
||||||
mov [ebp+_hea],esi
|
mov [ebp+_hea],ecx
|
||||||
mov [ebp+_frm],eax ; eax & ecx are invalid by now
|
mov [ebp+_frm],eax ; eax & ecx are invalid by now
|
||||||
|
|
||||||
;esi is still pushed!
|
lea edx,[esp+4] ; 2nd param: parameter array
|
||||||
|
xchg esp,esi ; switch to caller stack
|
||||||
|
push edx
|
||||||
push ebp ; 1st param: amx
|
push ebp ; 1st param: amx
|
||||||
call ebx ; direct call
|
call ebx ; direct call
|
||||||
_DROPARGS 8 ; remove args from stack
|
_DROPARGS 8 ; remove args from stack
|
||||||
|
xchg esp,esi ; switch back to AMX stack
|
||||||
pop ecx
|
|
||||||
mov ebp,amx ; get amx into EBP
|
mov ebp,amx ; get amx into EBP
|
||||||
cmp dword [ebp+_error],AMX_ERR_NONE
|
cmp dword [ebp+_error],AMX_ERR_NONE
|
||||||
jne _return_popstack; return error code, if any
|
jne _return_popstack; return error code, if any
|
||||||
@ -2202,57 +2200,32 @@ JIT_OP_SYSREQ_D: ; (TR)
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
JIT_OP_BREAK:
|
JIT_OP_LINE:
|
||||||
%ifdef DEBUGSUPPORT
|
pop ecx ; get return address
|
||||||
push ecx
|
mov ebp,amx
|
||||||
push esi
|
push eax
|
||||||
mov ebp,amx ; get amx into EBP
|
push edx
|
||||||
|
mov eax,[ecx] ; get curline
|
||||||
|
mov edx,[ecx+4] ; get curfile
|
||||||
|
add ecx,8 ; skip curline & curfile
|
||||||
|
mov [ebp+_curline],eax ; store curline
|
||||||
|
mov [ebp+_curfile],edx ; store curfile
|
||||||
|
|
||||||
sub esi,edi ; correct STK
|
pop edx
|
||||||
|
pop eax
|
||||||
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
|
jmp ecx ; jump back
|
||||||
mov [ebp+_alt],edx ; ALT,
|
|
||||||
mov [ebp+_stk],esi ; STK,
|
|
||||||
mov esi,hea ; HEA,
|
|
||||||
mov ebx,frm ; and FRM
|
|
||||||
mov [ebp+_hea],esi
|
|
||||||
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
|
|
||||||
;??? storing CIP is not very useful, because the code changed (during JIT compile)
|
|
||||||
|
|
||||||
push ebp ; 1st param: amx
|
|
||||||
call [ebp+_debug]
|
|
||||||
_DROPARGS 4 ; remove args from stack
|
|
||||||
|
|
||||||
pop esi
|
|
||||||
pop ecx
|
|
||||||
cmp eax,AMX_ERR_NONE
|
|
||||||
jne _return_popstack; return error code, if any
|
|
||||||
|
|
||||||
mov ebp,amx ; get amx into EBP
|
|
||||||
mov eax,[ebp+_pri] ; restore values
|
|
||||||
mov edx,[ebp+_alt] ; ALT,
|
|
||||||
mov edx,alt ; restore ALT
|
|
||||||
mov ebx,frm ; restore FRM
|
|
||||||
add ebx,edi ; relocate frame
|
|
||||||
%endif
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
JIT_OP_SWITCH:
|
JIT_OP_SWITCH:
|
||||||
pop ebp ; pop return address = table address
|
pop ebp ; pop return address = table address
|
||||||
push ecx
|
|
||||||
mov ecx,[ebp] ; ECX = number of records
|
mov ecx,[ebp] ; ECX = number of records
|
||||||
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
|
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
|
||||||
;if there are zero cases we should just skip this -- bail
|
|
||||||
test ecx, ecx
|
|
||||||
jz op_switch_jump
|
|
||||||
op_switch_loop:
|
op_switch_loop:
|
||||||
cmp eax,[ebp-8] ; PRI == case label?
|
cmp eax,[ebp-8] ; PRI == case label?
|
||||||
je op_switch_jump ; found, jump
|
je op_switch_jump ; found, jump
|
||||||
sub ebp,8 ; position to preceding case
|
sub ebp,8 ; position to preceding case
|
||||||
loop op_switch_loop ; check next case, or fall through
|
loop op_switch_loop ; check next case, or fall through
|
||||||
op_switch_jump:
|
op_switch_jump:
|
||||||
pop ecx
|
|
||||||
%ifndef FORCERELOCATABLE
|
%ifndef FORCERELOCATABLE
|
||||||
jmp [ebp-4] ; jump to the case instructions
|
jmp [ebp-4] ; jump to the case instructions
|
||||||
%else
|
%else
|
||||||
@ -2261,10 +2234,9 @@ JIT_OP_SWITCH:
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; The caller of asm_runJIT() can determine the maximum size of the compiled
|
; The caller of asm_runJIT() can determine the maximum size of the compiled
|
||||||
; code by multiplying the result of this function by the number of opcodes in
|
; code by multiplying the result of this function by the number of opcodes in
|
||||||
; Pawn module.
|
; Small module.
|
||||||
;
|
;
|
||||||
; unsigned long getMaxCodeSize_();
|
; unsigned long getMaxCodeSize_();
|
||||||
;
|
;
|
||||||
@ -2306,17 +2278,17 @@ jit_fill DD JIT_OP_FILL
|
|||||||
jit_bounds DD JIT_OP_BOUNDS
|
jit_bounds DD JIT_OP_BOUNDS
|
||||||
jit_sysreq DD JIT_OP_SYSREQ
|
jit_sysreq DD JIT_OP_SYSREQ
|
||||||
jit_sysreq_d DD JIT_OP_SYSREQ_D
|
jit_sysreq_d DD JIT_OP_SYSREQ_D
|
||||||
jit_break DD JIT_OP_BREAK
|
jit_line DD JIT_OP_LINE
|
||||||
jit_switch DD JIT_OP_SWITCH
|
jit_switch DD JIT_OP_SWITCH
|
||||||
|
|
||||||
;
|
;
|
||||||
; The table for the browser/relocator function.
|
; The table for the browser/relocator function.
|
||||||
;
|
;
|
||||||
|
|
||||||
global amx_opcodelist_jit, _amx_opcodelist_jit
|
global amx_opcodelist, _amx_opcodelist
|
||||||
|
|
||||||
amx_opcodelist_jit:
|
amx_opcodelist:
|
||||||
_amx_opcodelist_jit:
|
_amx_opcodelist:
|
||||||
DD OP_INVALID
|
DD OP_INVALID
|
||||||
DD OP_LOAD_PRI
|
DD OP_LOAD_PRI
|
||||||
DD OP_LOAD_ALT
|
DD OP_LOAD_ALT
|
||||||
@ -2454,6 +2426,3 @@ _amx_opcodelist_jit:
|
|||||||
DD OP_NOP ; TR
|
DD OP_NOP ; TR
|
||||||
DD OP_SYSREQ_D ; TR
|
DD OP_SYSREQ_D ; TR
|
||||||
DD OP_SYMTAG ; TR
|
DD OP_SYMTAG ; TR
|
||||||
DD OP_BREAK ; TR
|
|
||||||
|
|
||||||
END
|
|
10
amxmodx/JIT/jits.def
Executable file
10
amxmodx/JIT/jits.def
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
LIBRARY jits
|
||||||
|
DESCRIPTION "JIT for AMX Mod X"
|
||||||
|
EXPORTS
|
||||||
|
asm_runJIT @1
|
||||||
|
getMaxCodeSize @2
|
||||||
|
amx_exec_asm @3
|
||||||
|
amx_opcodelist @4
|
||||||
|
SECTIONS
|
||||||
|
.data READ WRITE
|
||||||
|
.code EXECUTE
|
BIN
amxmodx/JIT/jits.exp
Executable file
BIN
amxmodx/JIT/jits.exp
Executable file
Binary file not shown.
BIN
amxmodx/JIT/jits.lib
Executable file
BIN
amxmodx/JIT/jits.lib
Executable file
Binary file not shown.
BIN
amxmodx/JIT/jits.o
Executable file
BIN
amxmodx/JIT/jits.o
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
166
amxmodx/Makefile
166
amxmodx/Makefile
@ -1,95 +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/SourceCode
|
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 -funroll-loops -s -pipe
|
EXTRA_FLAGS = -Dstrcmpi=strcasecmp
|
||||||
DEBUG_FLAGS = -g -ggdb3
|
|
||||||
CPP = gcc
|
|
||||||
NAME = amxmodx_mm
|
|
||||||
|
|
||||||
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
SDKTOP=../hlsdk
|
||||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
METADIR=../metamod/metamod
|
||||||
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
|
|
||||||
|
|
||||||
LINK = -lz
|
|
||||||
|
|
||||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
SDKSRC=$(SDKTOP)/SourceCode
|
||||||
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
OBJDIR_LINUX=obj.linux
|
||||||
|
OBJDIR_WIN32=obj.win32
|
||||||
|
SRCDIR=.
|
||||||
|
|
||||||
ifeq "$(DEBUG)" "true"
|
ifdef windir
|
||||||
BIN_DIR = Debug
|
OS=WIN32
|
||||||
CFLAGS = $(DEBUG_FLAGS)
|
|
||||||
else
|
else
|
||||||
BIN_DIR = Release
|
OS=LINUX
|
||||||
CFLAGS = $(OPT_FLAGS)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq "$(MMGR)" "true"
|
CC_LINUX=gcc
|
||||||
OBJECTS += mmgr/mmgr.cpp
|
ifeq "$(OS)" "WIN32"
|
||||||
CFLAGS += -DMEMORY_TEST
|
CC_WIN32=gcc
|
||||||
endif
|
LD_WINDLL=dllwrap
|
||||||
|
DEFAULT=win32
|
||||||
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
|
CLEAN=clean_win32
|
||||||
|
|
||||||
ifeq "$(AMD64)" "true"
|
|
||||||
BINARY = $(NAME)_amd64.so
|
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
|
|
||||||
OBJECTS += JIT/natives-amd64.o
|
|
||||||
else
|
else
|
||||||
BINARY = $(NAME)_i386.so
|
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
|
||||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
DEFAULT=linux win32
|
||||||
OPT_FLAGS += -march=i686
|
CLEAN=clean_both
|
||||||
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_mmgr:
|
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 MMGR=true
|
ODEF = -DOPT_TYPE=\"optimized\"
|
||||||
|
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
|
||||||
|
|
||||||
amd64_debug_mmgr:
|
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 DEBUG=true MMGR=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_debug:
|
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c
|
||||||
rm -f zlib/libz.a
|
$(DO_CC_LINUX)
|
||||||
$(MAKE) all AMD64=true DEBUG=true
|
|
||||||
|
|
||||||
mmgr:
|
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp
|
||||||
$(MAKE) all MMGR=true
|
$(DO_CC_LINUX)
|
||||||
|
|
||||||
debug_mmgr:
|
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c
|
||||||
$(MAKE) all MMGR=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
|
|
||||||
|
|
||||||
default: all
|
$(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)
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf Release/*.o
|
|
||||||
rm -rf Release/$(BINARY)
|
|
||||||
rm -rf Debug/*.o
|
|
||||||
rm -rf Debug/$(BINARY)
|
|
||||||
|
|
||||||
|
223
amxmodx/Makefile.pl
Executable file
223
amxmodx/Makefile.pl
Executable file
@ -0,0 +1,223 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
$PROJECT = "amxx_mm";
|
||||||
|
$sdk = "../hlsdk/SourceCode";
|
||||||
|
$mm = "../metamod/metamod";
|
||||||
|
|
||||||
|
@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", "MMGR/MMGR.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\"";
|
||||||
|
|
||||||
|
$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 =~ /jit/)
|
||||||
|
{
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
die "You cannot compile the JIT and AMD64 yet.\n";
|
||||||
|
} else {
|
||||||
|
$OPTIONS{"jit"} = 1;
|
||||||
|
}
|
||||||
|
} elsif ($cmd =~ /amd64/) {
|
||||||
|
if ($OPTIONS{"jit"})
|
||||||
|
{
|
||||||
|
die "You cannot compile the JIT 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$gcc = `gcc --version`;
|
||||||
|
if ($gcc =~ /2\.9/)
|
||||||
|
{
|
||||||
|
`ln -s amx.cpp amx.c`;
|
||||||
|
push(@C_SOURCE_FILES, "amx.c");
|
||||||
|
$OPT{"opt"} .= " -malign-loops=2 -malign-jumps=2 -malign-functions=2";
|
||||||
|
} else {
|
||||||
|
if ($OPTIONS{"amd64"})
|
||||||
|
{
|
||||||
|
`cp 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{"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/MMGR/*.o`;
|
||||||
|
`rm $outdir/minilzo/*.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"})
|
||||||
|
{
|
||||||
|
push(@LINK, "JIT/jits.o");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(-d $outdir))
|
||||||
|
{
|
||||||
|
mkdir($outdir);
|
||||||
|
}
|
||||||
|
if (!(-d "$outdir/MMGR"))
|
||||||
|
{
|
||||||
|
mkdir("$outdir/MMGR");
|
||||||
|
}
|
||||||
|
if (!(-d "$outdir/JIT"))
|
||||||
|
{
|
||||||
|
mkdir("$outdir/JIT");
|
||||||
|
}
|
||||||
|
if (!(-d "$outdir/minilzo"))
|
||||||
|
{
|
||||||
|
mkdir("$outdir/minilzo");
|
||||||
|
}
|
||||||
|
|
||||||
|
$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 = "gcc $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||||
|
if (-e $ofile)
|
||||||
|
{
|
||||||
|
$file_time = (stat($file))[9];
|
||||||
|
$ofile_time = (stat($file))[9];
|
||||||
|
if ($file_time > $ofile_time)
|
||||||
|
{
|
||||||
|
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 = "cc $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
|
||||||
|
if (-e $ofile)
|
||||||
|
{
|
||||||
|
$file_time = (stat($file))[9];
|
||||||
|
$ofile_time = (stat($file))[9];
|
||||||
|
if ($file_time > $ofile_time)
|
||||||
|
{
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$gcc = "gcc $cflags -Lzlib/ -shared -ldl -lm @LINK -lz -o $outdir/$bin";
|
||||||
|
print "$gcc\n";
|
||||||
|
`$gcc`;
|
1441
amxmodx/amx.cpp
1441
amxmodx/amx.cpp
File diff suppressed because it is too large
Load Diff
218
amxmodx/amx.h
218
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,34 +21,22 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined FREEBSD && !defined __FreeBSD__
|
#if defined __linux__
|
||||||
#define __FreeBSD__
|
#include "sclinux.h"
|
||||||
#endif
|
|
||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
|
||||||
#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
|
//#define JIT
|
||||||
|
|
||||||
|
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else
|
|
||||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
|
||||||
#if defined HAVE_INTTYPES_H
|
|
||||||
#include <inttypes.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||||
* here, these types are probably undefined.
|
* here, these types are probably undefined.
|
||||||
*/
|
*/
|
||||||
#if defined __MACH__
|
#if defined __FreeBSD__
|
||||||
#include <ppc/types.h>
|
|
||||||
typedef unsigned short int uint16_t;
|
|
||||||
typedef unsigned long int uint32_t;
|
|
||||||
#elif defined __FreeBSD__
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#else
|
#else
|
||||||
typedef short int int16_t;
|
typedef short int int16_t;
|
||||||
@ -71,40 +59,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
|
||||||
#if !defined __64BIT__
|
|
||||||
#define __64BIT__
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_ALLOCA_H
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||||
#if !defined alloca
|
#if !defined alloca
|
||||||
#define alloca(n) _alloca(n)
|
#define alloca(n) _alloca(n)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined arraysize
|
|
||||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
|
||||||
#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
|
||||||
@ -115,8 +80,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
|
||||||
@ -134,39 +97,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
|
||||||
@ -180,7 +149,7 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
|||||||
/* 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
|
||||||
|
|
||||||
@ -191,10 +160,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) */
|
||||||
@ -204,10 +171,10 @@ 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 */
|
||||||
@ -215,19 +182,14 @@ typedef struct tagAMX_NATIVE_INFO {
|
|||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
typedef struct tagAMX_FUNCSTUB {
|
||||||
ucell address PACKED;
|
ucell address PACKED;
|
||||||
char name[sEXPMAX+1] PACKED;
|
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 */
|
||||||
@ -239,26 +201,30 @@ 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 */
|
||||||
long 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 */
|
||||||
|
#if defined JIT
|
||||||
/* 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;
|
#endif
|
||||||
|
} 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.
|
||||||
@ -280,10 +246,8 @@ 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;
|
||||||
|
|
||||||
//This is always the same for us
|
|
||||||
#define AMX_MAGIC 0xf1e0
|
#define AMX_MAGIC 0xf1e0
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -301,8 +265,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 */
|
||||||
@ -315,18 +277,27 @@ 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_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,24 +305,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
|
|
||||||
|
|
||||||
/* 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
|
||||||
@ -365,7 +328,7 @@ enum {
|
|||||||
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)
|
||||||
|
|
||||||
@ -374,12 +337,20 @@ 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);
|
||||||
@ -389,7 +360,7 @@ 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);
|
||||||
@ -401,45 +372,22 @@ 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_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);
|
|
||||||
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
|
||||||
|
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 PACKED; /* file format version */
|
|
||||||
char amx_version PACKED; /* 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 */
|
|
||||||
} AMX_DBG_HDR PACKED;
|
|
||||||
#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] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_FILE PACKED;
|
|
||||||
|
|
||||||
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 */
|
|
||||||
} AMX_DBG_LINE PACKED;
|
|
||||||
|
|
||||||
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 PACKED; /* kind of symbol (function/variable) */
|
|
||||||
char vclass PACKED; /* class of symbol (global/local) */
|
|
||||||
int16_t dim PACKED; /* number of dimensions */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_SYMBOL PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMDIM {
|
|
||||||
int16_t tag PACKED; /* tag for the array dimension */
|
|
||||||
ucell size PACKED; /* size of the array dimension */
|
|
||||||
} AMX_DBG_SYMDIM PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_TAG {
|
|
||||||
int16_t tag PACKED; /* tag id */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_TAG PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_MACHINE {
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
ucell address PACKED; /* address of state variable */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_MACHINE PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_STATE {
|
|
||||||
int16_t state PACKED; /* state id */
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_STATE PACKED;
|
|
||||||
|
|
||||||
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;
|
|
||||||
} AMX_DBG PACKED;
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
1645
amxmodx/amxexecn.asm
1645
amxmodx/amxexecn.asm
File diff suppressed because it is too large
Load Diff
1803
amxmodx/amxmodx.cpp
1803
amxmodx/amxmodx.cpp
File diff suppressed because it is too large
Load Diff
@ -32,16 +32,10 @@
|
|||||||
#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>
|
||||||
#include "mm_pextensions.h" // metamod-p extensions
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
#include "mmgr/mmgr.h"
|
#include "mmgr/mmgr.h"
|
||||||
@ -68,17 +62,18 @@
|
|||||||
#include "amxxlog.h"
|
#include "amxxlog.h"
|
||||||
|
|
||||||
#define AMXXLOG_Log g_log.Log
|
#define AMXXLOG_Log g_log.Log
|
||||||
#define AMX_VERSION "1.60"
|
#define AMX_VERSION "0.2"
|
||||||
|
|
||||||
extern AMX_NATIVE_INFO core_Natives[];
|
extern AMX_NATIVE_INFO core_Natives[];
|
||||||
extern AMX_NATIVE_INFO time_Natives[];
|
extern AMX_NATIVE_INFO time_Natives[];
|
||||||
extern AMX_NATIVE_INFO power_Natives[];
|
extern AMX_NATIVE_INFO power_Natives[];
|
||||||
extern AMX_NATIVE_INFO amxmodx_Natives[];
|
extern AMX_NATIVE_INFO amxmod_Natives[];
|
||||||
extern AMX_NATIVE_INFO file_Natives[];
|
extern AMX_NATIVE_INFO file_Natives[];
|
||||||
extern AMX_NATIVE_INFO float_Natives[];
|
extern AMX_NATIVE_INFO float_Natives[];
|
||||||
extern AMX_NATIVE_INFO string_Natives[];
|
extern AMX_NATIVE_INFO string_Natives[];
|
||||||
extern AMX_NATIVE_INFO vault_Natives[];
|
extern AMX_NATIVE_INFO vault_Natives[];
|
||||||
|
|
||||||
|
|
||||||
#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)
|
||||||
@ -108,7 +103,6 @@ extern AMX_NATIVE_INFO vault_Natives[];
|
|||||||
|
|
||||||
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);
|
||||||
@ -117,30 +111,25 @@ 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 bool g_IsNewMM;
|
|
||||||
extern pextension_funcs_t *gpMetaPExtFuncs;
|
|
||||||
extern CLog g_log;
|
extern CLog g_log;
|
||||||
extern CPluginMngr g_plugins;
|
extern CPluginMngr g_plugins;
|
||||||
extern CTaskMngr g_tasksMngr;
|
extern CTaskMngr g_tasksMngr;
|
||||||
@ -151,8 +140,7 @@ extern CList<CCVar> g_cvars;
|
|||||||
extern CList<ForceObject> g_forcemodels;
|
extern CList<ForceObject> g_forcemodels;
|
||||||
extern CList<ForceObject> g_forcesounds;
|
extern CList<ForceObject> g_forcesounds;
|
||||||
extern CList<ForceObject> g_forcegeneric;
|
extern CList<ForceObject> g_forcegeneric;
|
||||||
extern CList<CModule, const char *> g_modules;
|
extern CList<CModule> 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;
|
||||||
@ -169,6 +157,7 @@ extern XVars g_xvars;
|
|||||||
extern bool g_bmod_cstrike;
|
extern bool g_bmod_cstrike;
|
||||||
extern bool g_bmod_dod;
|
extern bool g_bmod_dod;
|
||||||
extern bool g_dontprecache;
|
extern bool g_dontprecache;
|
||||||
|
extern bool g_initialized;
|
||||||
extern int g_srvindex;
|
extern int g_srvindex;
|
||||||
extern cvar_t* amxmodx_version;
|
extern cvar_t* amxmodx_version;
|
||||||
extern cvar_t* hostname;
|
extern cvar_t* hostname;
|
||||||
@ -178,7 +167,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;
|
||||||
@ -230,13 +218,11 @@ 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();
|
||||||
|
|
||||||
#ifdef FAKEMETA
|
|
||||||
void attachModules();
|
void attachModules();
|
||||||
#endif
|
void attachMetaModModules(PLUG_LOADTIME now, const char* filename);
|
||||||
|
|
||||||
// Count modules
|
// Count modules
|
||||||
enum CountModulesMode
|
enum CountModulesMode
|
||||||
@ -249,20 +235,18 @@ enum CountModulesMode
|
|||||||
int countModules(CountModulesMode mode);
|
int countModules(CountModulesMode mode);
|
||||||
void modules_callPluginsLoaded();
|
void modules_callPluginsLoaded();
|
||||||
|
|
||||||
|
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
||||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||||
char* build_pathname(char *fmt, ... );
|
char* build_pathname(char *fmt, ... );
|
||||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
|
||||||
char* 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);
|
||||||
|
|
||||||
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 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, ... );
|
||||||
@ -271,8 +255,6 @@ 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);
|
|
||||||
void LogError(AMX *amx, int err, const char *fmt, ...);
|
|
||||||
|
|
||||||
enum ModuleCallReason
|
enum ModuleCallReason
|
||||||
{
|
{
|
||||||
@ -286,9 +268,6 @@ extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
|||||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||||
|
|
||||||
void Module_CacheFunctions();
|
|
||||||
void Module_UncacheFunctions();
|
|
||||||
|
|
||||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||||
|
|
||||||
// standard forwards
|
// standard forwards
|
||||||
@ -305,16 +284,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 bool g_coloredmenus;
|
|
||||||
|
|
||||||
#ifdef FAKEMETA
|
|
||||||
extern CFakeMeta g_FakeMeta;
|
extern CFakeMeta g_FakeMeta;
|
||||||
#endif
|
|
||||||
|
|
||||||
struct func_s
|
|
||||||
{
|
|
||||||
void *pfn;
|
|
||||||
const char *desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
#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"
|
||||||
|
@ -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,7 +36,6 @@
|
|||||||
/**********************
|
/**********************
|
||||||
****** AMXXFILE ******
|
****** AMXXFILE ******
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKED __attribute__((packed))
|
||||||
#else
|
#else
|
||||||
@ -51,6 +51,10 @@
|
|||||||
#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 PACKED;
|
mint8_t cellSize 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)
|
|
||||||
{
|
{
|
||||||
//we have an invalid, old, RLEB file
|
// check for old file
|
||||||
m_Status = Err_OldFile;
|
AMX_HEADER hdr;
|
||||||
fclose(m_pFile);
|
rewind(m_pFile);
|
||||||
m_pFile = NULL;
|
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||||
|
amx_Align16(&hdr.magic);
|
||||||
return;
|
if (hdr.magic == AMX_MAGIC)
|
||||||
}
|
|
||||||
else if (magic == MAGIC_HEADER2)
|
|
||||||
{
|
{
|
||||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
if (cellsize != 4)
|
||||||
|
|
||||||
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;
|
m_Status = Err_SectionNotFound;
|
||||||
fclose(m_pFile);
|
fclose(m_pFile);
|
||||||
m_pFile = NULL;
|
m_pFile = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pe = &(m_Bh.plugins[m_Entry]);
|
m_OldFile = true;
|
||||||
m_SectionLength = pe->disksize;
|
return;
|
||||||
}
|
}
|
||||||
else if (magic == MAGIC_HEADER)
|
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
|
||||||
|
m_Status = Err_OldFile;
|
||||||
|
fclose(m_pFile);
|
||||||
|
m_pFile = NULL;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
|
||||||
// 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;
|
||||||
@ -194,39 +164,12 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
|||||||
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,25 +214,14 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,51 +251,30 @@ 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)
|
|
||||||
{
|
|
||||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
|
||||||
char *tempBuffer = new char[m_SectionLength + 1];
|
|
||||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
|
||||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
|
||||||
uLongf destLen = GetBufferSize();
|
|
||||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
|
||||||
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
|
// new file type: go to the section table entry
|
||||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||||
// go to the offset
|
// go to the offset
|
||||||
TableEntry entry;
|
TableEntry entry;
|
||||||
DATAREAD(&entry, sizeof(entry), 1);
|
DATAREAD(&entry, sizeof(entry), 1);
|
||||||
fseek(m_pFile, entry.offset, SEEK_SET);
|
fseek(m_pFile, entry.offset, SEEK_SET);
|
||||||
|
// AMXXLOG_Log("|||| Offset needed: %d At: %d", entry.offset, ftell(m_pFile));
|
||||||
uLongf destLen = GetBufferSize();
|
uLongf destLen = GetBufferSize();
|
||||||
// read the data to a temporary buffer
|
// read the data to a temporary buffer
|
||||||
char *tempBuffer = new char[m_SectionLength + 1];
|
char *tempBuffer = new char[m_SectionLength + 1];
|
||||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||||
// decompress
|
// decompress
|
||||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
// AMXXLOG_Log("|||| First Bytes: %d %d %d %d", tempBuffer[0], tempBuffer[1], tempBuffer[2], tempBuffer[3]);
|
||||||
delete [] tempBuffer;
|
int result = uncompress((Bytef *)buffer, &destLen,
|
||||||
|
(Bytef *)tempBuffer, m_SectionLength);
|
||||||
|
// AMXXLOG_Log("|||| Result: %d, m_SectionLength=%d, destLen=%d", result, m_SectionLength, destLen);
|
||||||
if (result != Z_OK)
|
if (result != Z_OK)
|
||||||
{
|
{
|
||||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
|
||||||
m_Status = Err_Decompress;
|
m_Status = Err_Decompress;
|
||||||
|
|
||||||
return Err_Decompress;
|
return Err_Decompress;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err_None;
|
return Err_None;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
@ -94,4 +66,6 @@ public:
|
|||||||
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // __AMXXFILE_H__
|
#endif // __AMXXFILE_H__
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
#ifndef __linux__
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CLog::CLog()
|
CLog::CLog()
|
||||||
{
|
{
|
||||||
m_LogType = 0;
|
m_LogType = 0;
|
||||||
@ -61,11 +57,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;
|
||||||
@ -78,7 +73,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,56 +80,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);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
m_LogFile.assign(build_pathname("%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i));
|
||||||
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||||
|
|
||||||
if (!pTmpFile)
|
if (!pTmpFile)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fclose(pTmpFile);
|
fclose(pTmpFile);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
|
fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
||||||
@ -150,7 +135,7 @@ void CLog::MapChange()
|
|||||||
}
|
}
|
||||||
else if (m_LogType == 1)
|
else if (m_LogType == 1)
|
||||||
{
|
{
|
||||||
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
|
Log("-------- Mapchange --------");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
@ -158,8 +143,6 @@ void CLog::MapChange()
|
|||||||
|
|
||||||
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
|
||||||
@ -171,14 +154,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);
|
vsprintf(msg, 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+");
|
||||||
@ -186,7 +169,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());
|
||||||
@ -194,32 +176,26 @@ void CLog::Log(const char *fmt, ...)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
|
|
||||||
pF = fopen(file, "a+");
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (pF)
|
|
||||||
{
|
{
|
||||||
fprintf(pF, "L %s: %s\n", date, msg);
|
pF = fopen(build_pathname("%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday), "a+");
|
||||||
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);
|
|
||||||
m_LogType = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
fprintf(pF, "L %s: %s\n", date, msg);
|
||||||
|
|
||||||
|
fclose(pF);
|
||||||
// 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);
|
vsprintf(msg, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
ALERT(at_logged, "%s\n", msg_);
|
ALERT(at_logged, "%s\n", msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,6 @@ private:
|
|||||||
public:
|
public:
|
||||||
CLog();
|
CLog();
|
||||||
~CLog();
|
~CLog();
|
||||||
|
|
||||||
void CreateNewFile();
|
void CreateNewFile();
|
||||||
void CloseFile();
|
void CloseFile();
|
||||||
void MapChange();
|
void MapChange();
|
||||||
@ -50,3 +49,4 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // __AMXXLOG_H__
|
#endif // __AMXXLOG_H__
|
||||||
|
|
||||||
|
1230
amxmodx/debugger.cpp
1230
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), used(false), next(NULL), prev(NULL) {};
|
|
||||||
|
|
||||||
cell cip;
|
|
||||||
cell frm;
|
|
||||||
|
|
||||||
trace_info *next;
|
|
||||||
trace_info *prev;
|
|
||||||
|
|
||||||
bool used;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
Tracer() : m_Error(0), m_pStart(NULL), m_pEnd(NULL), m_Reset(true) {};
|
|
||||||
~Tracer();
|
|
||||||
public:
|
|
||||||
void StepI(cell frm, cell cip);
|
|
||||||
void Reset();
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
Debugger::Tracer::trace_info *GetStart() const;
|
|
||||||
Debugger::Tracer::trace_info *GetEnd() const;
|
|
||||||
public:
|
|
||||||
int m_Error;
|
|
||||||
private:
|
|
||||||
trace_info *m_pStart;
|
|
||||||
trace_info *m_pEnd;
|
|
||||||
|
|
||||||
bool m_Reset;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
Debugger(AMX *pAmx, AMX_DBG *pAmxDbg) : m_pAmx(pAmx), m_pAmxDbg(pAmxDbg), m_Top(-1)
|
|
||||||
{
|
|
||||||
_CacheAmxOpcodeList();
|
|
||||||
};
|
|
||||||
~Debugger();
|
|
||||||
public:
|
|
||||||
//Begin a trace for a function
|
|
||||||
void BeginExec();
|
|
||||||
|
|
||||||
//Step through one instruction
|
|
||||||
void StepI();
|
|
||||||
|
|
||||||
//Get/set the last traced error
|
|
||||||
int GetTracedError();
|
|
||||||
void SetTracedError(int error);
|
|
||||||
|
|
||||||
//Get the first trace info of the call stack
|
|
||||||
Debugger::Tracer::trace_info *GetTraceStart() const;
|
|
||||||
|
|
||||||
//Get extra info about the call stack
|
|
||||||
bool GetTraceInfo(Debugger::Tracer::trace_info *pTraceInfo, long &line, const char *&function, const char *&file);
|
|
||||||
|
|
||||||
//Get the next trace in the call stack, NULL if none
|
|
||||||
Debugger::Tracer::trace_info *GetNextTrace(Debugger::Tracer::trace_info *pTraceInfo);
|
|
||||||
|
|
||||||
//Returns true if an error exists
|
|
||||||
bool ErrorExists();
|
|
||||||
|
|
||||||
//Formats the error message into a buffer.
|
|
||||||
//returns length of data copied, or -1 if there is no error.
|
|
||||||
int FormatError(char *buffer, size_t maxLength);
|
|
||||||
|
|
||||||
//End a trace
|
|
||||||
void EndExec();
|
|
||||||
|
|
||||||
//Reset the internal states as if the debugger was inactive
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
//Destroy internal states for shutdown
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
void DisplayTrace(const char *message);
|
|
||||||
|
|
||||||
AMX *GetAMX() const { return m_pAmx; }
|
|
||||||
public:
|
|
||||||
//generic static opcode breaker
|
|
||||||
static int AMXAPI DebugHook(AMX *amx);
|
|
||||||
|
|
||||||
static void FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength);
|
|
||||||
static void GenericMessage(AMX *amx, int error);
|
|
||||||
private:
|
|
||||||
void _CacheAmxOpcodeList();
|
|
||||||
|
|
||||||
int _GetOpcodeFromCip(cell cip, cell *&addr);
|
|
||||||
cell _CipAsVa(cell cip);
|
|
||||||
|
|
||||||
const char *_GetFilename();
|
|
||||||
public:
|
|
||||||
AMX *m_pAmx;
|
|
||||||
AMX_DBG *m_pAmxDbg;
|
|
||||||
|
|
||||||
int m_Top;
|
|
||||||
cell *m_pOpcodeList;
|
|
||||||
String m_FileName;
|
|
||||||
|
|
||||||
CVector<Tracer *> m_pCalls;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Debugger::Tracer::trace_info trace_info_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error handler for plugins
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Handler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Handler(AMX *pAmx) : m_pAmx(pAmx), m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1), m_Handling(false), m_InNativeFilter(false) {};
|
|
||||||
~Handler() {};
|
|
||||||
public:
|
|
||||||
int SetErrorHandler(const char *function);
|
|
||||||
int SetNativeFilter(const char *function);
|
|
||||||
int SetModuleFilter(const char *function);
|
|
||||||
public:
|
|
||||||
int HandleError(const char *msg);
|
|
||||||
int HandleNative(const char *native, int index, int trap);
|
|
||||||
int HandleModule(const char *module);
|
|
||||||
public:
|
|
||||||
bool IsHandling() const { return m_Handling; }
|
|
||||||
void SetErrorMsg(const char *msg);
|
|
||||||
|
|
||||||
const char *GetLastMsg();
|
|
||||||
trace_info_t *GetTrace() const { return m_pTrace; }
|
|
||||||
const char *GetFmtCache() { return m_FmtCache.c_str(); }
|
|
||||||
|
|
||||||
bool IsNativeFiltering() { return (m_iNatFunc > 0); }
|
|
||||||
bool InNativeFilter() { return m_InNativeFilter; }
|
|
||||||
private:
|
|
||||||
AMX *m_pAmx;
|
|
||||||
|
|
||||||
int m_iErrFunc;
|
|
||||||
int m_iModFunc;
|
|
||||||
int m_iNatFunc;
|
|
||||||
|
|
||||||
bool m_Handling;
|
|
||||||
|
|
||||||
//in the future, make this a stack!
|
|
||||||
bool m_InNativeFilter;
|
|
||||||
|
|
||||||
String m_MsgCache;
|
|
||||||
String m_FmtCache;
|
|
||||||
|
|
||||||
trace_info_t *m_pTrace;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern AMX_NATIVE_INFO g_DebugNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_DEBUGGER_H_
|
|
@ -58,9 +58,7 @@ WeaponsVault g_weaponsData[MAX_WEAPONS];
|
|||||||
void Client_VGUIMenu(void* mValue)
|
void Client_VGUIMenu(void* mValue)
|
||||||
{
|
{
|
||||||
if (!mPlayer) return;
|
if (!mPlayer) return;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
mPlayer->menu = -(*(int*)mValue);
|
mPlayer->menu = -(*(int*)mValue);
|
||||||
break;
|
break;
|
||||||
@ -72,9 +70,7 @@ void Client_VGUIMenu(void* mValue)
|
|||||||
void Client_ShowMenu(void* mValue)
|
void Client_ShowMenu(void* mValue)
|
||||||
{
|
{
|
||||||
if (!mPlayer) return;
|
if (!mPlayer) return;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
mPlayer->keys = *(int*)mValue;
|
mPlayer->keys = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -87,9 +83,7 @@ void Client_TeamInfo(void* mValue)
|
|||||||
{
|
{
|
||||||
if (mPlayer) return;
|
if (mPlayer) return;
|
||||||
static int index;
|
static int index;
|
||||||
|
switch (mState++) {
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
index = *(int*)mValue;
|
index = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -104,57 +98,44 @@ void Client_TeamInfo(void* mValue)
|
|||||||
void Client_TextMsg(void* mValue)
|
void Client_TextMsg(void* mValue)
|
||||||
{
|
{
|
||||||
if ( mPlayer ) return;
|
if ( mPlayer ) return;
|
||||||
|
switch (mState++) {
|
||||||
switch (mState++)
|
case 1:{
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
char * msg = (char*)mValue;
|
char * msg = (char*)mValue;
|
||||||
if (!msg) break;
|
if (!msg) break;
|
||||||
|
if ( !strncmp("#Game_C", msg , 7) ) {
|
||||||
if (!strncmp("#Game_C", msg, 7))
|
|
||||||
{
|
|
||||||
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
|
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
|
||||||
// g_endround_time = gpGlobals->time;
|
// g_endround_time = gpGlobals->time;
|
||||||
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
|
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
|
||||||
}
|
}
|
||||||
else if (!strncmp("#Game_w", msg, 7))
|
else if (!strncmp("#Game_w", msg , 7) ) {
|
||||||
{
|
|
||||||
g_game_timeleft = -2;
|
g_game_timeleft = -2;
|
||||||
}
|
}
|
||||||
else if (!strncmp("#game_clan_s", msg, 12))
|
else if ( !strncmp("#game_clan_s", msg , 12) ){
|
||||||
{
|
|
||||||
g_game_timeleft = -3;
|
g_game_timeleft = -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:{
|
||||||
{
|
|
||||||
char * msg = (char*)mValue;
|
char * msg = (char*)mValue;
|
||||||
if (!msg) break;
|
if (!msg) break;
|
||||||
|
if (g_game_timeleft == -2 ){
|
||||||
if (g_game_timeleft == -2)
|
|
||||||
{
|
|
||||||
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
|
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
|
||||||
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
|
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
|
||||||
}
|
}
|
||||||
else if ( g_game_timeleft == -3 )
|
else if ( g_game_timeleft == -3 )
|
||||||
g_game_restarting = atoi(msg) * 60.0f;
|
g_game_restarting = atoi( msg ) * 60;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:{
|
||||||
{
|
|
||||||
char * msg = (char*)mValue;
|
char * msg = (char*)mValue;
|
||||||
if (!msg) break;
|
if (!msg) break;
|
||||||
if ( g_game_timeleft != -3 ) break;
|
if ( g_game_timeleft != -3 ) break;
|
||||||
g_game_restarting += atoi( msg );
|
g_game_restarting += atoi( msg );
|
||||||
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
|
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client_WeaponList(void* mValue)
|
void Client_WeaponList(void* mValue)
|
||||||
@ -163,9 +144,7 @@ void Client_WeaponList(void* mValue)
|
|||||||
//static int wpnList2;
|
//static int wpnList2;
|
||||||
static int iSlot;
|
static int iSlot;
|
||||||
static const char* wpnName;
|
static const char* wpnName;
|
||||||
|
switch (mState++) {
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
wpnName = (char*)mValue;
|
wpnName = (char*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -174,12 +153,24 @@ void Client_WeaponList(void* mValue)
|
|||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
int iId = *(int*)mValue;
|
int iId = *(int*)mValue;
|
||||||
|
/*int* blocker;
|
||||||
|
|
||||||
|
int iwpn = iId;
|
||||||
|
|
||||||
|
if (iId > 31) {
|
||||||
|
iwpn -= 31;
|
||||||
|
blocker = &wpnList2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
blocker = &wpnList;*/
|
||||||
|
|
||||||
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
|
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
|
||||||
break;
|
break;
|
||||||
wpnList |= (1<<iId);
|
wpnList |= (1<<iId);
|
||||||
g_weaponsData[iId].iId = iId;
|
g_weaponsData[iId].iId = iId;
|
||||||
g_weaponsData[iId].ammoSlot = iSlot;
|
g_weaponsData[iId].ammoSlot = iSlot;
|
||||||
g_weaponsData[iId].fullName.assign(wpnName);
|
g_weaponsData[iId].fullName.assign(wpnName);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,9 +178,7 @@ void Client_CurWeapon(void* mValue)
|
|||||||
{
|
{
|
||||||
static int iState;
|
static int iState;
|
||||||
static int iId;
|
static int iId;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
iState = *(int*)mValue;
|
iState = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -208,10 +197,9 @@ void Client_CurWeapon(void* 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;
|
||||||
@ -226,9 +214,7 @@ void Client_AmmoX(void* mValue)
|
|||||||
void Client_AmmoPickup(void* mValue)
|
void Client_AmmoPickup(void* mValue)
|
||||||
{
|
{
|
||||||
static int iSlot;
|
static int iSlot;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
iSlot = *(int*)mValue;
|
iSlot = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -244,9 +230,7 @@ void Client_ScoreInfo(void* mValue)
|
|||||||
{
|
{
|
||||||
static int index;
|
static int index;
|
||||||
static int deaths;
|
static int deaths;
|
||||||
|
switch (mState++){
|
||||||
switch (mState++)
|
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
index = *(int*)mValue;
|
index = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
@ -288,21 +272,24 @@ 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) ? GET_PLAYER_POINTER_I(killer_id) : 0;
|
killer = (killer_id > 0 && killer_id < 33) ?
|
||||||
|
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) ?
|
||||||
|
GET_PLAYER_POINTER_I(victim_id) : 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
hs = *(int*)mValue;
|
hs = *(int*)mValue;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
|
||||||
if ( !killer || !victim ) break;
|
if ( !killer || !victim ) break;
|
||||||
|
|
||||||
victim->death_killer = killer_id;
|
victim->death_killer = killer_id;
|
||||||
victim->death_weapon.assign((char*)mValue);
|
victim->death_weapon.assign((char*)mValue);
|
||||||
victim->death_headshot = hs;
|
victim->death_headshot = hs;
|
||||||
|
@ -28,53 +28,10 @@
|
|||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Fake metamod api
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
#include "fakemeta.h"
|
#include "fakemeta.h"
|
||||||
|
|
||||||
#ifndef FAKEMETA
|
|
||||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now)
|
|
||||||
{
|
|
||||||
if (gpMetaPExtFuncs)
|
|
||||||
{
|
|
||||||
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, path, now, handle) || !*handle)
|
|
||||||
{
|
|
||||||
LOG_MESSAGE(PLID, "Can't Attach metamod-module \"%s\".", path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else if (g_IsNewMM) {
|
|
||||||
int err = 0;
|
|
||||||
if ( (err = LOAD_PLUGIN(PLID, path, now, handle)) || !*handle)
|
|
||||||
{
|
|
||||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int UnloadMetamodPlugin(void *handle)
|
|
||||||
{
|
|
||||||
if (gpMetaPExtFuncs)
|
|
||||||
{
|
|
||||||
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)handle, PT_ANYTIME, PNL_PLUGIN)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else if (g_IsNewMM) {
|
|
||||||
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)handle, PT_ANYTIME, PNL_PLUGIN))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Fake metamod api
|
|
||||||
|
|
||||||
// for varargs
|
// for varargs
|
||||||
#define MAX_STRBUF_LEN 512
|
#define MAX_STRBUF_LEN 512
|
||||||
|
|
||||||
@ -363,7 +320,7 @@ int UnloadMetamodPlugin(void *handle)
|
|||||||
prev_mres = mres; \
|
prev_mres = mres; \
|
||||||
if (mres == MRES_UNSET) \
|
if (mres == MRES_UNSET) \
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
||||||
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnName); \
|
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnArgs); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Set meta result to the highest value */ \
|
/* Set meta result to the highest value */ \
|
||||||
@ -396,7 +353,7 @@ int UnloadMetamodPlugin(void *handle)
|
|||||||
prev_mres = mres; \
|
prev_mres = mres; \
|
||||||
if (mres == MRES_UNSET) \
|
if (mres == MRES_UNSET) \
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
||||||
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnName); \
|
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnArgs); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Set meta result to the highest value */ \
|
/* Set meta result to the highest value */ \
|
||||||
@ -422,7 +379,7 @@ int UnloadMetamodPlugin(void *handle)
|
|||||||
prev_mres = mres; \
|
prev_mres = mres; \
|
||||||
if (mres == MRES_UNSET) \
|
if (mres == MRES_UNSET) \
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
||||||
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnName); \
|
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnArgs); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Set meta result to the highest value */ \
|
/* Set meta result to the highest value */ \
|
||||||
@ -455,10 +412,7 @@ int UnloadMetamodPlugin(void *handle)
|
|||||||
prev_mres = mres; \
|
prev_mres = mres; \
|
||||||
if (mres == MRES_UNSET) \
|
if (mres == MRES_UNSET) \
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has not set meta result in \"%s\"", \
|
||||||
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnName); \
|
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnArgs); \
|
||||||
if (mres == MRES_SUPERCEDE) \
|
|
||||||
AMXXLOG_Log("[AMXX] Module \"%s\" (\"%s\") has set meta result in \"%s\" to supercede", \
|
|
||||||
(*iter).GetInfo()->name, (*iter).GetPath(), #pfnName); \
|
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
/* Set meta result to the highest value */ \
|
/* Set meta result to the highest value */ \
|
||||||
@ -2387,24 +2341,8 @@ CFakeMeta::CFakeMetaPlugin::~CFakeMetaPlugin()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ghost_of_evilspy's "could not find memloc for cvar" fix
|
|
||||||
void FakeMeta_New_CVarRegister(cvar_t *pCVar)
|
|
||||||
{
|
|
||||||
static cvar_t tmpvar;
|
|
||||||
tmpvar = *pCVar;
|
|
||||||
CVAR_REGISTER(&tmpvar);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
||||||
{
|
{
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
//load plugins in meta_attach
|
|
||||||
m_Status = PL_OPENED;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the library
|
// Load the library
|
||||||
// We don't have to DLCLOSE here.
|
// We don't have to DLCLOSE here.
|
||||||
m_Handle = DLOPEN(build_pathname("%s", m_Path.c_str()));
|
m_Handle = DLOPEN(build_pathname("%s", m_Path.c_str()));
|
||||||
@ -2449,13 +2387,7 @@ int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
|||||||
m_Status = PL_BADFILE;
|
m_Status = PL_BADFILE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
giveEngFuncsFn(&g_engfuncs, gpGlobals);
|
||||||
// ghost_of_evilspy's "Could not find memloc for cvar" fix
|
|
||||||
static enginefuncs_t fakemeta_engfuncs;
|
|
||||||
memcpy(&fakemeta_engfuncs, &g_engfuncs, sizeof(enginefuncs_t));
|
|
||||||
// Override cvar register to our own function
|
|
||||||
fakemeta_engfuncs.pfnCVarRegister = FakeMeta_New_CVarRegister;
|
|
||||||
giveEngFuncsFn(&fakemeta_engfuncs, gpGlobals);
|
|
||||||
|
|
||||||
if (queryFn(META_INTERFACE_VERSION, &m_Info, pMetaUtilFuncs) != 1)
|
if (queryFn(META_INTERFACE_VERSION, &m_Info, pMetaUtilFuncs) != 1)
|
||||||
{
|
{
|
||||||
@ -2470,35 +2402,8 @@ int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
|
|||||||
|
|
||||||
int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs)
|
int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs)
|
||||||
{
|
{
|
||||||
// evilspy's patch:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if (gpMetaPExtFuncs)
|
|
||||||
{
|
|
||||||
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, m_Path.c_str(), now, (void**)&m_Handle) || !m_Handle)
|
|
||||||
{
|
|
||||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
|
||||||
m_Status = PL_FAILED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Status = PL_RUNNING;
|
|
||||||
return 1;
|
|
||||||
} else if (g_IsNewMM) {
|
|
||||||
int err = 0;
|
|
||||||
if ( (err = LOAD_PLUGIN(PLID, m_Path.c_str(), now, (void **)&m_Handle)) || !m_Handle)
|
|
||||||
{
|
|
||||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
|
||||||
m_Status = PL_FAILED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Status = PL_RUNNING;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_Handle)
|
if (!m_Handle)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach");
|
META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach");
|
||||||
if (!attachFn)
|
if (!attachFn)
|
||||||
{
|
{
|
||||||
@ -2508,7 +2413,7 @@ int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlob
|
|||||||
}
|
}
|
||||||
if (attachFn(now, &m_MetaFuncTable, pMGlobals, pGameDllFuncs) != 1)
|
if (attachFn(now, &m_MetaFuncTable, pMGlobals, pGameDllFuncs) != 1)
|
||||||
{
|
{
|
||||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
|
AMXXLOG_Log("[AMXX] Can't Attach Module \"%s\" (\"%s\").", m_Info->name, m_Path.c_str());
|
||||||
m_Status = PL_FAILED;
|
m_Status = PL_FAILED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2521,29 +2426,6 @@ int CFakeMeta::CFakeMetaPlugin::Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reaso
|
|||||||
{
|
{
|
||||||
if (!m_Handle)
|
if (!m_Handle)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// evilspy's patch:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if (gpMetaPExtFuncs)
|
|
||||||
{
|
|
||||||
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)m_Handle, now, reason)) {
|
|
||||||
m_Status = PL_FAILED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
m_Status = PL_OPENED;
|
|
||||||
m_Handle = NULL;
|
|
||||||
return 1;
|
|
||||||
} else if (g_IsNewMM) {
|
|
||||||
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)m_Handle, now, reason))
|
|
||||||
{
|
|
||||||
m_Status = PL_FAILED;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
m_Status = PL_OPENED;
|
|
||||||
m_Handle = NULL;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach");
|
META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach");
|
||||||
if (!detachFn)
|
if (!detachFn)
|
||||||
{
|
{
|
||||||
@ -2634,11 +2516,6 @@ void CFakeMeta::ReleasePlugins()
|
|||||||
|
|
||||||
bool CFakeMeta::AddCorePlugin()
|
bool CFakeMeta::AddCorePlugin()
|
||||||
{
|
{
|
||||||
// evilspy:
|
|
||||||
// not needed when using metamod p-extensions
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Check whether there already is a core plugin
|
// Check whether there already is a core plugin
|
||||||
if (m_Plugins.begin() && strcmp((*m_Plugins.begin()).GetPath(), "[AMXX Core]") == 0)
|
if (m_Plugins.begin() && strcmp((*m_Plugins.begin()).GetPath(), "[AMXX Core]") == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -2660,12 +2537,7 @@ void CFakeMeta::Meta_Query(mutil_funcs_t *pMetaUtilFuncs)
|
|||||||
|
|
||||||
// Query all plugins except core
|
// Query all plugins except core
|
||||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||||
|
|
||||||
// evilspy:
|
|
||||||
// using metamod p-extensions?
|
|
||||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
|
||||||
++iter; // Skip core
|
++iter; // Skip core
|
||||||
|
|
||||||
for (; iter; ++iter)
|
for (; iter; ++iter)
|
||||||
{
|
{
|
||||||
(*iter).Query(pMetaUtilFuncs);
|
(*iter).Query(pMetaUtilFuncs);
|
||||||
@ -2679,11 +2551,7 @@ void CFakeMeta::Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedl
|
|||||||
|
|
||||||
// Attach all plugins except core
|
// Attach all plugins except core
|
||||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||||
// evilspy:
|
|
||||||
// using metamod p-extensions?
|
|
||||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
|
||||||
++iter; // Skip core
|
++iter; // Skip core
|
||||||
|
|
||||||
for (; iter; ++iter)
|
for (; iter; ++iter)
|
||||||
{
|
{
|
||||||
(*iter).Attach(now, pMGlobals, pGamedllFuncs);
|
(*iter).Attach(now, pMGlobals, pGamedllFuncs);
|
||||||
@ -2695,11 +2563,7 @@ void CFakeMeta::Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
|||||||
{
|
{
|
||||||
// Detach all plugins except core
|
// Detach all plugins except core
|
||||||
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
|
||||||
// evilspy:
|
|
||||||
// using metamod p-extensions?
|
|
||||||
if(!gpMetaPExtFuncs && !g_IsNewMM)
|
|
||||||
++iter; // Skip core
|
++iter; // Skip core
|
||||||
|
|
||||||
for (; iter; ++iter)
|
for (; iter; ++iter)
|
||||||
{
|
{
|
||||||
(*iter).Detach(now, reason);
|
(*iter).Detach(now, reason);
|
||||||
@ -2715,15 +2579,6 @@ int CFakeMeta::GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int
|
|||||||
*interfaceVersion = INTERFACE_VERSION;
|
*interfaceVersion = INTERFACE_VERSION;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// evilspy:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pFunctionTable, &g_DllFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
memcpy( pFunctionTable, &g_DllFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
@ -2753,15 +2608,6 @@ int CFakeMeta::GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/
|
|||||||
*interfaceVersion = INTERFACE_VERSION;
|
*interfaceVersion = INTERFACE_VERSION;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// evilspy
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pFunctionTable, &g_DllFunctionTable_Post, sizeof( DLL_FUNCTIONS ) );
|
memcpy( pFunctionTable, &g_DllFunctionTable_Post, sizeof( DLL_FUNCTIONS ) );
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
@ -2791,15 +2637,6 @@ int CFakeMeta::GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inter
|
|||||||
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// evilspy:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable, sizeof( enginefuncs_t ) );
|
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable, sizeof( enginefuncs_t ) );
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
@ -2828,15 +2665,6 @@ int CFakeMeta::GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *
|
|||||||
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
*interfaceVersion = ENGINE_INTERFACE_VERSION;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// evilspy:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable_Post, sizeof( enginefuncs_t ) );
|
memcpy( pengfuncsFromEngine, &g_EngineFunctionTable_Post, sizeof( enginefuncs_t ) );
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
@ -2872,16 +2700,7 @@ int CFakeMeta::GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *int
|
|||||||
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
memcpy( pNewFunctionTable, &g_NewDllFunctionTable, sizeof( DLL_FUNCTIONS ) );
|
||||||
// evilspy:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pNewFunctionTable, &g_NewDllFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
AddCorePlugin();
|
AddCorePlugin();
|
||||||
@ -2916,16 +2735,7 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
|
|||||||
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
*interfaceVersion = NEW_DLL_FUNCTIONS_VERSION;
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
memcpy( pNewFunctionTable, &g_NewDllFunctionTable_Post, sizeof( DLL_FUNCTIONS ) );
|
||||||
// evilspy:
|
|
||||||
//using metamod p-extensions?
|
|
||||||
if(gpMetaPExtFuncs || g_IsNewMM)
|
|
||||||
{
|
|
||||||
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( pNewFunctionTable, &g_NewDllFunctionTable_Post, sizeof( NEW_DLL_FUNCTIONS ) );
|
|
||||||
|
|
||||||
// Make sure there is a core plugin
|
// Make sure there is a core plugin
|
||||||
AddCorePlugin();
|
AddCorePlugin();
|
||||||
@ -2944,5 +2754,3 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FAKEMETA
|
|
||||||
|
@ -31,10 +31,6 @@
|
|||||||
#ifndef __FAKEMETA_H__
|
#ifndef __FAKEMETA_H__
|
||||||
#define __FAKEMETA_H__
|
#define __FAKEMETA_H__
|
||||||
|
|
||||||
#ifndef FAKEMETA
|
|
||||||
int UnloadMetamodPlugin(void *handle);
|
|
||||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
|
||||||
#else
|
|
||||||
// Fake metamod api for modules
|
// Fake metamod api for modules
|
||||||
|
|
||||||
#include "CList.h"
|
#include "CList.h"
|
||||||
@ -42,8 +38,7 @@
|
|||||||
// from mplugin.h (metamod)
|
// from mplugin.h (metamod)
|
||||||
// Flags to indicate current "load" state of plugin.
|
// Flags to indicate current "load" state of plugin.
|
||||||
// NOTE: order is important, as greater/less comparisons are made.
|
// NOTE: order is important, as greater/less comparisons are made.
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
PL_EMPTY = 0, // empty slot
|
PL_EMPTY = 0, // empty slot
|
||||||
PL_VALID, // has valid info in it
|
PL_VALID, // has valid info in it
|
||||||
PL_BADFILE, // nonexistent file (open failed),
|
PL_BADFILE, // nonexistent file (open failed),
|
||||||
@ -56,10 +51,11 @@ typedef enum
|
|||||||
|
|
||||||
// from h_export.h (metamod)
|
// from h_export.h (metamod)
|
||||||
// Our GiveFnptrsToDll, called by engine.
|
// Our GiveFnptrsToDll, called by engine.
|
||||||
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals);
|
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t
|
||||||
|
*pengfuncsFromEngine, globalvars_t *pGlobals);
|
||||||
|
|
||||||
|
|
||||||
// *** CFakeMeta
|
// *** CFakeMeta
|
||||||
|
|
||||||
class CFakeMeta
|
class CFakeMeta
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -100,6 +96,7 @@ public:
|
|||||||
inline void SetStatus(PLUG_STATUS newStatus)
|
inline void SetStatus(PLUG_STATUS newStatus)
|
||||||
{ m_Status = newStatus; }
|
{ m_Status = newStatus; }
|
||||||
|
|
||||||
|
|
||||||
inline plugin_info_t * GetInfo()
|
inline plugin_info_t * GetInfo()
|
||||||
{ return m_Info; }
|
{ return m_Info; }
|
||||||
inline const plugin_info_t * GetInfo() const
|
inline const plugin_info_t * GetInfo() const
|
||||||
@ -228,6 +225,5 @@ public:
|
|||||||
// defined in meta_api.cpp
|
// defined in meta_api.cpp
|
||||||
extern CFakeMeta g_FakeMeta;
|
extern CFakeMeta g_FakeMeta;
|
||||||
|
|
||||||
#endif //FAKEMETA
|
|
||||||
|
|
||||||
#endif // #ifndef __FAKEMETA_H__
|
#endif // #ifndef __FAKEMETA_H__
|
||||||
|
|
||||||
|
469
amxmodx/file.cpp
469
amxmodx/file.cpp
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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<EFBFBD> License as published by the
|
* under the terms of the GNU General Public License as published by the
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
* Free Software Foundation; either version 2 of the License, or (at
|
||||||
* your option) any later version.
|
* your option) any later version.
|
||||||
*
|
*
|
||||||
@ -36,18 +36,18 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
//#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// header file for unlink()
|
// header file for unlink()
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#else
|
#else
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -57,25 +57,6 @@
|
|||||||
|
|
||||||
CVector<FILE *> FileList;
|
CVector<FILE *> FileList;
|
||||||
|
|
||||||
class AutoFilePtr
|
|
||||||
{
|
|
||||||
FILE *m_FP;
|
|
||||||
public:
|
|
||||||
AutoFilePtr(FILE *fp) : m_FP(fp)
|
|
||||||
{}
|
|
||||||
|
|
||||||
~AutoFilePtr()
|
|
||||||
{
|
|
||||||
if (m_FP)
|
|
||||||
fclose(m_FP);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator FILE* ()
|
|
||||||
{
|
|
||||||
return m_FP;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -84,24 +65,18 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
|||||||
DIR *dp;
|
DIR *dp;
|
||||||
char* dirname = build_pathname("%s",get_amxstring(amx,params[1],0,a) );
|
char* dirname = build_pathname("%s",get_amxstring(amx,params[1],0,a) );
|
||||||
a = params[2];
|
a = params[2];
|
||||||
|
|
||||||
if ( (dp = opendir (dirname)) == NULL )
|
if ( (dp = opendir (dirname)) == NULL )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
seekdir( dp , a );
|
seekdir( dp , a );
|
||||||
|
if ( (ep = readdir (dp)) != NULL ) {
|
||||||
if ((ep = readdir (dp)) != NULL)
|
|
||||||
{
|
|
||||||
cell *length = get_amxaddr(amx,params[5]);
|
cell *length = get_amxaddr(amx,params[5]);
|
||||||
*length = set_amxstring(amx,params[3], ep->d_name ,params[4]);
|
*length = set_amxstring(amx,params[3], ep->d_name ,params[4]);
|
||||||
a = telldir( dp );
|
a = telldir( dp );
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
a = 0;
|
a = 0;
|
||||||
|
|
||||||
closedir (dp);
|
closedir (dp);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
int tmp;
|
int tmp;
|
||||||
char *dirname = build_pathname("%s/*", get_amxstring(amx, params[1], 0, tmp));
|
char *dirname = build_pathname("%s/*", get_amxstring(amx, params[1], 0, tmp));
|
||||||
@ -109,12 +84,10 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
|||||||
|
|
||||||
_finddata_t fd;
|
_finddata_t fd;
|
||||||
intptr_t handle = _findfirst(dirname, &fd);
|
intptr_t handle = _findfirst(dirname, &fd);
|
||||||
|
|
||||||
if (handle < 0)
|
if (handle < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
++tmp;
|
++tmp;
|
||||||
|
|
||||||
for (int i = 0; i < tmp; ++i)
|
for (int i = 0; i < tmp; ++i)
|
||||||
{
|
{
|
||||||
if (_findnext(handle, &fd) < 0)
|
if (_findnext(handle, &fd) < 0)
|
||||||
@ -123,7 +96,6 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// current data in fd
|
// current data in fd
|
||||||
cell *length = get_amxaddr(amx,params[5]); // pointer to the outLen parameter
|
cell *length = get_amxaddr(amx,params[5]); // pointer to the outLen parameter
|
||||||
*length = set_amxstring(amx, params[3], fd.name, params[4]); // set output and outLen parameters
|
*length = set_amxstring(amx, params[3], fd.name, params[4]); // set output and outLen parameters
|
||||||
@ -138,37 +110,25 @@ static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
|
|||||||
int iLen;
|
int iLen;
|
||||||
char* szFile = get_amxstring(amx,params[1],0,iLen);
|
char* szFile = get_amxstring(amx,params[1],0,iLen);
|
||||||
FILE*fp;
|
FILE*fp;
|
||||||
|
if ( (fp =fopen(build_pathname("%s",szFile),"r")) == NULL) {
|
||||||
if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL)
|
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffor[1024];
|
char buffor[1024];
|
||||||
int i = 0, iLine = params[2];
|
int i = 0, iLine = params[2];
|
||||||
|
|
||||||
while((i <= iLine) && fgets(buffor,1023,fp) )
|
while((i <= iLine) && fgets(buffor,1023,fp) )
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
if (i > iLine){
|
||||||
if (i > iLine)
|
|
||||||
{
|
|
||||||
int len = strlen(buffor);
|
int len = strlen(buffor);
|
||||||
|
|
||||||
if (buffor[len-1]=='\n')
|
if (buffor[len-1]=='\n')
|
||||||
buffor[--len]=0;
|
buffor[--len]=0;
|
||||||
|
|
||||||
if (buffor[len-1]=='\r')
|
if (buffor[len-1]=='\r')
|
||||||
buffor[--len]=0;
|
buffor[--len]=0;
|
||||||
|
|
||||||
cell *length = get_amxaddr(amx,params[5]);
|
cell *length = get_amxaddr(amx,params[5]);
|
||||||
*length = set_amxstring(amx,params[3],buffor,params[4]);
|
*length = set_amxstring(amx,params[3],buffor,params[4]);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,86 +141,69 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
|||||||
int iLine = params[3];
|
int iLine = params[3];
|
||||||
|
|
||||||
// apending to the end
|
// apending to the end
|
||||||
if (iLine < 0)
|
if (iLine < 0) {
|
||||||
{
|
if ( (pFile = fopen( sFile ,"a")) == NULL ){
|
||||||
if ((pFile = fopen(sFile, "a")) == NULL)
|
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs( sText , pFile );
|
fputs( sText , pFile );
|
||||||
fputc( '\n', pFile );
|
fputc( '\n', pFile );
|
||||||
fclose( pFile );
|
fclose( pFile );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// creating a new file with a line in a middle
|
// creating a new file with a line in a middle
|
||||||
if ((pFile = fopen(sFile, "r")) == NULL)
|
if ( (pFile = fopen(sFile,"r")) == NULL ) {
|
||||||
{
|
if ( (pFile = fopen(sFile,"w")) == NULL ){
|
||||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i < iLine;++i)
|
for(i=0;i < iLine;++i)
|
||||||
fputc('\n',pFile);
|
fputc('\n',pFile);
|
||||||
|
|
||||||
fputs( sText , pFile );
|
fputs( sText , pFile );
|
||||||
fputc( '\n', pFile );
|
fputc( '\n', pFile );
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding a new line in a middle of already existing file
|
// adding a new line in a middle of already existing file
|
||||||
FILE* pTemp;
|
FILE* pTemp;
|
||||||
char buffor[2048];
|
char buffor[1024];
|
||||||
|
|
||||||
if ((pTemp = tmpfile()) == NULL)
|
if ( (pTemp = tmpfile()) == NULL ){
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ; ++i)
|
for(i=0;;++i){
|
||||||
{
|
if ( i == iLine ){
|
||||||
if (i == iLine)
|
fgets(buffor,1023,pFile);
|
||||||
{
|
|
||||||
fgets(buffor, 2047, pFile);
|
|
||||||
fputs( sText , pTemp );
|
fputs( sText , pTemp );
|
||||||
fputc( '\n', pTemp );
|
fputc( '\n', pTemp );
|
||||||
}
|
}
|
||||||
else if (fgets(buffor, 2047, pFile))
|
else if ( fgets(buffor,1023,pFile) ){
|
||||||
{
|
|
||||||
fputs(buffor , pTemp );
|
fputs(buffor , pTemp );
|
||||||
}
|
}
|
||||||
else if (i < iLine)
|
else if ( i < iLine ) {
|
||||||
{
|
|
||||||
fputc( '\n', pTemp );
|
fputc( '\n', pTemp );
|
||||||
}
|
}
|
||||||
else
|
else break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
rewind(pTemp);
|
rewind(pTemp);
|
||||||
|
|
||||||
// now rewrite because file can be now smaller...
|
// now rewrite because file can be now smaller...
|
||||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
if ( (pFile = fopen(sFile,"w")) == NULL ){
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buffor, 2047, pTemp))
|
while(fgets(buffor,1023,pTemp))
|
||||||
fputs(buffor,pFile );
|
fputs(buffor,pFile );
|
||||||
|
|
||||||
fclose(pTemp);
|
fclose(pTemp);
|
||||||
fclose(pFile);
|
fclose(pFile);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +211,6 @@ static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */
|
|||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||||
|
|
||||||
return (unlink( build_pathname("%s",sFile) )?0:1);
|
return (unlink( build_pathname("%s",sFile) )?0:1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,83 +218,32 @@ static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
|
|||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||||
char *file = build_pathname("%s", sFile);
|
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||||
|
if ( fp != NULL) {
|
||||||
#if defined WIN32 || defined _WIN32
|
fclose(fp);
|
||||||
DWORD attr = GetFileAttributes(file);
|
|
||||||
|
|
||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
if (stat(file, &s) != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (S_ISDIR(s.st_mode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
|
|
||||||
{
|
|
||||||
int iLen;
|
|
||||||
char *sFile = get_amxstring(amx, params[1], 0, iLen);
|
|
||||||
char *file = build_pathname("%s", sFile);
|
|
||||||
|
|
||||||
#if defined WIN32 || defined _WIN32
|
|
||||||
DWORD attr = GetFileAttributes(file);
|
|
||||||
|
|
||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
if (stat(file, &s) != 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (S_ISDIR(s.st_mode))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||||
AutoFilePtr fp(fopen(build_pathname("%s", sFile), "r"));
|
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||||
|
if ( fp != NULL) {
|
||||||
if (fp != NULL)
|
if ( params[0] < 2 || params[2] == 0 ){
|
||||||
{
|
|
||||||
if (params[0] < 2 || params[2] == 0)
|
|
||||||
{
|
|
||||||
fseek(fp,0,SEEK_END);
|
fseek(fp,0,SEEK_END);
|
||||||
int size = ftell(fp);
|
int size = ftell(fp);
|
||||||
|
fclose(fp);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
else if (params[2] == 1)
|
else if ( params[2] == 1 ){
|
||||||
{
|
|
||||||
int a = 0,lines = 0;
|
int a = 0,lines = 0;
|
||||||
|
while( a != EOF ){
|
||||||
while (a != EOF)
|
|
||||||
{
|
|
||||||
++lines;
|
++lines;
|
||||||
while ((a = fgetc(fp)) != '\n' && a != EOF);
|
while ( (a = fgetc(fp)) != '\n' && a != EOF )
|
||||||
|
;
|
||||||
}
|
}
|
||||||
//int a, b = '\n';
|
//int a, b = '\n';
|
||||||
//while( (a = fgetc(fp)) != EOF ){
|
//while( (a = fgetc(fp)) != EOF ){
|
||||||
@ -364,17 +255,13 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
|||||||
// ++lines;
|
// ++lines;
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
else if (params[2] == 2)
|
else if ( params[2] == 2 ){
|
||||||
{
|
|
||||||
fseek(fp,-1,SEEK_END);
|
fseek(fp,-1,SEEK_END);
|
||||||
|
|
||||||
if ( fgetc(fp) == '\n' )
|
if ( fgetc(fp) == '\n' )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,15 +273,7 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
|||||||
int len, j=-1;
|
int len, j=-1;
|
||||||
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
|
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
|
||||||
char *flags = get_amxstring(amx, params[2], 0, len);
|
char *flags = get_amxstring(amx, params[2], 0, len);
|
||||||
|
|
||||||
FILE *fp = fopen(file, flags);
|
FILE *fp = fopen(file, flags);
|
||||||
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
// Failed
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i<FileList.size(); i++)
|
for (i=0; i<FileList.size(); i++)
|
||||||
{
|
{
|
||||||
if (FileList.at(i) == NULL)
|
if (FileList.at(i) == NULL)
|
||||||
@ -403,7 +282,6 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j==-1)
|
if (j==-1)
|
||||||
{
|
{
|
||||||
FileList.push_back(fp);
|
FileList.push_back(fp);
|
||||||
@ -418,187 +296,140 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
|||||||
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fclose(fp);
|
return fclose(fp);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
unsigned int id = params[1] - 1;
|
||||||
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
|
return 0;
|
||||||
|
FILE *fp = FileList.at(id);
|
||||||
|
if (fp) {
|
||||||
|
return fgetc(fp);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
|
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
|
||||||
fread(buffer, sizeof(char), params[3], fp);
|
fread(buffer, sizeof(char), params[3], fp);
|
||||||
set_amxstring(amx, params[2], buffer, params[3]);
|
set_amxstring(amx, params[2], buffer, params[3]);
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNUSED
|
|
||||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
unsigned int id = params[1] - 1;
|
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
|
||||||
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fgetc(fp);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
int len;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
buf = format_amxstring(amx, params, 2, len);
|
buf = format_amxstring(amx, params, 2, len);
|
||||||
return fwrite(buf, sizeof(char), strlen(buf), fp);
|
return fwrite(buf, sizeof(char), strlen(buf), fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
if (feof(fp)) {
|
||||||
{
|
|
||||||
if (feof(fp))
|
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
return fseek(fp, (long)params[2], params[3]);
|
return fseek(fp, (long)params[2], params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
return fputc(params[2], fp);
|
return fputc(params[2], fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
return fflush(fp);
|
return fflush(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
char *buf;
|
char *buf;
|
||||||
int len;
|
int len;
|
||||||
buf = format_amxstring(amx, params, 2, len);
|
buf = format_amxstring(amx, params, 2, len);
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fscanf(fp, "%s", buf);
|
return fscanf(fp, "%s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,299 +439,154 @@ static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
|
|||||||
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
if (fp)
|
if (fp) {
|
||||||
{
|
|
||||||
return ftell(fp);
|
return ftell(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif //UNUSED
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *file = build_pathname("%s", format_amxstring(amx, params, 1, len));
|
char *file = build_pathname("%s", format_amxstring(amx, params, 1, len));
|
||||||
long size;
|
long size;
|
||||||
|
FILE *fp = fopen(file, "rb");
|
||||||
AutoFilePtr fp(fopen(file, "rb"));
|
if (fp) {
|
||||||
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
size = ftell(fp);
|
size = ftell(fp);
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNUSED
|
|
||||||
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
long t;
|
long t;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fread(&t, sizeof(long), 1, fp);
|
fread(&t, sizeof(long), 1, fp);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
int t;
|
int t;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fread(&t, sizeof(int), 1, fp);
|
fread(&t, sizeof(int), 1, fp);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
short t;
|
short t;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fread(&t, sizeof(short), 1, fp);
|
fread(&t, sizeof(short), 1, fp);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
short size = params[2];
|
short size = params[2];
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fwrite(&size, sizeof(short), 1, fp);
|
return fwrite(&size, sizeof(short), 1, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
long size = params[2];
|
long size = params[2];
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fwrite(&size, sizeof(long), 1, fp);
|
return fwrite(&size, sizeof(long), 1, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
int size = params[2];
|
int size = params[2];
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fwrite(&size, sizeof(int), 1, fp);
|
return fwrite(&size, sizeof(int), 1, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
float t;
|
float t;
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fread(&t, sizeof(float), 1, fp);
|
fread(&t, sizeof(float), 1, fp);
|
||||||
return *(cell*)&t;
|
return *(cell*)&t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
unsigned int id = params[1] - 1;
|
unsigned int id = params[1] - 1;
|
||||||
|
|
||||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FILE *fp = FileList.at(id);
|
FILE *fp = FileList.at(id);
|
||||||
|
|
||||||
float size = *(float *)((void *)¶ms[2]);
|
float size = *(float *)((void *)¶ms[2]);
|
||||||
|
if (fp) {
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
return fwrite(&size, sizeof(float), 1, fp);
|
return fwrite(&size, sizeof(float), 1, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif //UNUSED
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *szPath = get_amxstring(amx, params[1], 0, len);
|
char *szPath = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]);
|
return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
|
AMX_NATIVE_INFO file_Natives[] = {
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *path = get_amxstring(amx, params[1], 0, len);
|
|
||||||
|
|
||||||
#if defined WIN32 || defined _WIN32
|
|
||||||
char *dirname = build_pathname("%s\\*", path);
|
|
||||||
|
|
||||||
WIN32_FIND_DATA fd;
|
|
||||||
HANDLE hFile = FindFirstFile(dirname, &fd);
|
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
|
||||||
|
|
||||||
return (DWORD)hFile;
|
|
||||||
#else
|
|
||||||
char *dirname = build_pathname("%s", path);
|
|
||||||
DIR *dp = opendir(dirname);
|
|
||||||
|
|
||||||
if (!dp)
|
|
||||||
return NULL;
|
|
||||||
struct dirent *ep = readdir(dp);
|
|
||||||
|
|
||||||
if (!ep)
|
|
||||||
{
|
|
||||||
closedir(dp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_amxstring(amx, params[2], ep->d_name, params[3]);
|
|
||||||
|
|
||||||
return (cell)dp;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_close_dir(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
#if defined WIN32 || defined _WIN32
|
|
||||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
FindClose(hFile);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
DIR *dp = (DIR *)params[1];
|
|
||||||
|
|
||||||
if (!dp)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
closedir(dp);
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
#if defined WIN32 || defined _WIN32
|
|
||||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
WIN32_FIND_DATA fd;
|
|
||||||
|
|
||||||
if (!FindNextFile(hFile, &fd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
DIR *dp = (DIR *)params[1];
|
|
||||||
|
|
||||||
if (!dp)
|
|
||||||
return 0;
|
|
||||||
struct dirent *ep = readdir(dp);
|
|
||||||
|
|
||||||
if (!ep)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
set_amxstring(amx, params[2], ep->d_name, params[3]);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO file_Natives[] =
|
|
||||||
{
|
|
||||||
{ "delete_file", delete_file },
|
{ "delete_file", delete_file },
|
||||||
{ "file_exists", file_exists },
|
{ "file_exists", file_exists },
|
||||||
{ "file_size", file_size },
|
{ "file_size", file_size },
|
||||||
@ -910,10 +596,8 @@ AMX_NATIVE_INFO file_Natives[] =
|
|||||||
//Sanji's File Natives
|
//Sanji's File Natives
|
||||||
{ "fopen", amx_fopen },
|
{ "fopen", amx_fopen },
|
||||||
{ "fclose", amx_fclose },
|
{ "fclose", amx_fclose },
|
||||||
{"fread", amx_fread},
|
|
||||||
{"filesize", amx_filesize},
|
|
||||||
#ifdef UNUSED
|
|
||||||
{ "fgetc", amx_fgetc },
|
{ "fgetc", amx_fgetc },
|
||||||
|
{ "fread", amx_fread },
|
||||||
{ "fwrite", amx_fwrite },
|
{ "fwrite", amx_fwrite },
|
||||||
{ "feof", amx_feof },
|
{ "feof", amx_feof },
|
||||||
{ "fseek", amx_fseek },
|
{ "fseek", amx_fseek },
|
||||||
@ -922,20 +606,19 @@ AMX_NATIVE_INFO file_Natives[] =
|
|||||||
{ "fflush", amx_fflush },
|
{ "fflush", amx_fflush },
|
||||||
{ "fscanf", amx_fscanf },
|
{ "fscanf", amx_fscanf },
|
||||||
{ "ftell", amx_ftell },
|
{ "ftell", amx_ftell },
|
||||||
|
{ "filesize", amx_filesize },
|
||||||
{ "fgetl", amx_fgetl },
|
{ "fgetl", amx_fgetl },
|
||||||
{ "fgeti", amx_fgeti },
|
{ "fgeti", amx_fgeti },
|
||||||
{ "fgets", amx_fgets },
|
{ "fgets", amx_fgets },
|
||||||
{ "fputs", amx_fputs },
|
{ "fputs", amx_fputs },
|
||||||
{ "fputl", amx_fputl },
|
{ "fputl", amx_fputl },
|
||||||
{ "fputi", amx_fputi },
|
{ "fputi", amx_fputi },
|
||||||
|
{ "unlink", delete_file },
|
||||||
{ "fgetf", amx_fgetf },
|
{ "fgetf", amx_fgetf },
|
||||||
{ "fputf", amx_fputf },
|
{ "fputf", amx_fputf },
|
||||||
#endif
|
|
||||||
{"unlink", delete_file},
|
|
||||||
{ "build_pathname", amx_build_pathname},
|
{ "build_pathname", amx_build_pathname},
|
||||||
{"dir_exists", dir_exists},
|
|
||||||
{"open_dir", amx_open_dir},
|
|
||||||
{"close_dir", amx_close_dir},
|
|
||||||
{"next_file", amx_get_dir},
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,19 +37,6 @@
|
|||||||
|
|
||||||
#define PI 3.1415926535897932384626433832795
|
#define PI 3.1415926535897932384626433832795
|
||||||
|
|
||||||
static REAL FromRadians(REAL angle, int radix)
|
|
||||||
{
|
|
||||||
switch (radix)
|
|
||||||
{
|
|
||||||
case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
|
|
||||||
return (REAL)(angle / PI * 180.0);
|
|
||||||
case 2: /* grades, centesimal system */
|
|
||||||
return (REAL)(angle / PI * 200.0);
|
|
||||||
default: /* assume already radian */
|
|
||||||
return angle;
|
|
||||||
} /* switch */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||||
#pragma argsused
|
#pragma argsused
|
||||||
#endif
|
#endif
|
||||||
@ -96,7 +83,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);
|
||||||
@ -370,7 +357,6 @@ static cell AMX_NATIVE_CALL n_floatatan(AMX *amx, cell *params)
|
|||||||
REAL fA = amx_ctof(params[1]);
|
REAL fA = amx_ctof(params[1]);
|
||||||
fA = ToRadians(fA, params[2]);
|
fA = ToRadians(fA, params[2]);
|
||||||
fA = atan(fA);
|
fA = atan(fA);
|
||||||
fA = FromRadians(fA, params[2]);
|
|
||||||
return amx_ftoc(fA);
|
return amx_ftoc(fA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,8 +371,8 @@ static cell AMX_NATIVE_CALL n_floatacos(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 = acos(fA);
|
fA = acos(fA);
|
||||||
fA = FromRadians(fA, params[2]);
|
|
||||||
return amx_ftoc(fA);
|
return amx_ftoc(fA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,8 +387,8 @@ static cell AMX_NATIVE_CALL n_floatasin(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 = asin(fA);
|
fA = asin(fA);
|
||||||
fA = FromRadians(fA, params[2]);
|
|
||||||
return amx_ftoc(fA);
|
return amx_ftoc(fA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +407,6 @@ static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
|
|||||||
REAL fB = amx_ctof(params[2]);
|
REAL fB = amx_ctof(params[2]);
|
||||||
REAL fC;
|
REAL fC;
|
||||||
fC = atan2(fA, fB);
|
fC = atan2(fA, fB);
|
||||||
fC = FromRadians(fC, params[3]);
|
|
||||||
return amx_ftoc(fC);
|
return amx_ftoc(fC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2004 Jussi Kivilinna
|
|
||||||
*
|
|
||||||
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
|
|
||||||
*
|
|
||||||
* Metamod is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the
|
|
||||||
* Free Software Foundation; either version 2 of the License, or (at
|
|
||||||
* your option) any later version.
|
|
||||||
*
|
|
||||||
* Metamod is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Metamod; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the author gives permission to
|
|
||||||
* link the code of this program with the Half-Life Game Engine ("HL
|
|
||||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
|
||||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
|
||||||
* respects for all of the code used other than the HL Engine and MODs
|
|
||||||
* from Valve. If you modify this file, you may extend this exception
|
|
||||||
* to your version of the file, but you are not obligated to do so. If
|
|
||||||
* you do not wish to do so, delete this exception statement from your
|
|
||||||
* version.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MM_PEXTENSIONS_H
|
|
||||||
#define MM_PEXTENSIONS_H
|
|
||||||
|
|
||||||
#include "plinfo.h" // plid_t
|
|
||||||
#include "meta_api.h" // PLUG_LOADTIME
|
|
||||||
/*
|
|
||||||
|
|
||||||
How to use:
|
|
||||||
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
|
|
||||||
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
|
|
||||||
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
|
|
||||||
and pointer to extension function table.
|
|
||||||
3. Meta_PExtGiveFnptrs should return plugin's interface version.
|
|
||||||
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
|
|
||||||
interface version greater than current. Plugin should disable itself in
|
|
||||||
this kind of situation.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
#include "mm_pextensions.h"
|
|
||||||
|
|
||||||
pextension_funcs_t *gpMetaPExtFuncs;
|
|
||||||
|
|
||||||
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
|
|
||||||
if(interfaceVersion < META_PEXT_VERSION) {
|
|
||||||
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
|
|
||||||
gpMetaPExtFuncs = NULL;
|
|
||||||
|
|
||||||
return(META_PEXT_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
gpMetaPExtFuncs = pMetaPExtFuncs;
|
|
||||||
|
|
||||||
return(META_PEXT_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
Callback functions:
|
|
||||||
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
|
||||||
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
|
|
||||||
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
|
|
||||||
plugin at it.
|
|
||||||
Returns zero on success.
|
|
||||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
|
||||||
|
|
||||||
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
|
||||||
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
|
|
||||||
unloads found plugin.
|
|
||||||
Returns zero on success.
|
|
||||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
|
||||||
|
|
||||||
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
|
||||||
Unloads plugin with 'plugin_handle'.
|
|
||||||
Returns zero on success.
|
|
||||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
|
||||||
|
|
||||||
!NOTE! Plugin cannot unload itself!
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Interface version
|
|
||||||
// 1: first version. Used in p13
|
|
||||||
// 2: Complete remake (p14):
|
|
||||||
// pfnLoadMetaPluginByName
|
|
||||||
// pfnUnloadMetaPluginByName
|
|
||||||
// pfnUnloadMetaPluginByHandle
|
|
||||||
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
|
|
||||||
#define META_PEXT_VERSION 2
|
|
||||||
|
|
||||||
// Meta PExtension Function table type.
|
|
||||||
typedef struct pextension_funcs_s {
|
|
||||||
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
|
||||||
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
|
||||||
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
|
||||||
} pextension_funcs_t;
|
|
||||||
|
|
||||||
// Convenience macros for MetaPExtension functions.
|
|
||||||
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
|
|
||||||
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
|
|
||||||
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
|
|
||||||
|
|
||||||
// Give plugin extension function table.
|
|
||||||
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
|
|
||||||
pextension_funcs_t *pMetaPExtFuncs);
|
|
||||||
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
|
|
||||||
pextension_funcs_t *pMetaPExtFuncs);
|
|
||||||
|
|
||||||
#endif /* MM_PEXTENSIONS_H */
|
|
@ -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() :)
|
||||||
|
1015
amxmodx/modules.cpp
1015
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -45,10 +45,135 @@
|
|||||||
#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
|
||||||
|
|
||||||
int CheckModules(AMX *amx, char error[128]);
|
struct module_info_s {
|
||||||
const char *StrCaseStr(const char *as, const char *bs);
|
const char* name;
|
||||||
|
const char* author;
|
||||||
|
const char* version;
|
||||||
|
int ivers;
|
||||||
|
int type;
|
||||||
|
long int serial;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Small scripting language
|
||||||
|
struct pfnamx_engine_g {
|
||||||
|
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
|
||||||
|
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
|
||||||
|
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
|
||||||
|
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
|
||||||
|
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
|
||||||
|
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
|
||||||
|
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
|
||||||
|
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
|
||||||
|
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
|
||||||
|
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
|
||||||
|
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
|
||||||
|
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
|
||||||
|
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
|
||||||
|
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
|
||||||
|
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
|
||||||
|
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
|
||||||
|
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
|
||||||
|
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
|
||||||
|
int (*pfnamx_Init)(AMX*, void *); // amx, program
|
||||||
|
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
|
||||||
|
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
|
||||||
|
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
|
||||||
|
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
|
||||||
|
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
|
||||||
|
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
|
||||||
|
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
|
||||||
|
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
|
||||||
|
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
|
||||||
|
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
|
||||||
|
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
|
||||||
|
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
|
||||||
|
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
|
||||||
|
};
|
||||||
|
extern pfnamx_engine_g* g_engAmxFunc;
|
||||||
|
|
||||||
|
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
|
||||||
|
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
|
||||||
|
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
|
||||||
|
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
|
||||||
|
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
|
||||||
|
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
|
||||||
|
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
|
||||||
|
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
|
||||||
|
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
|
||||||
|
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
|
||||||
|
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
|
||||||
|
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
|
||||||
|
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
|
||||||
|
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
|
||||||
|
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
|
||||||
|
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
|
||||||
|
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
|
||||||
|
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
|
||||||
|
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
|
||||||
|
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
|
||||||
|
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
|
||||||
|
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
|
||||||
|
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
|
||||||
|
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
|
||||||
|
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
|
||||||
|
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
|
||||||
|
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
|
||||||
|
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
|
||||||
|
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
|
||||||
|
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
|
||||||
|
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
|
||||||
|
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
|
||||||
|
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
|
||||||
|
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
|
||||||
|
|
||||||
|
// Modules API
|
||||||
|
struct pfnmodule_engine_g {
|
||||||
|
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
|
||||||
|
char* (*pfnbuild_pathname)(char*, ...); // format, ....
|
||||||
|
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
|
||||||
|
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
|
||||||
|
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
|
||||||
|
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
|
||||||
|
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
|
||||||
|
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
|
||||||
|
void (*pfnget_modname)(char*); // modname
|
||||||
|
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64]); // amx, code, path, error info
|
||||||
|
void (*pfnprint_console)(char*, ...); // format, ....
|
||||||
|
void (*pfnreport_error)(int code, char*, ... );
|
||||||
|
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
|
||||||
|
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
|
||||||
|
int (*pfnamxstring_length)(cell*); // src
|
||||||
|
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
|
||||||
|
void* (*pfnalloc_amxmemory)(void**,int size);
|
||||||
|
void (*pfnfree_amxmemory)(void**);
|
||||||
|
};
|
||||||
|
extern pfnmodule_engine_g* g_engModuleFunc;
|
||||||
|
|
||||||
|
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
|
||||||
|
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
|
||||||
|
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
|
||||||
|
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
|
||||||
|
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
|
||||||
|
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
|
||||||
|
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
|
||||||
|
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
|
||||||
|
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
|
||||||
|
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
|
||||||
|
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
|
||||||
|
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
|
||||||
|
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
|
||||||
|
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
|
||||||
|
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
|
||||||
|
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
|
||||||
|
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
|
||||||
|
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
|
||||||
|
|
||||||
|
|
||||||
#endif // __MODULES_H__
|
#endif // __MODULES_H__
|
||||||
|
@ -42,13 +42,12 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\JIT\natives-x86.obj ..\zlib\zlib.lib"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
|
||||||
OutputFile="debug/amxmodx_mm.dll"
|
OutputFile="debug/amxx_mm.dll"
|
||||||
Version="0.1"
|
Version="0.1"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
||||||
@ -113,12 +112,11 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||||
OutputFile="release/amxmodx_mm.dll"
|
OutputFile="release/amxx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
ProgramDatabaseFile=".\release/amxx_mm.pdb"
|
ProgramDatabaseFile=".\release/amxx_mm.pdb"
|
||||||
ImportLibrary=".\release/amxx_mm.lib"/>
|
ImportLibrary=".\release/amxx_mm.lib"/>
|
||||||
@ -181,13 +179,12 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||||
OutputFile="memtestdebug/amxmodx_mm.dll"
|
OutputFile="memtestdebug/amxx_mm.dll"
|
||||||
Version="0.1"
|
Version="0.1"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
|
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
|
||||||
@ -252,17 +249,13 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib"
|
||||||
OutputFile="memtestrelease/amxmodx_mm.dll"
|
OutputFile="memtestrelease/amxx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="LIBC"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||||
GenerateMapFile="TRUE"
|
|
||||||
MapExports="TRUE"
|
|
||||||
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
@ -304,7 +297,7 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
Optimization="0"
|
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"
|
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
StructMemberAlignment="3"
|
StructMemberAlignment="3"
|
||||||
@ -323,13 +316,12 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib"
|
||||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
OutputFile="jitdebug/amxx_mm.dll"
|
||||||
Version="0.1"
|
Version="0.1"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
GenerateDebugInformation="TRUE"
|
||||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||||
@ -375,10 +367,8 @@
|
|||||||
GlobalOptimizations="TRUE"
|
GlobalOptimizations="TRUE"
|
||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
OmitFramePointers="TRUE"
|
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||||
IgnoreStandardIncludePath="FALSE"
|
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
@ -396,16 +386,13 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
OutputFile="jitrelease/amxx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
|
||||||
GenerateMapFile="FALSE"
|
|
||||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCMIDLTool"
|
Name="VCMIDLTool"
|
||||||
@ -449,7 +436,7 @@
|
|||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT"
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
@ -467,14 +454,12 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib"
|
||||||
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
OutputFile="jitmemtestrelease/amxx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
IgnoreDefaultLibraryNames="MSVCRT"
|
|
||||||
ModuleDefinitionFile=""
|
ModuleDefinitionFile=""
|
||||||
GenerateDebugInformation="TRUE"
|
|
||||||
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||||
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
||||||
<Tool
|
<Tool
|
||||||
@ -540,8 +525,8 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib"
|
||||||
OutputFile="MaximalSpeed/amxmodx_mm.dll"
|
OutputFile="MaximalSpeed/amxx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||||
@ -589,9 +574,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxcore.cpp">
|
RelativePath="..\amxcore.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\amxdbg.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.cpp">
|
RelativePath="..\amxmodx.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -640,9 +622,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CVault.cpp">
|
RelativePath="..\CVault.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\emsg.cpp">
|
RelativePath="..\emsg.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -670,12 +649,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\modules.cpp">
|
RelativePath="..\modules.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\natives.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\newmenus.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\power.cpp">
|
RelativePath="..\power.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -738,9 +711,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amx.h">
|
RelativePath="..\amx.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\amxdbg.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.h">
|
RelativePath="..\amxmodx.h">
|
||||||
</File>
|
</File>
|
||||||
@ -787,7 +757,7 @@
|
|||||||
RelativePath="..\CQueue.h">
|
RelativePath="..\CQueue.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CStack.h">
|
RelativePath="..\CRList.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\CString.h">
|
RelativePath="..\CString.h">
|
||||||
@ -801,36 +771,15 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\CVector.h">
|
RelativePath="..\CVector.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\debugger.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\fakemeta.h">
|
RelativePath="..\fakemeta.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.h">
|
RelativePath="..\md5.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\menus.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\modules.h">
|
RelativePath="..\modules.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="..\natives.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\newmenus.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\resource.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\zlib\zconf.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\zlib\zlib.h">
|
|
||||||
</File>
|
|
||||||
<Filter
|
<Filter
|
||||||
Name="mmgr"
|
Name="mmgr"
|
||||||
Filter="">
|
Filter="">
|
||||||
@ -849,25 +798,6 @@
|
|||||||
RelativePath="..\version.rc">
|
RelativePath="..\version.rc">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
|
||||||
Name="Assembly"
|
|
||||||
Filter="">
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxdefn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxexecn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\amxjitsn.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-amd64.asm">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\natives-x86.asm">
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
</Files>
|
</Files>
|
||||||
<Globals>
|
<Globals>
|
||||||
</Globals>
|
</Globals>
|
@ -1,39 +0,0 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
|
||||||
Debug = Debug
|
|
||||||
JITDebug = JITDebug
|
|
||||||
JITMemtestRelease = JITMemtestRelease
|
|
||||||
JITRelease = JITRelease
|
|
||||||
MaximalSpeed = MaximalSpeed
|
|
||||||
MemtestDebug = MemtestDebug
|
|
||||||
MemtestRelease = MemtestRelease
|
|
||||||
Release = Release
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfiguration) = postSolution
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
|
|
||||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@ -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,436 +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 "CStack.h"
|
|
||||||
#include "natives.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;
|
|
||||||
CStack<regnative *> g_NativeStack;
|
|
||||||
CVector<String> g_Libraries;
|
|
||||||
static char g_errorStr[512] = {0};
|
|
||||||
static int g_errorNum = 0;
|
|
||||||
bool g_Initialized = false;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//parameter stack
|
|
||||||
pNative->caller = amx;
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
|
||||||
|
|
||||||
int err = 0;
|
|
||||||
cell ret = 0;
|
|
||||||
g_errorNum = 0;
|
|
||||||
g_NativeStack.push(pNative);
|
|
||||||
if (pNative->style == 0)
|
|
||||||
{
|
|
||||||
amx_Push(pNative->amx, numParams);
|
|
||||||
amx_Push(pNative->amx, pPlugin->getId());
|
|
||||||
for (int i=numParams; i>=1; i--)
|
|
||||||
pNative->params[i] = params[i];
|
|
||||||
} else if (pNative->style == 1) {
|
|
||||||
//use dJeyL's system .. very clever!
|
|
||||||
for (int i=numParams; i>=1; i--)
|
|
||||||
amx_Push(pNative->amx, params[i]);
|
|
||||||
}
|
|
||||||
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
|
|
||||||
{
|
|
||||||
g_NativeStack.pop();
|
|
||||||
LogError(pNative->amx, err, "");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g_errorNum)
|
|
||||||
{
|
|
||||||
g_NativeStack.pop();
|
|
||||||
LogError(amx, g_errorNum, g_errorStr);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
g_NativeStack.pop();
|
|
||||||
|
|
||||||
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_errorNum = params[1];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get_string(param, dest[], len)
|
|
||||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *str = get_amxstring(pNative->caller, pNative->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_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->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(pNative->caller, pNative->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_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
return pNative->params[p];
|
|
||||||
}
|
|
||||||
|
|
||||||
//get_param_byref(num)
|
|
||||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
|
||||||
|
|
||||||
return addr[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//set_param_byref(num, val)
|
|
||||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
if (!g_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *addr = get_amxaddr(pNative->caller, pNative->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_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *source = get_amxaddr(pNative->caller, pNative->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_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int p = params[1];
|
|
||||||
|
|
||||||
cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
|
|
||||||
cell *source = get_amxaddr(amx, params[2]);
|
|
||||||
|
|
||||||
int size = params[3];
|
|
||||||
|
|
||||||
memcpy(dest, source, size * sizeof(cell));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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_NativeStack.size())
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
regnative *pNative = g_NativeStack.top();
|
|
||||||
if (pNative->style != 1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
cell p = params[1];
|
|
||||||
|
|
||||||
AMX *caller = pNative->caller;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
AddPluginLibrary(lib);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LibraryExists(const char *name)
|
|
||||||
{
|
|
||||||
for (size_t i=0; i<g_Libraries.size(); i++)
|
|
||||||
{
|
|
||||||
if (stricmp(g_Libraries[i].c_str(), name)==0)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddPluginLibrary(const char *name)
|
|
||||||
{
|
|
||||||
String f(name);
|
|
||||||
g_Libraries.push_back(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearPluginLibraries()
|
|
||||||
{
|
|
||||||
g_Libraries.clear();
|
|
||||||
|
|
||||||
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},
|
|
||||||
{"param_convert", param_convert},
|
|
||||||
//////////////////////////
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
@ -1,69 +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
|
|
||||||
#define CALLFUNC_MAXPARAMS 16
|
|
||||||
|
|
||||||
#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;
|
|
||||||
AMX *caller;
|
|
||||||
int style;
|
|
||||||
cell params[CALLFUNC_MAXPARAMS];
|
|
||||||
};
|
|
||||||
|
|
||||||
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 AddPluginLibrary(const char *name);
|
|
||||||
void ClearPluginLibraries();
|
|
||||||
bool LibraryExists(const char *name);
|
|
||||||
|
|
||||||
//I couldn't resist :)
|
|
||||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_NATIVES_H
|
|
@ -1,484 +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 "newmenus.h"
|
|
||||||
|
|
||||||
CVector<Menu *> g_NewMenus;
|
|
||||||
|
|
||||||
void ClearMenus()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < g_NewMenus.size(); i++)
|
|
||||||
delete g_NewMenus[i];
|
|
||||||
|
|
||||||
g_NewMenus.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu::Menu(const char *title, int mid, int tid)
|
|
||||||
{
|
|
||||||
m_Title.assign(title);
|
|
||||||
menuId = mid;
|
|
||||||
thisId = tid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu::~Menu()
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < m_Items.size(); i++)
|
|
||||||
delete m_Items[i];
|
|
||||||
|
|
||||||
m_Items.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
|
|
||||||
{
|
|
||||||
menuitem *pItem = new menuitem;
|
|
||||||
|
|
||||||
pItem->name.assign(name);
|
|
||||||
pItem->cmd.assign(cmd);
|
|
||||||
pItem->access = access;
|
|
||||||
pItem->id = m_Items.size();
|
|
||||||
pItem->handler = -1;
|
|
||||||
pItem->pfn = NULL;
|
|
||||||
|
|
||||||
m_Items.push_back(pItem);
|
|
||||||
|
|
||||||
return pItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem *Menu::GetMenuItem(item_t item)
|
|
||||||
{
|
|
||||||
if (item >= m_Items.size())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return m_Items[item];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Menu::GetItemCount()
|
|
||||||
{
|
|
||||||
return m_Items.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Menu::GetPageCount()
|
|
||||||
{
|
|
||||||
size_t items = GetItemCount();
|
|
||||||
page_t numPages = (items / MENUITEMS) + 1;
|
|
||||||
|
|
||||||
if (!items)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (numPages % MENUITEMS == 0)
|
|
||||||
numPages--;
|
|
||||||
|
|
||||||
return numPages;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Menu::PagekeyToItem(page_t page, item_t key)
|
|
||||||
{
|
|
||||||
page_t pages = GetPageCount();
|
|
||||||
item_t numItems = GetItemCount();
|
|
||||||
|
|
||||||
if (page >= pages)
|
|
||||||
return MENU_EXIT;
|
|
||||||
|
|
||||||
item_t start = page * 7;
|
|
||||||
|
|
||||||
if (page == 0)
|
|
||||||
{
|
|
||||||
item_t rem = numItems >= 7 ? 7 : numItems;
|
|
||||||
|
|
||||||
if (key == rem)
|
|
||||||
{
|
|
||||||
if (pages > 1)
|
|
||||||
return MENU_MORE;
|
|
||||||
else
|
|
||||||
return MENU_EXIT;
|
|
||||||
}
|
|
||||||
else if (key == rem + 1)
|
|
||||||
{
|
|
||||||
return MENU_EXIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (page == pages - 1)
|
|
||||||
{
|
|
||||||
//find number of remaining items
|
|
||||||
//for example, 11 items on page 1... means start=7, 11-7=4
|
|
||||||
item_t rem = numItems - start;
|
|
||||||
//however, the last item is actually this -1, so...
|
|
||||||
if (key == rem)
|
|
||||||
{
|
|
||||||
return MENU_EXIT;
|
|
||||||
}
|
|
||||||
else if (key == rem + 1)
|
|
||||||
{
|
|
||||||
return MENU_BACK;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (key == 7)
|
|
||||||
{
|
|
||||||
return MENU_MORE;
|
|
||||||
}
|
|
||||||
else if (key == 8)
|
|
||||||
{
|
|
||||||
return MENU_BACK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (start + key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Menu::Display(int player, page_t page)
|
|
||||||
{
|
|
||||||
int keys = 0;
|
|
||||||
const char *str = GetTextString(player, page, keys);
|
|
||||||
|
|
||||||
if (!str)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
static char buffer[2048];
|
|
||||||
int len = _snprintf(buffer, sizeof(buffer)-1, "%s", str);
|
|
||||||
|
|
||||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
|
|
||||||
|
|
||||||
pPlayer->keys = keys;
|
|
||||||
pPlayer->menu = menuId;
|
|
||||||
pPlayer->newmenu = thisId;
|
|
||||||
pPlayer->page = (int)page;
|
|
||||||
|
|
||||||
UTIL_ShowMenu(pPlayer->pEdict, keys, -1, buffer, len);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Menu::GetTextString(int player, page_t page, int &keys)
|
|
||||||
{
|
|
||||||
page_t pages = GetPageCount();
|
|
||||||
item_t numItems = GetItemCount();
|
|
||||||
|
|
||||||
if (page >= pages)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
m_Text.clear();
|
|
||||||
|
|
||||||
char buffer[255];
|
|
||||||
if (g_coloredmenus)
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
|
|
||||||
else
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
|
||||||
|
|
||||||
m_Text.append(buffer);
|
|
||||||
|
|
||||||
item_t start = page * 7;
|
|
||||||
item_t end = 0;
|
|
||||||
if (start + 7 <= numItems)
|
|
||||||
{
|
|
||||||
end = start + 7;
|
|
||||||
} else {
|
|
||||||
end = numItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuitem *pItem = NULL;
|
|
||||||
|
|
||||||
int option = 0;
|
|
||||||
keys = 0;
|
|
||||||
bool enabled = true;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
for (item_t i = start; i < end; i++)
|
|
||||||
{
|
|
||||||
pItem = m_Items[i];
|
|
||||||
|
|
||||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
|
||||||
enabled = false;
|
|
||||||
|
|
||||||
if (pItem->handler != -1)
|
|
||||||
{
|
|
||||||
ret = executeForwards(pItem->handler, player, thisId, i);
|
|
||||||
if (ret == ITEM_ENABLED)
|
|
||||||
enabled = true;
|
|
||||||
else if (ret == ITEM_DISABLED)
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pItem->pfn)
|
|
||||||
{
|
|
||||||
ret = (pItem->pfn)(player, thisId, i);
|
|
||||||
if (ret == ITEM_ENABLED)
|
|
||||||
enabled = true;
|
|
||||||
else if (ret == ITEM_DISABLED)
|
|
||||||
enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enabled)
|
|
||||||
{
|
|
||||||
keys |= (1<<option);
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
|
|
||||||
} else {
|
|
||||||
if (g_coloredmenus)
|
|
||||||
{
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
|
|
||||||
} else {
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
|
||||||
option++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_Text.append(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
//now for a weird part >:o
|
|
||||||
//this will either be MORE or BACK..
|
|
||||||
keys |= (1<<option++);
|
|
||||||
if ((page < pages - 1) && (pages > 1))
|
|
||||||
{
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
|
|
||||||
} else {
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Text.append(buffer);
|
|
||||||
|
|
||||||
if (pages > 1)
|
|
||||||
{
|
|
||||||
keys |= (1<<option++);
|
|
||||||
if (pages == 0)
|
|
||||||
{
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
|
||||||
} else {
|
|
||||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
|
|
||||||
}
|
|
||||||
m_Text.append(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_Text.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
|
|
||||||
return 0; } \
|
|
||||||
Menu *pMenu = g_NewMenus[p];
|
|
||||||
|
|
||||||
//Makes a new menu handle (-1 for failure)
|
|
||||||
//native csdm_makemenu(title[]);
|
|
||||||
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *title = get_amxstring(amx, params[1], 0, len);
|
|
||||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
|
||||||
|
|
||||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
|
|
||||||
if (func == -1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int id = g_menucmds.registerMenuId(title, amx);
|
|
||||||
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
|
|
||||||
|
|
||||||
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
|
|
||||||
g_NewMenus.push_back(pMenu);
|
|
||||||
|
|
||||||
return (int)g_NewMenus.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Adds an item to the menu (returns current item count - 1)
|
|
||||||
//native menu_additem(menu, const name[], const command[]="", access=0);
|
|
||||||
static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *name, *cmd;
|
|
||||||
int access;
|
|
||||||
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
name = get_amxstring(amx, params[2], 0, len);
|
|
||||||
cmd = get_amxstring(amx, params[3], 1, len);
|
|
||||||
access = params[4];
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->AddItem(name, cmd, access);
|
|
||||||
|
|
||||||
pItem->handler = params[5];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns the number of pages in a menu
|
|
||||||
//native csdm_menu_pages(menu);
|
|
||||||
static cell AMX_NATIVE_CALL menu_pages(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
return pMenu->GetPageCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns the number of items in a menu
|
|
||||||
//native csdm_menu_items(menu);
|
|
||||||
static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
return pMenu->GetItemCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Builds the menu string for a specific page (set title to 0 to not include title)
|
|
||||||
//page indices start at 0!
|
|
||||||
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[2]);
|
|
||||||
|
|
||||||
int player = params[1];
|
|
||||||
int page = params[3];
|
|
||||||
|
|
||||||
return pMenu->Display(player, page);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Finds the id of a menu item for a specific page and key value.
|
|
||||||
//Note that key should be from 0-6, as it only displays 7 per page.
|
|
||||||
//page indices start at 0
|
|
||||||
//native menu_keyid(menu, page, key);
|
|
||||||
static cell AMX_NATIVE_CALL menu_find_id(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
page_t page = static_cast<page_t>(params[2]);
|
|
||||||
item_t key = static_cast<item_t>(params[3]);
|
|
||||||
|
|
||||||
return pMenu->PagekeyToItem(page, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Gets info about a menu option
|
|
||||||
//native menu_item_getinfo(menu, item, &access, command[], cmdlen, name[]="", namelen=0, &callback);
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cell *addr = get_amxaddr(amx, params[3]);
|
|
||||||
addr[0] = pItem->access;
|
|
||||||
|
|
||||||
set_amxstring(amx, params[4], pItem->cmd.c_str(), params[5]);
|
|
||||||
set_amxstring(amx, params[6], pItem->name.c_str(), params[7]);
|
|
||||||
|
|
||||||
if (params[8])
|
|
||||||
{
|
|
||||||
addr = get_amxaddr(amx, params[8]);
|
|
||||||
if (addr)
|
|
||||||
addr[0] = pItem->handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *name = get_amxstring(amx, params[1], 0, len);
|
|
||||||
|
|
||||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
|
||||||
|
|
||||||
if (id == -1)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function %s", name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
name = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
pItem->name.assign(name);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int len;
|
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
cmd = get_amxstring(amx, params[3], 0, len);
|
|
||||||
|
|
||||||
pItem->cmd.assign(cmd);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
GETMENU(params[1]);
|
|
||||||
|
|
||||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
|
||||||
|
|
||||||
if (!pItem)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pItem->handler = params[3];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
|
||||||
{
|
|
||||||
{"menu_create", menu_create},
|
|
||||||
{"menu_additem", menu_additem},
|
|
||||||
{"menu_pages", menu_pages},
|
|
||||||
{"menu_items", menu_items},
|
|
||||||
{"menu_display", menu_display},
|
|
||||||
{"menu_find_id", menu_find_id},
|
|
||||||
{"menu_item_getinfo", menu_item_getinfo},
|
|
||||||
{"menu_makecallback", menu_makecallback},
|
|
||||||
{"menu_item_setcall", menu_item_setcall},
|
|
||||||
{"menu_item_setcmd", menu_item_setcmd},
|
|
||||||
{"menu_item_setname", menu_item_setname},
|
|
||||||
{NULL, NULL},
|
|
||||||
};
|
|
@ -1,106 +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 MENUITEMS 7
|
|
||||||
|
|
||||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
|
||||||
|
|
||||||
struct menuitem
|
|
||||||
{
|
|
||||||
String name;
|
|
||||||
String cmd;
|
|
||||||
|
|
||||||
int access;
|
|
||||||
int handler;
|
|
||||||
|
|
||||||
MENUITEM_CALLBACK pfn;
|
|
||||||
size_t id;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef unsigned int menu_t;
|
|
||||||
typedef unsigned int item_t;
|
|
||||||
typedef unsigned int page_t;
|
|
||||||
|
|
||||||
class Menu
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Menu(const char *title, int menuId, int thisId);
|
|
||||||
~Menu();
|
|
||||||
|
|
||||||
menuitem *GetMenuItem(item_t item);
|
|
||||||
size_t GetPageCount();
|
|
||||||
size_t GetItemCount();
|
|
||||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
|
||||||
|
|
||||||
const char *GetTextString(int player, page_t page, int &keys);
|
|
||||||
bool Display(int player, page_t page);
|
|
||||||
|
|
||||||
int PagekeyToItem(page_t page, item_t key);
|
|
||||||
int GetMenuMenuid();
|
|
||||||
private:
|
|
||||||
CVector<menuitem * > m_Items;
|
|
||||||
|
|
||||||
String m_Title;
|
|
||||||
String m_Text;
|
|
||||||
|
|
||||||
int menuId;
|
|
||||||
int thisId;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*Menu *CreateMenu(const char *title);
|
|
||||||
Menu *GetMenuById(menu_t menu);
|
|
||||||
menuitem *GetMenuItem(menu_t menu, item_t item);
|
|
||||||
size_t GetMenuPages(menu_t menu);
|
|
||||||
size_t GetMenuItems(menu_t menu);
|
|
||||||
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
|
|
||||||
bool DisplayMenu(menu_t menu, int player, page_t page);
|
|
||||||
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
|
|
||||||
int FindByMenuid(int menuid);
|
|
||||||
int GetMenuMenuid(menu_t menu);
|
|
||||||
const char *GetItemName(menu_t menu, item_t item);
|
|
||||||
const char *GetItemCmd(menu_t menu, item_t item);*/
|
|
||||||
|
|
||||||
void ClearMenus();
|
|
||||||
|
|
||||||
extern CVector<Menu *> g_NewMenus;
|
|
||||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
|
||||||
|
|
||||||
#endif //_INCLUDE_NEWMENUS_H
|
|
@ -6,7 +6,6 @@
|
|||||||
* This file may be freely used. No warranties of any kind.
|
* This file may be freely used. No warranties of any kind.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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"
|
||||||
|
@ -20,13 +20,6 @@
|
|||||||
#define stricmp(a,b) strcasecmp(a,b)
|
#define stricmp(a,b) strcasecmp(a,b)
|
||||||
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
||||||
|
|
||||||
#if defined __linux__ && !defined _snprintf
|
|
||||||
#define _snprintf snprintf
|
|
||||||
#endif
|
|
||||||
#if defined __linux__ && !defined _vsnprintf
|
|
||||||
//#define _vsnprintf vsnprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WinWorld wants '\'. Unices do not.
|
* WinWorld wants '\'. Unices do not.
|
||||||
*/
|
*/
|
||||||
|
@ -45,13 +45,6 @@
|
|||||||
enginefuncs_t g_engfuncs;
|
enginefuncs_t g_engfuncs;
|
||||||
globalvars_t *gpGlobals;
|
globalvars_t *gpGlobals;
|
||||||
|
|
||||||
DLL_FUNCTIONS *g_pFunctionTable;
|
|
||||||
DLL_FUNCTIONS *g_pFunctionTable_Post;
|
|
||||||
enginefuncs_t *g_pengfuncsTable;
|
|
||||||
enginefuncs_t *g_pengfuncsTable_Post;
|
|
||||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
|
|
||||||
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
|
|
||||||
|
|
||||||
// GetEntityAPI2 functions
|
// GetEntityAPI2 functions
|
||||||
static DLL_FUNCTIONS g_EntityAPI_Table =
|
static DLL_FUNCTIONS g_EntityAPI_Table =
|
||||||
{
|
{
|
||||||
@ -2121,7 +2114,6 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof(DLL_FUNCTIONS));
|
memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof(DLL_FUNCTIONS));
|
||||||
g_pFunctionTable=pFunctionTable;
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2139,7 +2131,7 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy( pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) );
|
memcpy( pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) );
|
||||||
g_pFunctionTable_Post=pFunctionTable;
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2162,7 +2154,6 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Table, sizeof(enginefuncs_t));
|
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Table, sizeof(enginefuncs_t));
|
||||||
g_pengfuncsTable=pengfuncsFromEngine;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2180,7 +2171,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t));
|
memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t));
|
||||||
g_pengfuncsTable_Post=pengfuncsFromEngine;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2205,7 +2195,6 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable,
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy(pNewFunctionTable, &g_NewFuncs_Table, sizeof(NEW_DLL_FUNCTIONS));
|
memcpy(pNewFunctionTable, &g_NewFuncs_Table, sizeof(NEW_DLL_FUNCTIONS));
|
||||||
g_pNewFunctionsTable=pNewFunctionTable;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2223,7 +2212,6 @@ C_DLLEXPORT int GetNewDLLFunctions_Post( NEW_DLL_FUNCTIONS *pNewFunctionTable, i
|
|||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
memcpy(pNewFunctionTable, &g_NewFuncs_Post_Table, sizeof(NEW_DLL_FUNCTIONS));
|
memcpy(pNewFunctionTable, &g_NewFuncs_Post_Table, sizeof(NEW_DLL_FUNCTIONS));
|
||||||
g_pNewFunctionsTable_Post=pNewFunctionTable;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2418,6 +2406,9 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
|
|||||||
|
|
||||||
/************* AMXX Stuff *************/
|
/************* AMXX Stuff *************/
|
||||||
|
|
||||||
|
// *** Types ***
|
||||||
|
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
|
|
||||||
// *** Globals ***
|
// *** Globals ***
|
||||||
// Module info
|
// Module info
|
||||||
static amxx_module_info_s g_ModuleInfo =
|
static amxx_module_info_s g_ModuleInfo =
|
||||||
@ -2426,17 +2417,15 @@ static amxx_module_info_s g_ModuleInfo =
|
|||||||
MODULE_AUTHOR,
|
MODULE_AUTHOR,
|
||||||
MODULE_VERSION,
|
MODULE_VERSION,
|
||||||
#ifdef MODULE_RELOAD_ON_MAPCHANGE
|
#ifdef MODULE_RELOAD_ON_MAPCHANGE
|
||||||
1,
|
1
|
||||||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
0,
|
0
|
||||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
MODULE_LOGTAG
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Storage for the requested functions
|
// Storage for the requested functions
|
||||||
PFN_ADD_NATIVES g_fn_AddNatives;
|
PFN_ADD_NATIVES g_fn_AddNatives;
|
||||||
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||||
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
|
||||||
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||||
PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
||||||
PFN_GET_MODNAME g_fn_GetModname;
|
PFN_GET_MODNAME g_fn_GetModname;
|
||||||
@ -2450,14 +2439,11 @@ PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen;
|
|||||||
PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
||||||
PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
||||||
PFN_LOG g_fn_Log;
|
PFN_LOG g_fn_Log;
|
||||||
PFN_LOG_ERROR g_fn_LogErrorFunc;
|
|
||||||
PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
||||||
PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
||||||
PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
||||||
PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray;
|
PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray;
|
||||||
PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray;
|
PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray;
|
||||||
PFN_PREPARE_CELLARRAY_A g_fn_PrepareCellArrayA;
|
|
||||||
PFN_PREPARE_CHARARRAY_A g_fn_PrepareCharArrayA;
|
|
||||||
PFN_IS_PLAYER_VALID g_fn_IsPlayerValid;
|
PFN_IS_PLAYER_VALID g_fn_IsPlayerValid;
|
||||||
PFN_GET_PLAYER_NAME g_fn_GetPlayerName;
|
PFN_GET_PLAYER_NAME g_fn_GetPlayerName;
|
||||||
PFN_GET_PLAYER_IP g_fn_GetPlayerIP;
|
PFN_GET_PLAYER_IP g_fn_GetPlayerIP;
|
||||||
@ -2467,7 +2453,6 @@ PFN_IS_PLAYER_AUTHORIZED g_fn_IsPlayerAuthorized;
|
|||||||
PFN_GET_PLAYER_TIME g_fn_GetPlayerTime;
|
PFN_GET_PLAYER_TIME g_fn_GetPlayerTime;
|
||||||
PFN_GET_PLAYER_PLAYTIME g_fn_GetPlayerPlayTime;
|
PFN_GET_PLAYER_PLAYTIME g_fn_GetPlayerPlayTime;
|
||||||
PFN_GET_PLAYER_CURWEAPON g_fn_GetPlayerCurweapon;
|
PFN_GET_PLAYER_CURWEAPON g_fn_GetPlayerCurweapon;
|
||||||
PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
|
|
||||||
PFN_GET_PLAYER_TEAMID g_fn_GetPlayerTeamID;
|
PFN_GET_PLAYER_TEAMID g_fn_GetPlayerTeamID;
|
||||||
PFN_GET_PLAYER_DEATHS g_fn_GetPlayerDeaths;
|
PFN_GET_PLAYER_DEATHS g_fn_GetPlayerDeaths;
|
||||||
PFN_GET_PLAYER_MENU g_fn_GetPlayerMenu;
|
PFN_GET_PLAYER_MENU g_fn_GetPlayerMenu;
|
||||||
@ -2478,11 +2463,9 @@ PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting;
|
|||||||
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
||||||
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
||||||
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
PFN_ALLOCATOR g_fn_Allocator;
|
PFN_ALLOCATOR g_fn_Allocator;
|
||||||
PFN_REALLOCATOR g_fn_Reallocator;
|
PFN_REALLOCATOR g_fn_Reallocator;
|
||||||
PFN_DEALLOCATOR g_fn_Deallocator;
|
PFN_DEALLOCATOR g_fn_Deallocator;
|
||||||
#endif
|
|
||||||
PFN_AMX_EXEC g_fn_AmxExec;
|
PFN_AMX_EXEC g_fn_AmxExec;
|
||||||
PFN_AMX_EXECV g_fn_AmxExecv;
|
PFN_AMX_EXECV g_fn_AmxExecv;
|
||||||
PFN_AMX_ALLOT g_fn_AmxAllot;
|
PFN_AMX_ALLOT g_fn_AmxAllot;
|
||||||
@ -2496,12 +2479,6 @@ PFN_REGISTER_SPFORWARD_BYNAME g_fn_RegisterSPForwardByName;
|
|||||||
PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward;
|
PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward;
|
||||||
PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File;
|
PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File;
|
||||||
PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
|
PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
|
||||||
PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
|
|
||||||
PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
|
|
||||||
PFN_FORMAT g_fn_Format;
|
|
||||||
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
|
||||||
PFN_REQ_FNPTR g_fn_RequestFunction;
|
|
||||||
PFN_AMX_PUSH g_fn_AmxPush;
|
|
||||||
|
|
||||||
// *** Exports ***
|
// *** Exports ***
|
||||||
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
||||||
@ -2539,19 +2516,13 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
if (!reqFnptrFunc)
|
if (!reqFnptrFunc)
|
||||||
return AMXX_PARAM;
|
return AMXX_PARAM;
|
||||||
|
|
||||||
g_fn_RequestFunction = reqFnptrFunc;
|
|
||||||
|
|
||||||
// Req all known functions
|
// Req all known functions
|
||||||
// Misc
|
// Misc
|
||||||
REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME);
|
REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME);
|
||||||
REQFUNC("BuildPathnameR", g_fn_BuildPathnameR, PFN_BUILD_PATHNAME_R);
|
|
||||||
REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE);
|
REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE);
|
||||||
REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME);
|
REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME);
|
||||||
REQFUNC("Log", g_fn_Log, PFN_LOG);
|
REQFUNC("Log", g_fn_Log, PFN_LOG);
|
||||||
REQFUNC("LogError", g_fn_LogErrorFunc, PFN_LOG_ERROR);
|
|
||||||
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
||||||
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
|
||||||
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
|
||||||
|
|
||||||
// Amx scripts
|
// Amx scripts
|
||||||
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
||||||
@ -2559,7 +2530,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("FindAmxScriptByName", g_fn_FindAmxScriptByName, PFN_FIND_AMXSCRIPT_BYNAME);
|
REQFUNC("FindAmxScriptByName", g_fn_FindAmxScriptByName, PFN_FIND_AMXSCRIPT_BYNAME);
|
||||||
REQFUNC("LoadAmxScript", g_fn_LoadAmxScript, PFN_LOAD_AMXSCRIPT);
|
REQFUNC("LoadAmxScript", g_fn_LoadAmxScript, PFN_LOAD_AMXSCRIPT);
|
||||||
REQFUNC("UnloadAmxScript", g_fn_UnloadAmxScript, PFN_UNLOAD_AMXSCRIPT);
|
REQFUNC("UnloadAmxScript", g_fn_UnloadAmxScript, PFN_UNLOAD_AMXSCRIPT);
|
||||||
REQFUNC("GetAmxScriptName", g_fn_GetAmxScriptName, PFN_GET_AMXSCRIPTNAME);
|
|
||||||
|
|
||||||
// String / mem in amx scripts support
|
// String / mem in amx scripts support
|
||||||
REQFUNC("SetAmxString", g_fn_SetAmxString, PFN_SET_AMXSTRING);
|
REQFUNC("SetAmxString", g_fn_SetAmxString, PFN_SET_AMXSTRING);
|
||||||
@ -2585,8 +2555,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("ExecuteForward", g_fn_ExecuteForward, PFN_EXECUTE_FORWARD);
|
REQFUNC("ExecuteForward", g_fn_ExecuteForward, PFN_EXECUTE_FORWARD);
|
||||||
REQFUNC("PrepareCellArray", g_fn_PrepareCellArray, PFN_PREPARE_CELLARRAY);
|
REQFUNC("PrepareCellArray", g_fn_PrepareCellArray, PFN_PREPARE_CELLARRAY);
|
||||||
REQFUNC("PrepareCharArray", g_fn_PrepareCharArray, PFN_PREPARE_CHARARRAY);
|
REQFUNC("PrepareCharArray", g_fn_PrepareCharArray, PFN_PREPARE_CHARARRAY);
|
||||||
REQFUNC("PrepareCellArrayA", g_fn_PrepareCellArrayA, PFN_PREPARE_CELLARRAY_A);
|
|
||||||
REQFUNC("PrepareCharArrayA", g_fn_PrepareCharArrayA, PFN_PREPARE_CHARARRAY_A);
|
|
||||||
// Player
|
// Player
|
||||||
REQFUNC("IsPlayerValid", g_fn_IsPlayerValid, PFN_IS_PLAYER_VALID);
|
REQFUNC("IsPlayerValid", g_fn_IsPlayerValid, PFN_IS_PLAYER_VALID);
|
||||||
REQFUNC("GetPlayerName", g_fn_GetPlayerName, PFN_GET_PLAYER_NAME);
|
REQFUNC("GetPlayerName", g_fn_GetPlayerName, PFN_GET_PLAYER_NAME);
|
||||||
@ -2598,7 +2567,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("GetPlayerPlayTime", g_fn_GetPlayerPlayTime, PFN_GET_PLAYER_PLAYTIME);
|
REQFUNC("GetPlayerPlayTime", g_fn_GetPlayerPlayTime, PFN_GET_PLAYER_PLAYTIME);
|
||||||
REQFUNC("GetPlayerCurweapon", g_fn_GetPlayerCurweapon, PFN_GET_PLAYER_CURWEAPON);
|
REQFUNC("GetPlayerCurweapon", g_fn_GetPlayerCurweapon, PFN_GET_PLAYER_CURWEAPON);
|
||||||
REQFUNC("GetPlayerTeamID", g_fn_GetPlayerTeamID, PFN_GET_PLAYER_TEAMID);
|
REQFUNC("GetPlayerTeamID", g_fn_GetPlayerTeamID, PFN_GET_PLAYER_TEAMID);
|
||||||
REQFUNC("GetPlayerTeam",g_fn_GetPlayerTeam, PFN_GET_PLAYER_TEAM);
|
|
||||||
REQFUNC("GetPlayerDeaths", g_fn_GetPlayerDeaths, PFN_GET_PLAYER_DEATHS);
|
REQFUNC("GetPlayerDeaths", g_fn_GetPlayerDeaths, PFN_GET_PLAYER_DEATHS);
|
||||||
REQFUNC("GetPlayerMenu", g_fn_GetPlayerMenu, PFN_GET_PLAYER_MENU);
|
REQFUNC("GetPlayerMenu", g_fn_GetPlayerMenu, PFN_GET_PLAYER_MENU);
|
||||||
REQFUNC("GetPlayerKeys", g_fn_GetPlayerKeys, PFN_GET_PLAYER_KEYS);
|
REQFUNC("GetPlayerKeys", g_fn_GetPlayerKeys, PFN_GET_PLAYER_KEYS);
|
||||||
@ -2608,16 +2576,11 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("IsPlayerHLTV", g_fn_IsPlayerHLTV, PFN_IS_PLAYER_HLTV);
|
REQFUNC("IsPlayerHLTV", g_fn_IsPlayerHLTV, PFN_IS_PLAYER_HLTV);
|
||||||
REQFUNC("GetPlayerArmor", g_fn_GetPlayerArmor, PFN_GET_PLAYER_ARMOR);
|
REQFUNC("GetPlayerArmor", g_fn_GetPlayerArmor, PFN_GET_PLAYER_ARMOR);
|
||||||
REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH);
|
REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH);
|
||||||
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
|
|
||||||
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
|
|
||||||
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
// Memory
|
// Memory
|
||||||
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
||||||
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
|
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
|
||||||
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
|
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
|
||||||
#endif
|
|
||||||
|
|
||||||
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
|
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
|
||||||
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
|
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
|
||||||
@ -2656,19 +2619,7 @@ void MF_Log(const char *fmt, ...)
|
|||||||
vsprintf(msg, fmt, arglst);
|
vsprintf(msg, fmt, arglst);
|
||||||
va_end(arglst);
|
va_end(arglst);
|
||||||
|
|
||||||
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
g_fn_Log("[%s] %s", MODULE_NAME, msg);
|
||||||
}
|
|
||||||
|
|
||||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
// :TODO: Overflow possible here
|
|
||||||
char msg[3072];
|
|
||||||
va_list arglst;
|
|
||||||
va_start(arglst, fmt);
|
|
||||||
vsprintf(msg, fmt, arglst);
|
|
||||||
va_end(arglst);
|
|
||||||
|
|
||||||
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2678,7 +2629,6 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
|||||||
void ValidateMacros_DontCallThis_Smiley()
|
void ValidateMacros_DontCallThis_Smiley()
|
||||||
{
|
{
|
||||||
MF_BuildPathname("str", "str", 0);
|
MF_BuildPathname("str", "str", 0);
|
||||||
MF_BuildPathnameR(NULL, 0, "%d", 0);
|
|
||||||
MF_FormatAmxString(NULL, 0, 0, NULL);
|
MF_FormatAmxString(NULL, 0, 0, NULL);
|
||||||
MF_GetAmxAddr(NULL, 0);
|
MF_GetAmxAddr(NULL, 0);
|
||||||
MF_PrintSrvConsole("str", "str", 0);
|
MF_PrintSrvConsole("str", "str", 0);
|
||||||
@ -2692,14 +2642,11 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||||||
MF_GetAmxStringLen(NULL);
|
MF_GetAmxStringLen(NULL);
|
||||||
MF_CopyAmxMemory(NULL, NULL, 0);
|
MF_CopyAmxMemory(NULL, NULL, 0);
|
||||||
MF_Log("str", "str", 0);
|
MF_Log("str", "str", 0);
|
||||||
MF_LogError(NULL, 0, NULL);
|
|
||||||
MF_RaiseAmxError(NULL, 0);
|
MF_RaiseAmxError(NULL, 0);
|
||||||
MF_RegisterForward("str", (ForwardExecType)0, 0, 0, 0);
|
MF_RegisterForward("str", (ForwardExecType)0, 0, 0, 0);
|
||||||
MF_ExecuteForward(0, 0, 0);
|
MF_ExecuteForward(0, 0, 0);
|
||||||
MF_PrepareCellArray(NULL, 0);
|
MF_PrepareCellArray(NULL, 0);
|
||||||
MF_PrepareCharArray(NULL, 0);
|
MF_PrepareCharArray(NULL, 0);
|
||||||
MF_PrepareCellArrayA(NULL, 0, true);
|
|
||||||
MF_PrepareCharArrayA(NULL, 0, true);
|
|
||||||
MF_IsPlayerValid(0);
|
MF_IsPlayerValid(0);
|
||||||
MF_GetPlayerName(0);
|
MF_GetPlayerName(0);
|
||||||
MF_GetPlayerIP(0);
|
MF_GetPlayerIP(0);
|
||||||
@ -2710,7 +2657,6 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||||||
MF_GetPlayerPlayTime(0);
|
MF_GetPlayerPlayTime(0);
|
||||||
MF_GetPlayerCurweapon(0);
|
MF_GetPlayerCurweapon(0);
|
||||||
MF_GetPlayerTeamID(0);
|
MF_GetPlayerTeamID(0);
|
||||||
MF_GetPlayerTeam(0);
|
|
||||||
MF_GetPlayerDeaths(0);
|
MF_GetPlayerDeaths(0);
|
||||||
MF_GetPlayerMenu(0);
|
MF_GetPlayerMenu(0);
|
||||||
MF_GetPlayerKeys(0);
|
MF_GetPlayerKeys(0);
|
||||||
@ -2720,24 +2666,18 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||||||
MF_IsPlayerHLTV(0);
|
MF_IsPlayerHLTV(0);
|
||||||
MF_GetPlayerArmor(0);
|
MF_GetPlayerArmor(0);
|
||||||
MF_GetPlayerHealth(0);
|
MF_GetPlayerHealth(0);
|
||||||
MF_AmxExec(0, 0, 0);
|
MF_AmxExec(0, 0, 0, 0);
|
||||||
MF_AmxExecv(0, 0, 0, 0, 0);
|
MF_AmxExecv(0, 0, 0, 0, 0);
|
||||||
MF_AmxFindPublic(0, 0, 0);
|
MF_AmxFindPublic(0, 0, 0);
|
||||||
MF_AmxAllot(0, 0, 0, 0);
|
MF_AmxAllot(0, 0, 0, 0);
|
||||||
MF_LoadAmxScript(0, 0, 0, 0, 0);
|
MF_LoadAmxScript(0, 0, 0, 0);
|
||||||
MF_UnloadAmxScript(0, 0);
|
MF_UnloadAmxScript(0, 0);
|
||||||
MF_RegisterSPForward(0, 0, 0, 0, 0, 0);
|
MF_RegisterSPForward(0, 0, 0, 0, 0, 0);
|
||||||
MF_RegisterSPForwardByName(0, 0, 0, 0, 0, 0);
|
MF_RegisterSPForwardByName(0, 0, 0, 0, 0, 0);
|
||||||
MF_UnregisterSPForward(0);
|
MF_UnregisterSPForward(0);
|
||||||
MF_GetPlayerFrags(0);
|
|
||||||
MF_GetPlayerEdict(0);
|
|
||||||
MF_Format("", 4, "str");
|
|
||||||
MF_RegisterFunction(NULL, "");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
|
|
||||||
/************* MEMORY *************/
|
/************* MEMORY *************/
|
||||||
// undef all defined macros
|
// undef all defined macros
|
||||||
#undef new
|
#undef new
|
||||||
@ -2851,7 +2791,7 @@ void *operator new(size_t reportedSize)
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
// allocation failed
|
// allocation failed
|
||||||
return NULL;
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new[](size_t reportedSize)
|
void *operator new[](size_t reportedSize)
|
||||||
@ -2864,7 +2804,7 @@ void *operator new[](size_t reportedSize)
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
// allocation failed
|
// allocation failed
|
||||||
return NULL;
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Microsoft memory tracking operators
|
// Microsoft memory tracking operators
|
||||||
@ -2878,7 +2818,7 @@ void *operator new(size_t reportedSize, const char *sourceFile, int sourceLine)
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
// allocation failed
|
// allocation failed
|
||||||
return NULL;
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine)
|
void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine)
|
||||||
{
|
{
|
||||||
@ -2890,7 +2830,7 @@ void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine
|
|||||||
return ptr;
|
return ptr;
|
||||||
|
|
||||||
// allocation failed
|
// allocation failed
|
||||||
return NULL;
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void *reportedAddress)
|
void operator delete(void *reportedAddress)
|
||||||
@ -2909,30 +2849,6 @@ void operator delete[](void *reportedAddress)
|
|||||||
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
|
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
|
|
||||||
void * ::operator new(size_t size) {
|
|
||||||
return(calloc(1, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void * ::operator new[](size_t size) {
|
|
||||||
return(calloc(1, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ::operator delete(void * ptr) {
|
|
||||||
if(ptr)
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ::operator delete[](void * ptr) {
|
|
||||||
if(ptr)
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //MEMORY_TEST
|
|
||||||
|
|
||||||
/************* stuff from dlls/util.cpp *************/
|
/************* stuff from dlls/util.cpp *************/
|
||||||
// must come here because cbase.h declares it's own operator new
|
// must come here because cbase.h declares it's own operator new
|
||||||
|
|
||||||
|
@ -31,10 +31,8 @@
|
|||||||
|
|
||||||
// ***** AMXX stuff *****
|
// ***** AMXX stuff *****
|
||||||
|
|
||||||
// module interface version was 1
|
// module interface version is 1
|
||||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
#define AMXX_INTERFACE_VERSION 1
|
||||||
// 3 - added new tagAMX structure (amxx1.5)
|
|
||||||
#define AMXX_INTERFACE_VERSION 3
|
|
||||||
|
|
||||||
// amxx module info
|
// amxx module info
|
||||||
struct amxx_module_info_s
|
struct amxx_module_info_s
|
||||||
@ -43,9 +41,10 @@ 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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return values from functions called by amxx
|
// return values from functions called by amxx
|
||||||
#define AMXX_OK 0 /* no error */
|
#define AMXX_OK 0 /* no error */
|
||||||
#define AMXX_IFVERS 1 /* interface version */
|
#define AMXX_IFVERS 1 /* interface version */
|
||||||
@ -54,26 +53,15 @@ struct amxx_module_info_s
|
|||||||
|
|
||||||
// *** Small stuff ***
|
// *** Small stuff ***
|
||||||
// The next section is copied from the amx.h file
|
// The next section is copied from the amx.h file
|
||||||
// Copyright (c) ITB CompuPhase, 1997-2005
|
// Copyright (c) ITB CompuPhase, 1997-2004
|
||||||
|
|
||||||
#if defined HAVE_STDINT_H
|
#if defined __LCC__ || defined __DMC__ || defined __linux__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#else
|
|
||||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
|
||||||
#if defined HAVE_INTTYPES_H
|
|
||||||
#include <inttypes.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||||
* here, these types are probably undefined.
|
* here, these types are probably undefined.
|
||||||
*/
|
*/
|
||||||
#if defined __MACH__
|
#if defined __FreeBSD__
|
||||||
#include <ppc/types.h>
|
|
||||||
typedef unsigned short int uint16_t;
|
|
||||||
typedef unsigned long int uint32_t;
|
|
||||||
#elif defined __FreeBSD__
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#else
|
#else
|
||||||
typedef short int int16_t;
|
typedef short int int16_t;
|
||||||
@ -96,13 +84,7 @@ struct amxx_module_info_s
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
|
||||||
#if !defined __64BIT__
|
|
||||||
#define __64BIT__
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* calling convention for native functions */
|
/* calling convention for native functions */
|
||||||
#if !defined AMX_NATIVE_CALL
|
#if !defined AMX_NATIVE_CALL
|
||||||
@ -122,26 +104,24 @@ struct amxx_module_info_s
|
|||||||
#define AMXEXPORT
|
#define AMXEXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined PAWN_CELL_SIZE
|
|
||||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
|
||||||
|
#if !defined SMALL_CELL_SIZE
|
||||||
|
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||||
#endif
|
#endif
|
||||||
#if PAWN_CELL_SIZE==16
|
#if SMALL_CELL_SIZE==32
|
||||||
typedef uint16_t ucell;
|
|
||||||
typedef int16_t cell;
|
|
||||||
#elif PAWN_CELL_SIZE==32
|
|
||||||
typedef uint32_t ucell;
|
typedef uint32_t ucell;
|
||||||
typedef int32_t cell;
|
typedef int32_t cell;
|
||||||
#define REAL float
|
typedef float REAL;
|
||||||
#elif PAWN_CELL_SIZE==64
|
#elif SMALL_CELL_SIZE==64
|
||||||
typedef uint64_t ucell;
|
typedef uint64_t ucell;
|
||||||
typedef int64_t cell;
|
typedef int64_t cell;
|
||||||
#define REAL double
|
typedef double REAL;
|
||||||
#else
|
#else
|
||||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
#error Unsupported cell size (SMALL_CELL_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
|
||||||
#define UNLIMITED (~1u >> 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);
|
||||||
@ -159,24 +139,21 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
|
||||||
*/
|
|
||||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
|
||||||
#define AMX_NO_ALIGN
|
#define AMX_NO_ALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined __GNUC__
|
#if defined __GNUC__
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKED __attribute__((packed))
|
||||||
#else
|
#else
|
||||||
#define PACKED
|
#define PACKED
|
||||||
#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) */
|
||||||
@ -197,7 +174,7 @@ typedef struct {
|
|||||||
* 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 */
|
||||||
@ -209,25 +186,30 @@ 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 */
|
||||||
long 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
|
|
||||||
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 */
|
||||||
|
#if defined JIT
|
||||||
/* 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;
|
#endif
|
||||||
|
} AMX;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AMX_ERR_NONE,
|
AMX_ERR_NONE,
|
||||||
@ -244,7 +226,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_MEMORY = 16, /* out of memory */
|
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||||
AMX_ERR_FORMAT, /* invalid file format */
|
AMX_ERR_FORMAT, /* invalid file format */
|
||||||
@ -259,14 +240,6 @@ enum {
|
|||||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined AMX_NO_ALIGN
|
|
||||||
#if defined __linux__
|
|
||||||
#pragma pack() /* reset default packing */
|
|
||||||
#else
|
|
||||||
#pragma pack(pop) /* reset previous packing */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***** declare functions *****
|
// ***** declare functions *****
|
||||||
|
|
||||||
@ -950,7 +923,7 @@ void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
|
|||||||
#endif // FN_EngineFprintf
|
#endif // FN_EngineFprintf
|
||||||
|
|
||||||
#ifdef FN_PvAllocEntPrivateData
|
#ifdef FN_PvAllocEntPrivateData
|
||||||
void *FN_PvAllocEntPrivateData(edict_t *pEdict, int32 cb);
|
void *FN_PvAllocEntPrivateData(edict_t *pEdict, long cb);
|
||||||
#endif // FN_PvAllocEntPrivateData
|
#endif // FN_PvAllocEntPrivateData
|
||||||
|
|
||||||
#ifdef FN_PvEntPrivateData
|
#ifdef FN_PvEntPrivateData
|
||||||
@ -1904,9 +1877,6 @@ void FN_AMXX_DETACH(void);
|
|||||||
void FN_AMXX_PLUGINSLOADED(void);
|
void FN_AMXX_PLUGINSLOADED(void);
|
||||||
#endif // FN_AMXX_PLUGINSLOADED
|
#endif // FN_AMXX_PLUGINSLOADED
|
||||||
|
|
||||||
// *** Types ***
|
|
||||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
|
||||||
|
|
||||||
// ***** Module funcs stuff *****
|
// ***** Module funcs stuff *****
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
{
|
{
|
||||||
@ -1930,7 +1900,6 @@ enum ForwardParam
|
|||||||
|
|
||||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||||
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
||||||
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
|
||||||
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
||||||
typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...);
|
typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...);
|
||||||
typedef const char * (*PFN_GET_MODNAME) (void);
|
typedef const char * (*PFN_GET_MODNAME) (void);
|
||||||
@ -1944,14 +1913,11 @@ typedef int (*PFN_GET_AMXSTRINGLEN) (const cell *ptr);
|
|||||||
typedef char * (*PFN_FORMAT_AMXSTRING) (AMX * /*amx*/, cell * /*params*/, int /*startParam*/, int * /*pLen*/);
|
typedef char * (*PFN_FORMAT_AMXSTRING) (AMX * /*amx*/, cell * /*params*/, int /*startParam*/, int * /*pLen*/);
|
||||||
typedef void (*PFN_COPY_AMXMEMORY) (cell * /*dest*/, const cell * /*src*/, int /*len*/);
|
typedef void (*PFN_COPY_AMXMEMORY) (cell * /*dest*/, const cell * /*src*/, int /*len*/);
|
||||||
typedef void (*PFN_LOG) (const char * /*fmt*/, ...);
|
typedef void (*PFN_LOG) (const char * /*fmt*/, ...);
|
||||||
typedef void (*PFN_LOG_ERROR) (AMX * /*amx*/, int /*err*/, const char * /*fmt*/, ...);
|
|
||||||
typedef int (*PFN_RAISE_AMXERROR) (AMX * /*amx*/, int /*error*/);
|
typedef int (*PFN_RAISE_AMXERROR) (AMX * /*amx*/, int /*error*/);
|
||||||
typedef int (*PFN_REGISTER_FORWARD) (const char * /*funcname*/, ForwardExecType /*exectype*/, ... /*paramtypes terminated by PF_DONE*/);
|
typedef int (*PFN_REGISTER_FORWARD) (const char * /*funcname*/, ForwardExecType /*exectype*/, ... /*paramtypes terminated by PF_DONE*/);
|
||||||
typedef int (*PFN_EXECUTE_FORWARD) (int /*id*/, ... /*params*/);
|
typedef int (*PFN_EXECUTE_FORWARD) (int /*id*/, ... /*params*/);
|
||||||
typedef cell (*PFN_PREPARE_CELLARRAY) (cell * /*ptr*/, unsigned int /*size*/);
|
typedef cell (*PFN_PREPARE_CELLARRAY) (cell * /*ptr*/, unsigned int /*size*/);
|
||||||
typedef cell (*PFN_PREPARE_CHARARRAY) (char * /*ptr*/, unsigned int /*size*/);
|
typedef cell (*PFN_PREPARE_CHARARRAY) (char * /*ptr*/, unsigned int /*size*/);
|
||||||
typedef cell (*PFN_PREPARE_CELLARRAY_A) (cell * /*ptr*/, unsigned int /*size*/, bool /*copyBack*/);
|
|
||||||
typedef cell (*PFN_PREPARE_CHARARRAY_A) (char * /*ptr*/, unsigned int /*size*/, bool /*copyBack*/);
|
|
||||||
typedef int (*PFN_IS_PLAYER_VALID) (int /*id*/);
|
typedef int (*PFN_IS_PLAYER_VALID) (int /*id*/);
|
||||||
typedef const char * (*PFN_GET_PLAYER_NAME) (int /*id*/);
|
typedef const char * (*PFN_GET_PLAYER_NAME) (int /*id*/);
|
||||||
typedef const char * (*PFN_GET_PLAYER_IP) (int /*id*/);
|
typedef const char * (*PFN_GET_PLAYER_IP) (int /*id*/);
|
||||||
@ -1960,9 +1926,7 @@ typedef int (*PFN_IS_PLAYER_BOT) (int /*id*/);
|
|||||||
typedef int (*PFN_IS_PLAYER_AUTHORIZED) (int /*id*/);
|
typedef int (*PFN_IS_PLAYER_AUTHORIZED) (int /*id*/);
|
||||||
typedef float (*PFN_GET_PLAYER_TIME) (int /*id*/);
|
typedef float (*PFN_GET_PLAYER_TIME) (int /*id*/);
|
||||||
typedef float (*PFN_GET_PLAYER_PLAYTIME) (int /*id*/);
|
typedef float (*PFN_GET_PLAYER_PLAYTIME) (int /*id*/);
|
||||||
typedef int (*PFN_GETPLAYERFLAGS) (int /* id*/);
|
|
||||||
typedef int (*PFN_GET_PLAYER_CURWEAPON) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_CURWEAPON) (int /*id*/);
|
||||||
typedef const char * (*PFN_GET_PLAYER_TEAM) (int /*id*/);
|
|
||||||
typedef int (*PFN_GET_PLAYER_TEAMID) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_TEAMID) (int /*id*/);
|
||||||
typedef int (*PFN_GET_PLAYER_DEATHS) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_DEATHS) (int /*id*/);
|
||||||
typedef int (*PFN_GET_PLAYER_MENU) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_MENU) (int /*id*/);
|
||||||
@ -1973,26 +1937,18 @@ typedef int (*PFN_IS_PLAYER_CONNECTING) (int /*id*/);
|
|||||||
typedef int (*PFN_IS_PLAYER_HLTV) (int /*id*/);
|
typedef int (*PFN_IS_PLAYER_HLTV) (int /*id*/);
|
||||||
typedef int (*PFN_GET_PLAYER_ARMOR) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_ARMOR) (int /*id*/);
|
||||||
typedef int (*PFN_GET_PLAYER_HEALTH) (int /*id*/);
|
typedef int (*PFN_GET_PLAYER_HEALTH) (int /*id*/);
|
||||||
#ifdef USE_METAMOD
|
|
||||||
typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
|
||||||
#else
|
|
||||||
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const size_t /*size*/);
|
const unsigned int /*type*/, const size_t /*size*/);
|
||||||
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
|
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
|
||||||
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||||
const unsigned int /*type*/, const void* /*addr*/ );
|
const unsigned int /*type*/, const void* /*addr*/ );
|
||||||
#endif
|
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, ... /*params*/);
|
||||||
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
|
|
||||||
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
||||||
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
||||||
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
||||||
typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
||||||
typedef int (*PFN_LOAD_AMXSCRIPT) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char[64] /*error info*/, int /* debug */);
|
typedef int (*PFN_LOAD_AMXSCRIPT) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char[64] /*error info*/);
|
||||||
typedef int (*PFN_UNLOAD_AMXSCRIPT) (AMX* /*amx*/,void** /*code*/);
|
typedef int (*PFN_UNLOAD_AMXSCRIPT) (AMX* /*amx*/,void** /*code*/);
|
||||||
typedef cell (*PFN_REAL_TO_CELL) (REAL /*x*/);
|
typedef cell (*PFN_REAL_TO_CELL) (REAL /*x*/);
|
||||||
typedef REAL (*PFN_CELL_TO_REAL) (cell /*x*/);
|
typedef REAL (*PFN_CELL_TO_REAL) (cell /*x*/);
|
||||||
@ -2000,13 +1956,9 @@ typedef int (*PFN_REGISTER_SPFORWARD) (AMX * /*amx*/, int /*func*/, ... /*pa
|
|||||||
typedef int (*PFN_REGISTER_SPFORWARD_BYNAME) (AMX * /*amx*/, const char * /*funcName*/, ... /*params*/);
|
typedef int (*PFN_REGISTER_SPFORWARD_BYNAME) (AMX * /*amx*/, const char * /*funcName*/, ... /*params*/);
|
||||||
typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/);
|
typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/);
|
||||||
typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
|
typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
|
||||||
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
|
||||||
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
|
||||||
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
|
||||||
|
|
||||||
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
||||||
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||||
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
|
||||||
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||||
extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
|
||||||
extern PFN_GET_MODNAME g_fn_GetModname;
|
extern PFN_GET_MODNAME g_fn_GetModname;
|
||||||
@ -2020,14 +1972,11 @@ extern PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen;
|
|||||||
extern PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
extern PFN_FORMAT_AMXSTRING g_fn_FormatAmxString;
|
||||||
extern PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
extern PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory;
|
||||||
extern PFN_LOG g_fn_Log;
|
extern PFN_LOG g_fn_Log;
|
||||||
extern PFN_LOG_ERROR g_fn_LogErrorFunc;
|
|
||||||
extern PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
extern PFN_RAISE_AMXERROR g_fn_RaiseAmxError;
|
||||||
extern PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
extern PFN_REGISTER_FORWARD g_fn_RegisterForward;
|
||||||
extern PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
extern PFN_EXECUTE_FORWARD g_fn_ExecuteForward;
|
||||||
extern PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray;
|
extern PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray;
|
||||||
extern PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray;
|
extern PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray;
|
||||||
extern PFN_PREPARE_CELLARRAY_A g_fn_PrepareCellArrayA;
|
|
||||||
extern PFN_PREPARE_CHARARRAY_A g_fn_PrepareCharArrayA;
|
|
||||||
extern PFN_IS_PLAYER_VALID g_fn_IsPlayerValid;
|
extern PFN_IS_PLAYER_VALID g_fn_IsPlayerValid;
|
||||||
extern PFN_GET_PLAYER_NAME g_fn_GetPlayerName;
|
extern PFN_GET_PLAYER_NAME g_fn_GetPlayerName;
|
||||||
extern PFN_GET_PLAYER_IP g_fn_GetPlayerIP;
|
extern PFN_GET_PLAYER_IP g_fn_GetPlayerIP;
|
||||||
@ -2048,6 +1997,7 @@ extern PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
|
|||||||
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
|
||||||
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
|
||||||
extern PFN_AMX_EXEC g_fn_AmxExec;
|
extern PFN_AMX_EXEC g_fn_AmxExec;
|
||||||
|
extern PFN_AMX_EXECV g_fn_AmxExecv;
|
||||||
extern PFN_AMX_ALLOT g_fn_AmxAllot;
|
extern PFN_AMX_ALLOT g_fn_AmxAllot;
|
||||||
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
|
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
|
||||||
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
|
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
|
||||||
@ -2059,20 +2009,12 @@ extern PFN_REGISTER_SPFORWARD_BYNAME g_fn_RegisterSPForwardByName;
|
|||||||
extern PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward;
|
extern PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward;
|
||||||
extern PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File;
|
extern PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File;
|
||||||
extern PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
|
extern PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
|
||||||
extern PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
|
|
||||||
extern PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
|
|
||||||
extern PFN_FORMAT g_fn_Format;
|
|
||||||
extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
|
|
||||||
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
|
||||||
extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
|
||||||
extern PFN_AMX_PUSH g_fn_AmxPush;
|
|
||||||
|
|
||||||
#ifdef MAY_NEVER_BE_DEFINED
|
#ifdef MAY_NEVER_BE_DEFINED
|
||||||
// Function prototypes for intellisense and similar systems
|
// Function prototypes for intellisense and similar systems
|
||||||
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
||||||
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
||||||
char * MF_BuildPathname (const char * format, ...) { }
|
char * MF_BuildPathname (const char * format, ...) { }
|
||||||
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
|
||||||
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
||||||
void MF_PrintSrvConsole (char * format, ...) { }
|
void MF_PrintSrvConsole (char * format, ...) { }
|
||||||
const char * MF_GetModname (void) { }
|
const char * MF_GetModname (void) { }
|
||||||
@ -2086,14 +2028,11 @@ int MF_GetAmxStringLen (const cell *ptr) { }
|
|||||||
char * MF_FormatAmxString (AMX * amx, cell * params, int startParam, int * pLen) { }
|
char * MF_FormatAmxString (AMX * amx, cell * params, int startParam, int * pLen) { }
|
||||||
void MF_CopyAmxMemory (cell * dest, const cell * src, int len) { }
|
void MF_CopyAmxMemory (cell * dest, const cell * src, int len) { }
|
||||||
void MF_Log (const char * fmt, ...) { }
|
void MF_Log (const char * fmt, ...) { }
|
||||||
void MF_LogError (AMX * amx, int err, const char *fmt, ...) { }
|
|
||||||
int MF_RaiseAmxError (AMX * amx, int error) { }
|
int MF_RaiseAmxError (AMX * amx, int error) { }
|
||||||
int MF_RegisterForward (const char * funcname, ForwardExecType exectype, ...) { }
|
int MF_RegisterForward (const char * funcname, ForwardExecType exectype, ...) { }
|
||||||
int MF_ExecuteForward (int id, ...) { }
|
int MF_ExecuteForward (int id, ...) { }
|
||||||
cell MF_PrepareCellArray (cell * ptr, unsigned int size) { }
|
cell MF_PrepareCellArray (cell * ptr, unsigned int size) { }
|
||||||
cell MF_PrepareCharArray (char * ptr, unsigned int size) { }
|
cell MF_PrepareCharArray (char * ptr, unsigned int size) { }
|
||||||
cell MF_PrepareCellArrayA (cell * ptr, unsigned int size, bool copyBack) { }
|
|
||||||
cell MF_PrepareCharArrayA (char * ptr, unsigned int size, bool copyBack) { }
|
|
||||||
int MF_IsPlayerValid (int id) { }
|
int MF_IsPlayerValid (int id) { }
|
||||||
const char * MF_GetPlayerName (int id) { }
|
const char * MF_GetPlayerName (int id) { }
|
||||||
const char * MF_GetPlayerIP (int id) { }
|
const char * MF_GetPlayerIP (int id) { }
|
||||||
@ -2103,7 +2042,6 @@ int MF_IsPlayerAuthorized (int id) { }
|
|||||||
float MF_GetPlayerTime (int id) { }
|
float MF_GetPlayerTime (int id) { }
|
||||||
float MF_GetPlayerPlayTime (int id) { }
|
float MF_GetPlayerPlayTime (int id) { }
|
||||||
int MF_GetPlayerCurweapon (int id) { }
|
int MF_GetPlayerCurweapon (int id) { }
|
||||||
const char * MF_GetPlayerTeam (int id) { }
|
|
||||||
int MF_GetPlayerTeamID (int id) { }
|
int MF_GetPlayerTeamID (int id) { }
|
||||||
int MF_GetPlayerDeaths (int id) { }
|
int MF_GetPlayerDeaths (int id) { }
|
||||||
int MF_GetPlayerMenu (int id) { }
|
int MF_GetPlayerMenu (int id) { }
|
||||||
@ -2119,18 +2057,10 @@ cell amx_ftoc (float x) { }
|
|||||||
int MF_RegisterSPForwardByName (AMX * amx, const char *str, ...) { }
|
int MF_RegisterSPForwardByName (AMX * amx, const char *str, ...) { }
|
||||||
int MF_RegisterSPForward (AMX * amx, int func, ...) { }
|
int MF_RegisterSPForward (AMX * amx, int func, ...) { }
|
||||||
void MF_UnregisterSPForward (int id) { }
|
void MF_UnregisterSPForward (int id) { }
|
||||||
int MF_GetPlayerFlags (int id) { }
|
|
||||||
edict_t* MF_GetPlayerEdict (int id) { }
|
|
||||||
const char * MF_Format (const char *fmt, ...) { }
|
|
||||||
void MF_RegisterFunction (void *pfn, const char *description) { }
|
|
||||||
void * MF_RequestFunction (const char *description) { }
|
|
||||||
int MF_AmxPush (AMX *amx, cell *params) { }
|
|
||||||
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
|
||||||
#endif // MAY_NEVER_BE_DEFINED
|
#endif // MAY_NEVER_BE_DEFINED
|
||||||
|
|
||||||
#define MF_AddNatives g_fn_AddNatives
|
#define MF_AddNatives g_fn_AddNatives
|
||||||
#define MF_BuildPathname g_fn_BuildPathname
|
#define MF_BuildPathname g_fn_BuildPathname
|
||||||
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
|
||||||
#define MF_FormatAmxString g_fn_FormatAmxString
|
#define MF_FormatAmxString g_fn_FormatAmxString
|
||||||
#define MF_GetAmxAddr g_fn_GetAmxAddr
|
#define MF_GetAmxAddr g_fn_GetAmxAddr
|
||||||
#define MF_PrintSrvConsole g_fn_PrintSrvConsole
|
#define MF_PrintSrvConsole g_fn_PrintSrvConsole
|
||||||
@ -2144,14 +2074,11 @@ int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
|||||||
#define MF_GetAmxStringLen g_fn_GetAmxStringLen
|
#define MF_GetAmxStringLen g_fn_GetAmxStringLen
|
||||||
#define MF_CopyAmxMemory g_fn_CopyAmxMemory
|
#define MF_CopyAmxMemory g_fn_CopyAmxMemory
|
||||||
void MF_Log(const char *fmt, ...);
|
void MF_Log(const char *fmt, ...);
|
||||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|
||||||
#define MF_RaiseAmxError g_fn_RaiseAmxError
|
#define MF_RaiseAmxError g_fn_RaiseAmxError
|
||||||
#define MF_RegisterForward g_fn_RegisterForward
|
#define MF_RegisterForward g_fn_RegisterForward
|
||||||
#define MF_ExecuteForward g_fn_ExecuteForward
|
#define MF_ExecuteForward g_fn_ExecuteForward
|
||||||
#define MF_PrepareCellArray g_fn_PrepareCellArray
|
#define MF_PrepareCellArray g_fn_PrepareCellArray
|
||||||
#define MF_PrepareCharArray g_fn_PrepareCharArray
|
#define MF_PrepareCharArray g_fn_PrepareCharArray
|
||||||
#define MF_PrepareCellArrayA g_fn_PrepareCellArrayA
|
|
||||||
#define MF_PrepareCharArrayA g_fn_PrepareCharArrayA
|
|
||||||
#define MF_IsPlayerValid g_fn_IsPlayerValid
|
#define MF_IsPlayerValid g_fn_IsPlayerValid
|
||||||
#define MF_GetPlayerName g_fn_GetPlayerName
|
#define MF_GetPlayerName g_fn_GetPlayerName
|
||||||
#define MF_GetPlayerIP g_fn_GetPlayerIP
|
#define MF_GetPlayerIP g_fn_GetPlayerIP
|
||||||
@ -2161,7 +2088,6 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|||||||
#define MF_GetPlayerTime g_fn_GetPlayerTime
|
#define MF_GetPlayerTime g_fn_GetPlayerTime
|
||||||
#define MF_GetPlayerPlayTime g_fn_GetPlayerPlayTime
|
#define MF_GetPlayerPlayTime g_fn_GetPlayerPlayTime
|
||||||
#define MF_GetPlayerCurweapon g_fn_GetPlayerCurweapon
|
#define MF_GetPlayerCurweapon g_fn_GetPlayerCurweapon
|
||||||
#define MF_GetPlayerTeam g_fn_GetPlayerTeam
|
|
||||||
#define MF_GetPlayerTeamID g_fn_GetPlayerTeamID
|
#define MF_GetPlayerTeamID g_fn_GetPlayerTeamID
|
||||||
#define MF_GetPlayerDeaths g_fn_GetPlayerDeaths
|
#define MF_GetPlayerDeaths g_fn_GetPlayerDeaths
|
||||||
#define MF_GetPlayerMenu g_fn_GetPlayerMenu
|
#define MF_GetPlayerMenu g_fn_GetPlayerMenu
|
||||||
@ -2185,14 +2111,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|||||||
#define MF_RegisterSPForwardByName g_fn_RegisterSPForwardByName
|
#define MF_RegisterSPForwardByName g_fn_RegisterSPForwardByName
|
||||||
#define MF_RegisterSPForward g_fn_RegisterSPForward
|
#define MF_RegisterSPForward g_fn_RegisterSPForward
|
||||||
#define MF_UnregisterSPForward g_fn_UnregisterSPForward
|
#define MF_UnregisterSPForward g_fn_UnregisterSPForward
|
||||||
#define MF_GetPlayerFlags g_fn_GetPlayerFlags
|
|
||||||
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
|
||||||
#define MF_Format g_fn_Format
|
|
||||||
#define MF_RegisterFunction g_fn_RegisterFunction
|
|
||||||
#define MF_RequestFunction g_fn_RequestFunction;
|
|
||||||
#define MF_AmxPush g_fn_AmxPush
|
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
|
||||||
/*** Memory ***/
|
/*** Memory ***/
|
||||||
void *operator new(size_t reportedSize);
|
void *operator new(size_t reportedSize);
|
||||||
void *operator new[](size_t reportedSize);
|
void *operator new[](size_t reportedSize);
|
||||||
@ -2236,6 +2155,4 @@ void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, cons
|
|||||||
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
|
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
|
||||||
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
|
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
|
||||||
|
|
||||||
#endif //MEMORY_TEST
|
|
||||||
|
|
||||||
#endif // #ifndef __AMXXMODULE_H__
|
#endif // #ifndef __AMXXMODULE_H__
|
||||||
|
@ -21,16 +21,6 @@
|
|||||||
// metamod plugin?
|
// metamod plugin?
|
||||||
// #define USE_METAMOD
|
// #define USE_METAMOD
|
||||||
|
|
||||||
// use memory manager/tester?
|
|
||||||
// note that if you use this, you cannot construct/allocate
|
|
||||||
// anything before the module attached (OnAmxxAttach).
|
|
||||||
// be careful of default constructors using new/malloc!
|
|
||||||
// #define MEMORY_TEST
|
|
||||||
|
|
||||||
// Unless you use STL or exceptions, keep this commented.
|
|
||||||
// It allows you to compile without libstdc++.so as a dependency
|
|
||||||
// #define NO_ALLOC_OVERRIDES
|
|
||||||
|
|
||||||
// - AMXX Init functions
|
// - AMXX Init functions
|
||||||
// Also consider using FN_META_*
|
// Also consider using FN_META_*
|
||||||
// AMXX query
|
// AMXX query
|
||||||
|
@ -31,44 +31,39 @@
|
|||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
void amx_command()
|
void amx_command(){
|
||||||
{
|
|
||||||
const char* cmd = CMD_ARGV(1);
|
const char* cmd = CMD_ARGV(1);
|
||||||
|
|
||||||
if (!strcmp(cmd,"plugins") || !strcmp(cmd,"list"))
|
if (!strcmp(cmd,"plugins") || !strcmp(cmd,"list"))
|
||||||
{
|
{
|
||||||
|
|
||||||
print_srvconsole( "Currently loaded plugins:\n");
|
print_srvconsole( "Currently loaded plugins:\n");
|
||||||
print_srvconsole(" %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status");
|
print_srvconsole( " %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
|
||||||
|
"name","version","author","file","status");
|
||||||
|
|
||||||
int plugins = 0;
|
int plugins = 0;
|
||||||
int running = 0;
|
int running = 0;
|
||||||
|
|
||||||
|
|
||||||
CPluginMngr::iterator a = g_plugins.begin();
|
CPluginMngr::iterator a = g_plugins.begin();
|
||||||
|
|
||||||
while (a)
|
while (a)
|
||||||
{
|
{
|
||||||
++plugins;
|
++plugins;
|
||||||
|
|
||||||
if ( (*a).isValid() && !(*a).isPaused() )
|
if ( (*a).isValid() && !(*a).isPaused() )
|
||||||
++running;
|
++running;
|
||||||
|
|
||||||
print_srvconsole(" [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus());
|
print_srvconsole( " [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
|
||||||
++a;
|
plugins,(*a).getTitle(),(*a).getVersion(),
|
||||||
}
|
(*a).getAuthor(), (*a).getName(), (*a).getStatus() );
|
||||||
|
|
||||||
a = g_plugins.begin();
|
|
||||||
|
|
||||||
while (a)
|
|
||||||
{
|
|
||||||
if ((*a).getStatusCode() == ps_bad_load)
|
|
||||||
{
|
|
||||||
//error
|
|
||||||
print_srvconsole("Load fails: %s\n", (*a).getError());
|
|
||||||
}
|
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_srvconsole( "%d plugins, %d running\n",plugins,running );
|
print_srvconsole( "%d plugins, %d running\n",plugins,running );
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
|
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
|
||||||
{
|
{
|
||||||
@ -81,8 +76,8 @@ void amx_command()
|
|||||||
plugin->pausePlugin();
|
plugin->pausePlugin();
|
||||||
print_srvconsole("Paused plugin \"%s\"\n",plugin->getName() );
|
print_srvconsole("Paused plugin \"%s\"\n",plugin->getName() );
|
||||||
}
|
}
|
||||||
else
|
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
|
||||||
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
|
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
|
||||||
{
|
{
|
||||||
@ -90,38 +85,39 @@ void amx_command()
|
|||||||
|
|
||||||
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
|
||||||
|
|
||||||
if (plugin && plugin->isValid() && plugin->isPaused())
|
if ( plugin && plugin->isValid() )
|
||||||
{
|
{
|
||||||
plugin->unpausePlugin();
|
plugin->unpausePlugin();
|
||||||
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
|
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
|
||||||
}
|
}
|
||||||
else if (!plugin)
|
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
|
||||||
{
|
|
||||||
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
|
|
||||||
} else {
|
|
||||||
print_srvconsole("Plugin %s can't be unpaused right now.", sPlugin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"cvars"))
|
else if (!strcmp(cmd,"cvars"))
|
||||||
{
|
{
|
||||||
print_srvconsole( "Registered cvars:\n");
|
print_srvconsole( "Registered cvars:\n");
|
||||||
print_srvconsole(" %-24.23s %-24.23s %-16.15s\n", "name", "value", "plugin");
|
print_srvconsole( " %-24.23s %-24.23s %-16.15s\n",
|
||||||
|
"name","value","plugin");
|
||||||
|
|
||||||
int ammount = 0;
|
int ammount = 0;
|
||||||
|
|
||||||
for( CList<CCVar>::iterator a = g_cvars.begin(); a ; ++a )
|
for( CList<CCVar>::iterator a = g_cvars.begin(); a ; ++a )
|
||||||
{
|
{
|
||||||
print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName());
|
print_srvconsole( " [%3d] %-24.23s %-24.23s %-16.15s\n",++ammount,
|
||||||
|
(*a).getName() ,CVAR_GET_STRING( (*a).getName() ),(*a).getPluginName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
print_srvconsole( "%d cvars\n",ammount);
|
print_srvconsole( "%d cvars\n",ammount);
|
||||||
}
|
}
|
||||||
else if ( !strcmp(cmd,"cmds") )
|
else if ( !strcmp(cmd,"cmds") )
|
||||||
{
|
{
|
||||||
|
|
||||||
print_srvconsole( "Registered commands:\n");
|
print_srvconsole( "Registered commands:\n");
|
||||||
print_srvconsole(" %-24.23s %-16.15s %-8.7s %-16.15s\n", "name", "access", "type", "plugin");
|
print_srvconsole( " %-24.23s %-16.15s %-8.7s %-16.15s\n",
|
||||||
|
"name","access" ,"type" ,"plugin");
|
||||||
|
|
||||||
int ammount = 0;
|
int ammount = 0;
|
||||||
|
|
||||||
char access[32];
|
char access[32];
|
||||||
|
|
||||||
CmdMngr::iterator a = g_commands.begin( CMD_ConsoleCommand );
|
CmdMngr::iterator a = g_commands.begin( CMD_ConsoleCommand );
|
||||||
@ -129,7 +125,8 @@ void amx_command()
|
|||||||
while( a )
|
while( a )
|
||||||
{
|
{
|
||||||
UTIL_GetFlags( access , (*a).getFlags() );
|
UTIL_GetFlags( access , (*a).getFlags() );
|
||||||
print_srvconsole(" [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n", ++ammount, (*a).getCmdLine(), access, (*a).getCmdType(), (*a).getPlugin()->getName());
|
print_srvconsole( " [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n",
|
||||||
|
++ammount,(*a).getCmdLine() , access , (*a).getCmdType() , (*a).getPlugin()->getName());
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,36 +134,33 @@ void amx_command()
|
|||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"version"))
|
else if (!strcmp(cmd,"version"))
|
||||||
{
|
{
|
||||||
|
|
||||||
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
|
||||||
print_srvconsole("Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
|
print_srvconsole( "author: %s (%s)\n", Plugin_info.author, Plugin_info.url);
|
||||||
print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__);
|
print_srvconsole( "compiled: %s\n", __DATE__ ", " __TIME__);
|
||||||
#if defined JIT && !defined ASM32
|
|
||||||
print_srvconsole("Core mode: JIT Only\n");
|
|
||||||
#elif !defined JIT && defined ASM32
|
|
||||||
print_srvconsole("Core mode: ASM32 Only\n");
|
|
||||||
#elif defined JIT && defined ASM32
|
|
||||||
print_srvconsole("Core mode: JIT+ASM32\n");
|
|
||||||
#else
|
|
||||||
print_srvconsole("Core mode: Normal\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd,"modules"))
|
else if (!strcmp(cmd,"modules"))
|
||||||
{
|
{
|
||||||
print_srvconsole( "Currently loaded modules:\n");
|
print_srvconsole( "Currently loaded modules:\n");
|
||||||
print_srvconsole(" %-23.22s %-8.7s %-20.19s %-11.10s\n", "name", "version", "author", "status");
|
print_srvconsole( " %-23.22s %-8.7s %-20.19s %-11.10s\n",
|
||||||
|
"name", "version", "author", "status");
|
||||||
|
|
||||||
int running = 0;
|
int running = 0;
|
||||||
int modules = 0;
|
int modules = 0;
|
||||||
|
|
||||||
CList<CModule,const char *>::iterator a = g_modules.begin();
|
CList<CModule>::iterator a = g_modules.begin();
|
||||||
|
|
||||||
while ( a )
|
while ( a )
|
||||||
{
|
{
|
||||||
if ( (*a).getStatusValue() == MODULE_LOADED )
|
if ( (*a).getStatusValue() == MODULE_LOADED )
|
||||||
++running;
|
++running;
|
||||||
|
|
||||||
++modules;
|
++modules;
|
||||||
|
|
||||||
print_srvconsole(" [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus());
|
print_srvconsole( " [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules,
|
||||||
|
(*a).getName(), (*a).getVersion(), (*a).getAuthor() , (*a).getStatus() );
|
||||||
|
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +223,11 @@ void amx_command()
|
|||||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x78\x78\x24\x40\x4E\x4E\x4D\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x3E\x3E\x3F\x3E\x3E\x3E\x3E\x3B\x3B\x3B\x3A\x3A\x3F\x3E\x3A\x2E\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x45\x4D\x40\x45\x78\x5E\x33\x68\x33\x2B\n");
|
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x78\x78\x24\x40\x4E\x4E\x4D\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x3E\x3E\x3F\x3E\x3E\x3E\x3E\x3B\x3B\x3B\x3A\x3A\x3F\x3E\x3A\x2E\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x45\x4D\x40\x45\x78\x5E\x33\x68\x33\x2B\n");
|
||||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x24\x48\x45\x48\x78\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x4E\x40\x2B\x66\x33\x78\x20\x20\n");
|
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x24\x48\x45\x48\x78\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x4E\x40\x2B\x66\x33\x78\x20\x20\n");
|
||||||
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x2C\x20\x3A\x20\x20\n");
|
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x2C\x20\x3A\x20\x20\n");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
print_srvconsole("Usage: amxx < command > [ argument ]\n");
|
print_srvconsole("Usage: amxx < command > [ argument ]\n");
|
||||||
print_srvconsole("Commands:\n");
|
print_srvconsole("Commands:\n");
|
||||||
print_srvconsole(" version - display amxx version info\n");
|
print_srvconsole(" version - display amxx version info\n");
|
||||||
@ -240,23 +238,47 @@ void amx_command()
|
|||||||
print_srvconsole(" cmds - list commands registered by plugins\n");
|
print_srvconsole(" cmds - list commands registered by plugins\n");
|
||||||
print_srvconsole(" pause < plugin > - pause a running plugin\n");
|
print_srvconsole(" pause < plugin > - pause a running plugin\n");
|
||||||
print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n");
|
print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void plugin_srvcmd()
|
void plugin_srvcmd()
|
||||||
{
|
{
|
||||||
|
|
||||||
cell ret = 0;
|
cell ret = 0;
|
||||||
|
int err;
|
||||||
const char* cmd = CMD_ARGV(0);
|
const char* cmd = CMD_ARGV(0);
|
||||||
|
|
||||||
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
try{
|
||||||
|
#endif
|
||||||
|
|
||||||
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
CmdMngr::iterator a = g_commands.srvcmdbegin();
|
||||||
|
|
||||||
while ( a )
|
while ( a )
|
||||||
{
|
{
|
||||||
if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction()))
|
if ( (*a).matchCommand( cmd ) &&
|
||||||
|
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
|
||||||
{
|
{
|
||||||
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
|
|
||||||
|
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
|
||||||
|
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
|
||||||
|
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")",
|
||||||
|
err,(*a).getPlugin()->getAMX()->curline,(*a).getPlugin()->getName());
|
||||||
|
|
||||||
if ( ret ) break;
|
if ( ret ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
++a;
|
++a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLEEXEPTIONS
|
||||||
|
}catch( ... )
|
||||||
|
{
|
||||||
|
AMXXLOG_Log( "[AMXX] fatal error at forward function execution");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,13 @@ const char* stristr(const char* str, const char* substr)
|
|||||||
register char *prevloc = (char *)str;
|
register char *prevloc = (char *)str;
|
||||||
register char *haystack = (char *)str;
|
register char *haystack = (char *)str;
|
||||||
|
|
||||||
while (*haystack)
|
while (*haystack) {
|
||||||
{
|
if (tolower(*haystack) == tolower(*needle)) {
|
||||||
if (tolower(*haystack) == tolower(*needle))
|
|
||||||
{
|
|
||||||
haystack++;
|
haystack++;
|
||||||
if (!*++needle)
|
if (!*++needle)
|
||||||
return prevloc;
|
return prevloc;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
haystack = ++prevloc;
|
haystack = ++prevloc;
|
||||||
needle = (char *)substr;
|
needle = (char *)substr;
|
||||||
}
|
}
|
||||||
@ -78,12 +77,9 @@ int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
|
|||||||
{
|
{
|
||||||
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
||||||
cell* start = dest;
|
cell* start = dest;
|
||||||
|
|
||||||
while (max--&&*source)
|
while (max--&&*source)
|
||||||
*dest++=(cell)*source++;
|
*dest++=(cell)*source++;
|
||||||
|
|
||||||
*dest = 0;
|
*dest = 0;
|
||||||
|
|
||||||
return dest-start;
|
return dest-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,11 +89,9 @@ char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
|
|||||||
register cell* source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
register cell* source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
|
||||||
register char* dest = buffor[id];
|
register char* dest = buffor[id];
|
||||||
char* start = dest;
|
char* start = dest;
|
||||||
|
while ((*dest++=(char)(*source++)))
|
||||||
while ((*dest++=(char)(*source++)));
|
;
|
||||||
|
|
||||||
len = --dest - start;
|
len = --dest - start;
|
||||||
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,41 +101,32 @@ void copy_amxmemory(cell* dest, cell* src, int len)
|
|||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char* parse_arg(char** line,int& state)
|
char* parse_arg(char** line,int& state)
|
||||||
{
|
{
|
||||||
static char arg[3072];
|
static char arg[3072];
|
||||||
char* dest = arg;
|
char* dest = arg;
|
||||||
state = 0;
|
state = 0;
|
||||||
|
while(**line) {
|
||||||
while (**line)
|
if ( isspace(**line) ) {
|
||||||
{
|
|
||||||
if (isspace(**line))
|
|
||||||
{
|
|
||||||
if (state == 1)
|
if (state == 1)
|
||||||
break;
|
break;
|
||||||
else if (!state)
|
else if (!state) {
|
||||||
{
|
|
||||||
(*line)++;
|
(*line)++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state != 2)
|
else if (state != 2)
|
||||||
state = 1;
|
state = 1;
|
||||||
|
if (**line=='"') {
|
||||||
if (**line == '"')
|
|
||||||
{
|
|
||||||
(*line)++;
|
(*line)++;
|
||||||
|
|
||||||
if (state == 2)
|
if (state == 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
state = 2;
|
state = 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest++ = *(*line)++;
|
*dest++ = *(*line)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest = '\0';
|
*dest = '\0';
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
@ -149,41 +134,30 @@ char* parse_arg(char** line, int& state)
|
|||||||
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
|
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
|
||||||
{
|
{
|
||||||
static char buffor[3072];
|
static char buffor[3072];
|
||||||
|
|
||||||
cell *a = get_amxaddr(amx,params[1]);
|
cell *a = get_amxaddr(amx,params[1]);
|
||||||
cell *b = get_amxaddr(amx,params[3]);
|
cell *b = get_amxaddr(amx,params[3]);
|
||||||
cell *c = get_amxaddr(amx,params[4]);
|
cell *c = get_amxaddr(amx,params[4]);
|
||||||
|
|
||||||
int iMain = amxstring_len(a);
|
int iMain = amxstring_len(a);
|
||||||
int iWhat = amxstring_len(b);
|
int iWhat = amxstring_len(b);
|
||||||
int iWith = amxstring_len(c);
|
int iWith = amxstring_len(c);
|
||||||
int iPot = iMain + iWith - iWhat;
|
int iPot = iMain + iWith - iWhat;
|
||||||
|
if (iPot>=params[2]){
|
||||||
if (iPot >= params[2])
|
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *d = buffor;
|
char *d = buffor;
|
||||||
cell *x, *y, *z = a, *l = a;
|
cell *x, *y, *z = a, *l = a;
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
while(*a){
|
||||||
while (*a)
|
if (*a==*b){
|
||||||
{
|
|
||||||
if (*a == *b)
|
|
||||||
{
|
|
||||||
x=a+1;
|
x=a+1;
|
||||||
y=b+1;
|
y=b+1;
|
||||||
p=1;
|
p=1;
|
||||||
if (!*y) break;
|
if (!*y) break;
|
||||||
|
while(*x==*y){
|
||||||
while (*x == *y)
|
|
||||||
{
|
|
||||||
x++; y++; p++;
|
x++; y++; p++;
|
||||||
if (!*y) break;
|
if (!*y) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*y) break;
|
if (!*y) break;
|
||||||
p = 0;
|
p = 0;
|
||||||
*d++=(char)*a++;
|
*d++=(char)*a++;
|
||||||
@ -191,9 +165,7 @@ static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
|
|||||||
}
|
}
|
||||||
*d++=(char)*a++;
|
*d++=(char)*a++;
|
||||||
}
|
}
|
||||||
|
if (p){
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
while(*c) *d++=(char)*c++;
|
while(*c) *d++=(char)*c++;
|
||||||
a+=p;
|
a+=p;
|
||||||
while(*a) *d++=(char)*a++;
|
while(*a) *d++=(char)*a++;
|
||||||
@ -203,7 +175,6 @@ static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
|
|||||||
*z=0;
|
*z=0;
|
||||||
return (z-l);
|
return (z-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,20 +185,17 @@ static cell AMX_NATIVE_CALL contain(AMX *amx, cell *params) /* 2 param */
|
|||||||
register cell *c = b;
|
register cell *c = b;
|
||||||
cell* str = b;
|
cell* str = b;
|
||||||
cell* substr = a;
|
cell* substr = a;
|
||||||
|
while (*c) {
|
||||||
while (*c)
|
if (*c == *a) {
|
||||||
{
|
|
||||||
if (*c == *a)
|
|
||||||
{
|
|
||||||
c++;
|
c++;
|
||||||
if (!*++a)
|
if (!*++a)
|
||||||
return b - str;
|
return b - str;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
c = ++b;
|
c = ++b;
|
||||||
a = substr;
|
a = substr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,20 +206,17 @@ static cell AMX_NATIVE_CALL containi(AMX *amx, cell *params) /* 2 param */
|
|||||||
register cell *c = b;
|
register cell *c = b;
|
||||||
cell* str = b;
|
cell* str = b;
|
||||||
cell* substr = a;
|
cell* substr = a;
|
||||||
|
while (*c) {
|
||||||
while (*c)
|
if (tolower(*c) == tolower(*a)) {
|
||||||
{
|
|
||||||
if (tolower(*c) == tolower(*a))
|
|
||||||
{
|
|
||||||
c++;
|
c++;
|
||||||
if (!*++a)
|
if (!*++a)
|
||||||
return b - str;
|
return b - str;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
c = ++b;
|
c = ++b;
|
||||||
a = substr;
|
a = substr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,72 +230,6 @@ static cell AMX_NATIVE_CALL numtostr(AMX *amx, cell *params) /* 3 param */
|
|||||||
{
|
{
|
||||||
char szTemp[32];
|
char szTemp[32];
|
||||||
sprintf(szTemp,"%d",(int)params[1]);
|
sprintf(szTemp,"%d",(int)params[1]);
|
||||||
|
|
||||||
return set_amxstring(amx, params[2], szTemp, params[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL str_to_float(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
cell *str = get_amxaddr(amx, params[1]);
|
|
||||||
|
|
||||||
bool neg = false;
|
|
||||||
unsigned long part1 = 0;
|
|
||||||
|
|
||||||
if (*str == '-')
|
|
||||||
{
|
|
||||||
neg = true;
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
else if (*str == '+')
|
|
||||||
++str;
|
|
||||||
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
if (*str == '.')
|
|
||||||
{
|
|
||||||
++str;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*str < '0' || *str > '9')
|
|
||||||
{
|
|
||||||
REAL fl = neg ? -static_cast<REAL>(part1) : static_cast<REAL>(part1);
|
|
||||||
return amx_ftoc(fl);
|
|
||||||
}
|
|
||||||
|
|
||||||
part1 *= 10;
|
|
||||||
part1 += *str - '0';
|
|
||||||
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long part2 = 0;
|
|
||||||
unsigned long div = 1;
|
|
||||||
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
if (*str < '0' || *str > '9')
|
|
||||||
break;
|
|
||||||
|
|
||||||
part2 *= 10;
|
|
||||||
part2 += *str - '0';
|
|
||||||
div *= 10;
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
|
|
||||||
REAL fl = static_cast<REAL>(part1) + (static_cast<REAL>(part2) / div);
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
fl = -fl;
|
|
||||||
|
|
||||||
return amx_ftoc(fl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL float_to_str(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
char szTemp[32];
|
|
||||||
sprintf(szTemp, "%f", amx_ctof(params[1]));
|
|
||||||
|
|
||||||
return set_amxstring(amx,params[2],szTemp,params[3]);
|
return set_amxstring(amx,params[2],szTemp,params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,23 +239,17 @@ static cell AMX_NATIVE_CALL add(AMX *amx, cell *params) /* 4 param */
|
|||||||
cell *dest = get_amxaddr(amx,params[1]);
|
cell *dest = get_amxaddr(amx,params[1]);
|
||||||
cell *start = dest;
|
cell *start = dest;
|
||||||
int c = params[2], d = params[4];
|
int c = params[2], d = params[4];
|
||||||
|
|
||||||
while(*dest&&c--)
|
while(*dest&&c--)
|
||||||
++dest;
|
++dest;
|
||||||
|
if (d){
|
||||||
if (d)
|
|
||||||
{
|
|
||||||
while(c--&&d--&&*src)
|
while(c--&&d--&&*src)
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
*dest=0;
|
*dest=0;
|
||||||
|
|
||||||
return (dest-start);
|
return (dest-start);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(c--&&*src)
|
while(c--&&*src)
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
*dest=0;
|
*dest=0;
|
||||||
|
|
||||||
return (dest-start);
|
return (dest-start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,11 +259,9 @@ static cell AMX_NATIVE_CALL copy(AMX *amx, cell *params) /* 4 param */
|
|||||||
cell *dest = get_amxaddr(amx,params[1]);
|
cell *dest = get_amxaddr(amx,params[1]);
|
||||||
cell *start = dest;
|
cell *start = dest;
|
||||||
int c = params[2];
|
int c = params[2];
|
||||||
|
|
||||||
while(c--&&*src)
|
while(c--&&*src)
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
*dest=0;
|
*dest=0;
|
||||||
|
|
||||||
return (dest-start);
|
return (dest-start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,11 +272,9 @@ static cell AMX_NATIVE_CALL copyc(AMX *amx, cell *params) /* 4 param */
|
|||||||
cell *start = dest;
|
cell *start = dest;
|
||||||
int c = params[2];
|
int c = params[2];
|
||||||
cell ch = params[4];
|
cell ch = params[4];
|
||||||
|
|
||||||
while(c--&&*src&&*src!=ch)
|
while(c--&&*src&&*src!=ch)
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
*dest=0;
|
*dest=0;
|
||||||
|
|
||||||
return (dest-start);
|
return (dest-start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,10 +283,8 @@ static cell AMX_NATIVE_CALL setc(AMX *amx, cell *params) /* 4 param */
|
|||||||
cell *src = get_amxaddr(amx,params[1]);
|
cell *src = get_amxaddr(amx,params[1]);
|
||||||
int c = params[2];
|
int c = params[2];
|
||||||
cell ch = params[3];
|
cell ch = params[3];
|
||||||
|
|
||||||
while(c--)
|
while(c--)
|
||||||
*src++=ch;
|
*src++=ch;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,19 +293,14 @@ static cell AMX_NATIVE_CALL equal(AMX *amx, cell *params) /* 3 param */
|
|||||||
cell *a = get_amxaddr(amx,params[1]);
|
cell *a = get_amxaddr(amx,params[1]);
|
||||||
cell *b = get_amxaddr(amx,params[2]);
|
cell *b = get_amxaddr(amx,params[2]);
|
||||||
int c = params[3];
|
int c = params[3];
|
||||||
|
if (c) {
|
||||||
if (c)
|
|
||||||
{
|
|
||||||
while (--c&&*a&&(*a==*b))
|
while (--c&&*a&&(*a==*b))
|
||||||
++a, ++b;
|
++a, ++b;
|
||||||
return (*a-*b)?0:1;
|
return (*a-*b)?0:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while(!(ret=*a-*b)&&*b)
|
while(!(ret=*a-*b)&&*b)
|
||||||
++a, ++b;
|
++a, ++b;
|
||||||
|
|
||||||
return ret?0:1;
|
return ret?0:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,24 +309,18 @@ static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
|
|||||||
cell *a = get_amxaddr(amx,params[1]);
|
cell *a = get_amxaddr(amx,params[1]);
|
||||||
cell *b = get_amxaddr(amx,params[2]);
|
cell *b = get_amxaddr(amx,params[2]);
|
||||||
int f,l, c = params[3];
|
int f,l, c = params[3];
|
||||||
|
if (c) {
|
||||||
if (c)
|
do {
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
f = tolower(*a++);
|
f = tolower(*a++);
|
||||||
l = tolower(*b++);
|
l = tolower(*b++);
|
||||||
} while (--c && l && f && f == l);
|
}
|
||||||
|
while (--c &&l&&f&& f==l);
|
||||||
return(f - l)?0:1;
|
return(f - l)?0:1;
|
||||||
}
|
}
|
||||||
|
do {
|
||||||
do
|
|
||||||
{
|
|
||||||
f = tolower(*a++);
|
f = tolower(*a++);
|
||||||
l = tolower(*b++);
|
l = tolower(*b++);
|
||||||
} while (f && f == l);
|
} while (f && f == l);
|
||||||
|
|
||||||
return (f - l)?0:1;
|
return (f - l)?0:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,19 +336,13 @@ static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */
|
|||||||
char* arg, *parse = get_amxstring(amx,params[1],0,c);
|
char* arg, *parse = get_amxstring(amx,params[1],0,c);
|
||||||
cell *cptr;
|
cell *cptr;
|
||||||
int state;
|
int state;
|
||||||
|
while(*parse){
|
||||||
while (*parse)
|
|
||||||
{
|
|
||||||
arg = parse_arg(&parse,state);
|
arg = parse_arg(&parse,state);
|
||||||
|
if (state){
|
||||||
if (state)
|
|
||||||
{
|
|
||||||
if (inum <= iarg)
|
if (inum <= iarg)
|
||||||
return( (iarg-2)>>1 );
|
return( (iarg-2)>>1 );
|
||||||
|
|
||||||
cptr = get_amxaddr(amx,params[iarg++]);
|
cptr = get_amxaddr(amx,params[iarg++]);
|
||||||
c = *get_amxaddr(amx,params[iarg++]);
|
c = *get_amxaddr(amx,params[iarg++]);
|
||||||
|
|
||||||
while(c--&&*arg)
|
while(c--&&*arg)
|
||||||
*cptr++=(cell)*arg++;
|
*cptr++=(cell)*arg++;
|
||||||
*cptr=0;
|
*cptr=0;
|
||||||
@ -486,13 +356,10 @@ static cell AMX_NATIVE_CALL strtolower(AMX *amx, cell *params) /* 1 param */
|
|||||||
{
|
{
|
||||||
cell *cptr = get_amxaddr(amx,params[1]);
|
cell *cptr = get_amxaddr(amx,params[1]);
|
||||||
cell *begin = cptr;
|
cell *begin = cptr;
|
||||||
|
while(*cptr){
|
||||||
while (*cptr)
|
|
||||||
{
|
|
||||||
*cptr = tolower(*cptr);
|
*cptr = tolower(*cptr);
|
||||||
cptr++;
|
cptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cptr - begin;
|
return cptr - begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,13 +367,10 @@ static cell AMX_NATIVE_CALL strtoupper(AMX *amx, cell *params) /* 1 param */
|
|||||||
{
|
{
|
||||||
cell *cptr = get_amxaddr(amx,params[1]);
|
cell *cptr = get_amxaddr(amx,params[1]);
|
||||||
cell *begin = cptr;
|
cell *begin = cptr;
|
||||||
|
while(*cptr){
|
||||||
while (*cptr)
|
|
||||||
{
|
|
||||||
*cptr = toupper(*cptr);
|
*cptr = toupper(*cptr);
|
||||||
cptr++;
|
cptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cptr - begin;
|
return cptr - begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +378,6 @@ int fo_numargs(AMX *amx)
|
|||||||
{
|
{
|
||||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||||
cell bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
|
cell bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
|
||||||
|
|
||||||
return (int)(bytes/sizeof(cell));
|
return (int)(bytes/sizeof(cell));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +385,6 @@ int fo_getargnum(AMX *amx, int pos)
|
|||||||
{
|
{
|
||||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||||
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
|
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
|
||||||
|
|
||||||
return *(cell *)(data+(int)value);
|
return *(cell *)(data+(int)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +393,6 @@ float fo_getargfloat(AMX *amx, int pos)
|
|||||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||||
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
|
cell value = * (cell *)(data+(int)amx->frm+(pos+3)*sizeof(cell));
|
||||||
cell number = *(cell *)(data+(int)value);
|
cell number = *(cell *)(data+(int)value);
|
||||||
|
|
||||||
return *(REAL *)((void *)&number);
|
return *(REAL *)((void *)&number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,12 +404,10 @@ char* fo_getargstr(AMX *amx, int swap, int pos)
|
|||||||
static char buffer[2][3072];
|
static char buffer[2][3072];
|
||||||
char* b = buffer[swap];
|
char* b = buffer[swap];
|
||||||
int a = 0;
|
int a = 0;
|
||||||
|
do {
|
||||||
do
|
|
||||||
{
|
|
||||||
value = src_value + a++ * sizeof(cell);
|
value = src_value + a++ * sizeof(cell);
|
||||||
value = *(cell *)(data+(int)value);
|
value = *(cell *)(data+(int)value);
|
||||||
*b++ = static_cast<char>(value);
|
*b++ = value;
|
||||||
} while (value);
|
} while (value);
|
||||||
|
|
||||||
return buffer[swap];
|
return buffer[swap];
|
||||||
@ -561,104 +420,34 @@ char* format_arguments(AMX *amx, int parm, int& len)
|
|||||||
char *ptr,*arg, *dest = *buffer;
|
char *ptr,*arg, *dest = *buffer;
|
||||||
char *src = fo_getargstr(amx, 0,parm++);
|
char *src = fo_getargstr(amx, 0,parm++);
|
||||||
int numparam = fo_numargs(amx);
|
int numparam = fo_numargs(amx);
|
||||||
|
while(*src) {
|
||||||
while (*src)
|
if (*src=='%'&&*(src+1)) {
|
||||||
{
|
|
||||||
if (*src == '%' && *(src + 1))
|
|
||||||
{
|
|
||||||
ptr = format;
|
ptr = format;
|
||||||
*ptr++ = *src++;
|
*ptr++ = *src++;
|
||||||
|
if (*src=='%'){
|
||||||
if (*src == '%')
|
|
||||||
{
|
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
while (!isalpha(*ptr++=*src++))
|
||||||
while (!isalpha(*ptr++ = *src++));
|
;
|
||||||
|
|
||||||
*ptr='\0';
|
*ptr='\0';
|
||||||
if (numparam < parm) continue;
|
if (numparam < parm) continue;
|
||||||
arg = buffer[1];
|
arg = buffer[1];
|
||||||
|
switch(*(ptr-1)){
|
||||||
switch (*(ptr - 1))
|
|
||||||
{
|
|
||||||
case 's': sprintf(arg,format,fo_getargstr(amx,1, parm++)); break;
|
case 's': sprintf(arg,format,fo_getargstr(amx,1, parm++)); break;
|
||||||
case 'f': case 'g': sprintf(arg,format,fo_getargfloat(amx, parm++)); break;
|
case 'f': case 'g': sprintf(arg,format,fo_getargfloat(amx, parm++)); break;
|
||||||
default: sprintf(arg,format,fo_getargnum(amx, parm++));
|
default: sprintf(arg,format,fo_getargnum(amx, parm++));
|
||||||
}
|
}
|
||||||
|
|
||||||
while(*arg) *dest++=*arg++;
|
while(*arg) *dest++=*arg++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*dest++=*src++;
|
*dest++=*src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest='\0';
|
*dest='\0';
|
||||||
len = dest - *buffer;
|
len = dest - *buffer;
|
||||||
|
|
||||||
return *buffer;
|
return *buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//added by BAILOPAN for jtp10181
|
|
||||||
//takes a string and breaks it into a 1st param and rest params
|
|
||||||
//different from strbreak because it's more crafted for control
|
|
||||||
static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int left_pos = 0;
|
|
||||||
int right_pos = 0;
|
|
||||||
unsigned int i = 0;
|
|
||||||
bool done_flag = false;
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
//string[]
|
|
||||||
char *string = get_amxstring(amx, params[1], 0, len);
|
|
||||||
//left[]
|
|
||||||
char *left = new char[len + 1];
|
|
||||||
//right[]
|
|
||||||
char *right = new char[len + 1];
|
|
||||||
int leftMax = params[3];
|
|
||||||
int rightMax = params[5];
|
|
||||||
//token
|
|
||||||
char token = static_cast<char>(params[6]);
|
|
||||||
//trim
|
|
||||||
int trim = params[7];
|
|
||||||
|
|
||||||
for (i = 0; i < (unsigned int)len; i++)
|
|
||||||
{
|
|
||||||
if (trim && !done_flag)
|
|
||||||
{
|
|
||||||
if (isspace(string[i]))
|
|
||||||
{
|
|
||||||
while (isspace(string[++i]));
|
|
||||||
done_flag = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!done_flag && string[i] == token)
|
|
||||||
{
|
|
||||||
done_flag = true;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done_flag)
|
|
||||||
{
|
|
||||||
right[right_pos++] = string[i];
|
|
||||||
} else {
|
|
||||||
left[left_pos++] = string[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
right[right_pos] = 0;
|
|
||||||
left[left_pos] = 0;
|
|
||||||
set_amxstring(amx, params[2], left, leftMax);
|
|
||||||
set_amxstring(amx, params[4], right, rightMax);
|
|
||||||
delete [] left;
|
|
||||||
delete [] right;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//added by BAILOPAN
|
//added by BAILOPAN
|
||||||
//Takes a string and breaks it into a 1st param and rest params
|
//Takes a string and breaks it into a 1st param and rest params
|
||||||
//strbreak(String[], First[], FirstLen, Rest[], RestLen)
|
//strbreak(String[], First[], FirstLen, Rest[], RestLen)
|
||||||
@ -678,53 +467,36 @@ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
|
|||||||
int LeftMax = params[3];
|
int LeftMax = params[3];
|
||||||
int RightMax = params[5];
|
int RightMax = params[5];
|
||||||
|
|
||||||
for (i = 0; i < (unsigned int)l; i++)
|
for (i=0; i<strlen(string); i++) {
|
||||||
{
|
if (string[i] == '"' && !quote_flag) {
|
||||||
if (string[i] == '"' && !quote_flag)
|
|
||||||
{
|
|
||||||
quote_flag = true;
|
quote_flag = true;
|
||||||
}
|
} else if (string[i] == '"' && quote_flag) {
|
||||||
else if (string[i] == '"' && quote_flag)
|
|
||||||
{
|
|
||||||
quote_flag = false;
|
quote_flag = false;
|
||||||
}
|
}
|
||||||
|
if ((string[i] == ' ') && !quote_flag && !done_flag) {
|
||||||
if (isspace(string[i]) && !quote_flag && !done_flag)
|
|
||||||
{
|
|
||||||
done_flag = true;
|
done_flag = true;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if (!done_flag && string[i]!='"') {
|
||||||
if (!done_flag && string[i]!='"')
|
if (left_pos < LeftMax) {
|
||||||
{
|
|
||||||
if (left_pos < LeftMax)
|
|
||||||
{
|
|
||||||
left[left_pos] = string[i];
|
left[left_pos] = string[i];
|
||||||
|
if (left[left_pos] == '\'') {
|
||||||
if (left[left_pos] == '\'')
|
|
||||||
{
|
|
||||||
left[left_pos] = hold;
|
left[left_pos] = hold;
|
||||||
}
|
}
|
||||||
|
|
||||||
left_pos++;
|
left_pos++;
|
||||||
} else {
|
} else {
|
||||||
done_flag = true;
|
done_flag = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (right_pos < RightMax && string[i]!='"')
|
if (right_pos < RightMax && string[i]!='"') {
|
||||||
{
|
|
||||||
right[right_pos] = string[i];
|
right[right_pos] = string[i];
|
||||||
|
if (right[right_pos] == '\'') {
|
||||||
if (right[right_pos] == '\'')
|
|
||||||
{
|
|
||||||
right[right_pos] = hold;
|
right[right_pos] = hold;
|
||||||
}
|
}
|
||||||
|
|
||||||
right_pos++;
|
right_pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
left[left_pos] = '\0';
|
left[left_pos] = '\0';
|
||||||
right[right_pos] = '\0';
|
right[right_pos] = '\0';
|
||||||
set_amxstring(amx, params[2], left, params[3]);
|
set_amxstring(amx, params[2], left, params[3]);
|
||||||
@ -739,15 +511,11 @@ static cell AMX_NATIVE_CALL format_args(AMX *amx, cell *params)
|
|||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int pos = params[3];
|
int pos = params[3];
|
||||||
|
if (pos < 0){
|
||||||
if (pos < 0)
|
|
||||||
{
|
|
||||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* string = format_arguments(amx, pos ,len); // indexed from 0
|
char* string = format_arguments(amx, pos ,len); // indexed from 0
|
||||||
|
|
||||||
return set_amxstring(amx,params[1],string,params[2]);
|
return set_amxstring(amx,params[1],string,params[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,116 +543,51 @@ static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
|
|||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
cell *str = get_amxaddr(amx, params[1]);
|
cell *str = get_amxaddr(amx, params[1]);
|
||||||
|
|
||||||
if (!isalpha((char)str[0]) || !(str[0]&(1<<5)))
|
if (!isalpha((char)str[0]) || !(str[0]&(1<<5)))
|
||||||
return 0;
|
return 0;
|
||||||
str[0] &= ~(1<<5);
|
str[0] &= ~(1<<5);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *str = get_amxstring(amx, params[1], 0, len);
|
|
||||||
|
|
||||||
return strlen(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
int len;
|
cell *asdf = get_amxaddr(amx, params[1]);
|
||||||
char *str = get_amxstring(amx, params[1], 0, len);
|
cell *cptr = asdf;
|
||||||
|
int len = 0;
|
||||||
String toTrim;
|
while (*cptr++) len++;
|
||||||
|
int flag = 0, incr = 0;
|
||||||
toTrim.assign(str);
|
register int i = 0;
|
||||||
toTrim.trim();
|
for (i=len-1; i>=0; i--)
|
||||||
|
|
||||||
len -= toTrim.size();
|
|
||||||
|
|
||||||
set_amxstring(amx, params[1], toTrim.c_str(), toTrim.size());
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL n_strcat(AMX *amx, cell *params)
|
|
||||||
{
|
{
|
||||||
cell *cdest, *csrc;
|
if (!isspace(asdf[i]))
|
||||||
|
|
||||||
cdest = get_amxaddr(amx, params[1]);
|
|
||||||
csrc = get_amxaddr(amx, params[2]);
|
|
||||||
int num = params[3];
|
|
||||||
|
|
||||||
while (*cdest && num)
|
|
||||||
{
|
{
|
||||||
cdest++;
|
break;
|
||||||
num--;
|
} else {
|
||||||
}
|
asdf[i] = 0;
|
||||||
|
len--;
|
||||||
if (!num)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (*csrc && num)
|
|
||||||
{
|
|
||||||
*cdest++ = *csrc++;
|
|
||||||
num--;
|
|
||||||
}
|
|
||||||
*cdest = 0;
|
|
||||||
|
|
||||||
return params[3] - num;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *str1 = get_amxstring(amx, params[1], 0, len);
|
|
||||||
char *str2 = get_amxstring(amx, params[2], 1, len);
|
|
||||||
|
|
||||||
if (params[1])
|
|
||||||
return stricmp(str1, str2);
|
|
||||||
else
|
|
||||||
return strcmp(str1, str2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
char *str = get_amxstring(amx, params[1], 0, len);
|
|
||||||
int sublen;
|
|
||||||
char *sub = get_amxstring(amx, params[2], 1, sublen);
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
bool igcase = params[3] ? true : false;
|
|
||||||
|
|
||||||
if (igcase)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
if (str[i] & (1<<5))
|
|
||||||
str[i] &= ~(1<<5);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < sublen; i++)
|
|
||||||
{
|
|
||||||
if (str[i] & (1<<5))
|
|
||||||
str[i] &= ~(1<<5);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params[4] > len)
|
for (i=0; i<len; i++)
|
||||||
return -1;
|
{
|
||||||
|
if (isspace(asdf[i]) && !flag)
|
||||||
|
{
|
||||||
|
incr++;
|
||||||
|
if (incr+i<len)
|
||||||
|
asdf[i] = asdf[incr+i];
|
||||||
|
} else {
|
||||||
|
if (!flag)
|
||||||
|
flag = 1;
|
||||||
|
if (incr)
|
||||||
|
asdf[i] = asdf[incr+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asdf[len] = 0;
|
||||||
|
|
||||||
char *pos = &(str[params[4]]);
|
return incr;
|
||||||
char *find = strstr(str, sub);
|
|
||||||
|
|
||||||
if (!find)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return (find - str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO string_Natives[] =
|
AMX_NATIVE_INFO string_Natives[] = {
|
||||||
{
|
|
||||||
{ "add", add },
|
{ "add", add },
|
||||||
{ "contain", contain },
|
{ "contain", contain },
|
||||||
{ "containi", containi },
|
{ "containi", containi },
|
||||||
@ -899,7 +602,6 @@ AMX_NATIVE_INFO string_Natives[] =
|
|||||||
{ "isspace", is_space },
|
{ "isspace", is_space },
|
||||||
{ "isalpha", is_alpha },
|
{ "isalpha", is_alpha },
|
||||||
{ "num_to_str", numtostr },
|
{ "num_to_str", numtostr },
|
||||||
{"numtostr", numtostr},
|
|
||||||
{ "parse", parse },
|
{ "parse", parse },
|
||||||
{ "replace", replace },
|
{ "replace", replace },
|
||||||
{ "setc", setc },
|
{ "setc", setc },
|
||||||
@ -907,15 +609,7 @@ AMX_NATIVE_INFO string_Natives[] =
|
|||||||
{ "strtolower", strtolower },
|
{ "strtolower", strtolower },
|
||||||
{ "strtoupper", strtoupper },
|
{ "strtoupper", strtoupper },
|
||||||
{ "str_to_num", strtonum },
|
{ "str_to_num", strtonum },
|
||||||
{"strtonum", strtonum},
|
|
||||||
{ "trim", amx_trim },
|
{ "trim", amx_trim },
|
||||||
{ "ucfirst", amx_ucfirst },
|
{ "ucfirst", amx_ucfirst },
|
||||||
{"strtok", amx_strtok},
|
|
||||||
{"strlen", amx_strlen},
|
|
||||||
{"strcat", n_strcat},
|
|
||||||
{"strfind", n_strfind},
|
|
||||||
{"strcmp", n_strcmp},
|
|
||||||
{"str_to_float", str_to_float},
|
|
||||||
{"float_to_str", float_to_str},
|
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -30,42 +30,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
#define _vsnprintf vsnprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *UTIL_VarArgs(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
static char string[4096];
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
_vsnprintf(string, sizeof(string)-1, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
int UTIL_ReadFlags(const char* c)
|
int UTIL_ReadFlags(const char* c)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
|
||||||
while (*c)
|
|
||||||
flags |= (1<<(*c++ - 'a'));
|
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_GetFlags(char* f,int a)
|
void UTIL_GetFlags(char* f,int a)
|
||||||
{
|
{
|
||||||
for (int i = 'a'; i <= 'z'; ++i)
|
for(int i='a';i<='z';++i){
|
||||||
{
|
|
||||||
if ( a & 1 ) *f++ = i;
|
if ( a & 1 ) *f++ = i;
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*f = 0;
|
*f = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,14 +59,12 @@ void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen)
|
|||||||
if (!gmsgShowMenu)
|
if (!gmsgShowMenu)
|
||||||
return; // some games don't support ShowMenu (Firearms)
|
return; // some games don't support ShowMenu (Firearms)
|
||||||
|
|
||||||
while (*n)
|
while ( *n ) {
|
||||||
{
|
|
||||||
a = mlen;
|
a = mlen;
|
||||||
if ( a > 175 ) a = 175;
|
if ( a > 175 ) a = 175;
|
||||||
mlen -= a;
|
mlen -= a;
|
||||||
c = *(n+=a);
|
c = *(n+=a);
|
||||||
*n = 0;
|
*n = 0;
|
||||||
|
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
|
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
|
||||||
WRITE_SHORT( slots );
|
WRITE_SHORT( slots );
|
||||||
WRITE_CHAR( time );
|
WRITE_CHAR( time );
|
||||||
@ -101,28 +79,23 @@ void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen)
|
|||||||
/* warning - don't pass here const string */
|
/* warning - don't pass here const string */
|
||||||
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
||||||
{
|
{
|
||||||
if (!gmsgMOTD)
|
if (!gmsgServerName)
|
||||||
return; // :TODO: Maybe output a warning log?
|
return; // :TODO: Maybe output a warning log?
|
||||||
|
|
||||||
if (gmsgServerName)
|
|
||||||
{
|
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||||
WRITE_STRING(name);
|
WRITE_STRING(name);
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
|
||||||
|
|
||||||
char *n = motd;
|
char *n = motd;
|
||||||
char c = 0;
|
char c = 0;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
while (*n)
|
while ( *n ) {
|
||||||
{
|
|
||||||
a = mlen;
|
a = mlen;
|
||||||
if ( a > 175 ) a = 175;
|
if ( a > 175 ) a = 175;
|
||||||
mlen -= a;
|
mlen -= a;
|
||||||
c = *(n+=a);
|
c = *(n+=a);
|
||||||
*n = 0;
|
*n = 0;
|
||||||
|
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
|
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
|
||||||
WRITE_BYTE( c ? FALSE : TRUE );
|
WRITE_BYTE( c ? FALSE : TRUE );
|
||||||
WRITE_STRING( motd );
|
WRITE_STRING( motd );
|
||||||
@ -131,52 +104,39 @@ void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name)
|
|||||||
motd = n;
|
motd = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gmsgServerName)
|
|
||||||
{
|
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||||
WRITE_STRING( hostname->string );
|
WRITE_STRING( hostname->string );
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void UTIL_IntToString(int value, char *output)
|
void UTIL_IntToString(int value, char *output)
|
||||||
{
|
{
|
||||||
static const char *words[] =
|
static const char *words[] = {"zero ","one ","two ","three ","four ",
|
||||||
{"zero ","one ","two ","three ","four ",
|
|
||||||
"five ", "six ","seven ","eight ","nine ","ten ",
|
"five ", "six ","seven ","eight ","nine ","ten ",
|
||||||
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
||||||
"sixteen ","seventeen ","eighteen ","nineteen ",
|
"sixteen ","seventeen ","eighteen ","nineteen ",
|
||||||
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
||||||
"seventy ","eighty ","ninety ",
|
"seventy ","eighty ","ninety ",
|
||||||
"hundred ","thousand "};
|
"hundred ","thousand "};
|
||||||
|
|
||||||
*output = 0;
|
*output = 0;
|
||||||
if (value < 0) value = -value;
|
if (value < 0) value = -value;
|
||||||
int tho = value / 1000;
|
int tho = value / 1000;
|
||||||
int aaa = 0;
|
int aaa = 0;
|
||||||
|
if (tho){
|
||||||
if (tho)
|
|
||||||
{
|
|
||||||
aaa += sprintf(&output[aaa], words[ tho ] );
|
aaa += sprintf(&output[aaa], words[ tho ] );
|
||||||
aaa += sprintf(&output[aaa], words[29] );
|
aaa += sprintf(&output[aaa], words[29] );
|
||||||
value = value % 1000;
|
value = value % 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hun = value / 100;
|
int hun = value / 100;
|
||||||
|
if (hun) {
|
||||||
if (hun)
|
|
||||||
{
|
|
||||||
aaa += sprintf(&output[aaa], words[ hun ] );
|
aaa += sprintf(&output[aaa], words[ hun ] );
|
||||||
aaa += sprintf(&output[aaa], words[28] );
|
aaa += sprintf(&output[aaa], words[28] );
|
||||||
value = value % 100;
|
value = value % 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ten = value / 10;
|
int ten = value / 10;
|
||||||
int unit = value % 10;
|
int unit = value % 10;
|
||||||
|
|
||||||
if ( ten )
|
if ( ten )
|
||||||
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
|
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
|
||||||
|
|
||||||
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
|
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
|
||||||
sprintf(&output[aaa], words[ unit ] );
|
sprintf(&output[aaa], words[ unit ] );
|
||||||
}
|
}
|
||||||
@ -186,34 +146,27 @@ char* UTIL_SplitHudMessage(const char *src)
|
|||||||
static char message[512];
|
static char message[512];
|
||||||
short b = 0, d = 0, e = 0, c = -1;
|
short b = 0, d = 0, e = 0, c = -1;
|
||||||
|
|
||||||
while (src[d] && e < 480)
|
while ( src[ d ] && e < 480 ) {
|
||||||
{
|
if ( src[ d ] == ' ' ) {
|
||||||
if (src[d] == ' ')
|
|
||||||
{
|
|
||||||
c = e;
|
c = e;
|
||||||
}
|
}
|
||||||
else if (src[d] == '\n')
|
else if ( src[ d ] == '\n' ) {
|
||||||
{
|
|
||||||
c = -1;
|
c = -1;
|
||||||
b = 0;
|
b = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
message[ e++ ] = src[ d++ ];
|
message[ e++ ] = src[ d++ ];
|
||||||
|
if ( ++b == 69 ) {
|
||||||
if (++b == 69)
|
if ( c == -1 ) {
|
||||||
{
|
|
||||||
if (c == -1)
|
|
||||||
{
|
|
||||||
message[ e++ ] = '\n';
|
message[ e++ ] = '\n';
|
||||||
b = 0;
|
b = 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
message[ c ] = '\n';
|
message[ c ] = '\n';
|
||||||
b = e - c - 1;
|
b = e - c - 1;
|
||||||
c = -1;
|
c = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message[ e ] = 0;
|
message[ e ] = 0;
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@ -265,10 +218,8 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pM
|
|||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
|
||||||
|
|
||||||
if (textparms.effect==2)
|
if (textparms.effect==2)
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
|
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
|
||||||
|
|
||||||
WRITE_STRING(pMessage);
|
WRITE_STRING(pMessage);
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
@ -282,12 +233,10 @@ void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg)
|
|||||||
|
|
||||||
char c = msg[190];
|
char c = msg[190];
|
||||||
msg[190] = 0; // truncate without checking with strlen()
|
msg[190] = 0; // truncate without checking with strlen()
|
||||||
|
|
||||||
if ( pEntity )
|
if ( pEntity )
|
||||||
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
||||||
else
|
else
|
||||||
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
|
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
|
||||||
|
|
||||||
WRITE_BYTE( msg_dest );
|
WRITE_BYTE( msg_dest );
|
||||||
WRITE_STRING( msg );
|
WRITE_STRING( msg );
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
@ -305,6 +254,17 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
|
|||||||
{
|
{
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return; // no command
|
return; // no command
|
||||||
|
/*
|
||||||
|
char clCmd[256];
|
||||||
|
snprintf(g_fakecmd.args, 255, "%s%s%s%s%s", cmd,
|
||||||
|
arg1 ? " " : "", arg1 ? arg1 : "",
|
||||||
|
arg2 ? " " : "", arg2 ? arg2 : "");
|
||||||
|
clCmd[255] = 0;
|
||||||
|
CLIENT_COMMAND(pEdict, clCmd);
|
||||||
|
return;
|
||||||
|
*/
|
||||||
|
if (!cmd)
|
||||||
|
return; // no command
|
||||||
|
|
||||||
// store command
|
// store command
|
||||||
g_fakecmd.argv[0] = cmd;
|
g_fakecmd.argv[0] = cmd;
|
||||||
|
@ -47,6 +47,7 @@ static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx, cell *params)
|
|||||||
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
|
|
||||||
const char* key = get_amxstring(amx,params[1],0,iLen);
|
const char* key = get_amxstring(amx,params[1],0,iLen);
|
||||||
|
|
||||||
if ( params[3] )
|
if ( params[3] )
|
||||||
@ -68,11 +69,11 @@ static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx, cell *params)
|
|||||||
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx,cell *params)
|
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx,cell *params)
|
||||||
{
|
{
|
||||||
int iLen;
|
int iLen;
|
||||||
|
|
||||||
return g_vault.exists( get_amxstring(amx,params[1],0,iLen) ) ? 1 : 0;
|
return g_vault.exists( get_amxstring(amx,params[1],0,iLen) ) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMX_NATIVE_INFO vault_Natives[] =
|
AMX_NATIVE_INFO vault_Natives[] = {
|
||||||
{
|
|
||||||
{ "set_vaultdata", set_vaultdata },
|
{ "set_vaultdata", set_vaultdata },
|
||||||
{ "get_vaultdata", get_vaultdata },
|
{ "get_vaultdata", get_vaultdata },
|
||||||
{ "remove_vaultdata", remove_vaultdata },
|
{ "remove_vaultdata", remove_vaultdata },
|
||||||
@ -80,3 +81,5 @@ AMX_NATIVE_INFO vault_Natives[] =
|
|||||||
{ "vaultdata_exists", vaultdata_exists },
|
{ "vaultdata_exists", vaultdata_exists },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,34 +1,8 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "winres.h"
|
#include "winres.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.S.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,6,0,0
|
FILEVERSION 0,2,0,0
|
||||||
PRODUCTVERSION 1,6,0,0
|
PRODUCTVERSION 0,2,0,0
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -43,14 +17,14 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
BLOCK "000004b0"
|
BLOCK "000004b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "Comments", "AMX Mod X"
|
VALUE "Comments", "AMX Mod X\0"
|
||||||
VALUE "FileDescription", "AMX Mod X"
|
VALUE "FileDescription", "AMX Mod X\0"
|
||||||
VALUE "FileVersion", "1.60"
|
VALUE "FileVersion", "0.20\0"
|
||||||
VALUE "InternalName", "amxmodx"
|
VALUE "InternalName", "amxmodx\0"
|
||||||
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
|
VALUE "LegalCopyright", "Copyright (c) 2004, AMX Mod X Dev Team\0"
|
||||||
VALUE "OriginalFilename", "amxmodx_mm.dll"
|
VALUE "OriginalFilename", "amxx_mm.dll\0"
|
||||||
VALUE "ProductName", "AMX Mod X"
|
VALUE "ProductName", "AMX Mod X\0"
|
||||||
VALUE "ProductVersion", "1.60"
|
VALUE "ProductVersion", "0.20\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
@ -58,45 +32,3 @@ BEGIN
|
|||||||
VALUE "Translation", 0x0, 1200
|
VALUE "Translation", 0x0, 1200
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#include ""winres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||||
version 1.2.3, July 18th, 2005
|
version 1.2.1, November 17th, 2003
|
||||||
|
|
||||||
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
|
Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
@ -37,8 +37,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZLIB_VERSION "1.2.3"
|
#define ZLIB_VERSION "1.2.1"
|
||||||
#define ZLIB_VERNUM 0x1230
|
#define ZLIB_VERNUM 0x1210
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The 'zlib' compression library provides in-memory compression and
|
The 'zlib' compression library provides in-memory compression and
|
||||||
@ -53,22 +53,24 @@ extern "C" {
|
|||||||
application must provide more input and/or consume the output
|
application must provide more input and/or consume the output
|
||||||
(providing more output space) before each call.
|
(providing more output space) before each call.
|
||||||
|
|
||||||
The compressed data format used by default by the in-memory functions is
|
The compressed data format used by the in-memory functions is the zlib
|
||||||
the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
|
format, which is a zlib wrapper documented in RFC 1950, wrapped around a
|
||||||
around a deflate stream, which is itself documented in RFC 1951.
|
deflate stream, which is itself documented in RFC 1951.
|
||||||
|
|
||||||
The library also supports reading and writing files in gzip (.gz) format
|
The library also supports reading and writing files in gzip (.gz) format
|
||||||
with an interface similar to that of stdio using the functions that start
|
with an interface similar to that of stdio using the functions that start
|
||||||
with "gz". The gzip format is different from the zlib format. gzip is a
|
with "gz". The gzip format is different from the zlib format. gzip is a
|
||||||
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||||
|
|
||||||
This library can optionally read and write gzip streams in memory as well.
|
|
||||||
|
|
||||||
The zlib format was designed to be compact and fast for use in memory
|
The zlib format was designed to be compact and fast for use in memory
|
||||||
and on communications channels. The gzip format was designed for single-
|
and on communications channels. The gzip format was designed for single-
|
||||||
file compression on file systems, has a larger header than zlib to maintain
|
file compression on file systems, has a larger header than zlib to maintain
|
||||||
directory information, and uses a different, slower check method than zlib.
|
directory information, and uses a different, slower check method than zlib.
|
||||||
|
|
||||||
|
This library does not provide any functions to write gzip files in memory.
|
||||||
|
However such functions could be easily written using zlib's deflate function,
|
||||||
|
the documentation in the gzip RFC, and the examples in gzio.c.
|
||||||
|
|
||||||
The library does not install any signal handler. The decoder checks
|
The library does not install any signal handler. The decoder checks
|
||||||
the consistency of the compressed data, so the library should never
|
the consistency of the compressed data, so the library should never
|
||||||
crash even in case of corrupted input.
|
crash even in case of corrupted input.
|
||||||
@ -95,36 +97,13 @@ typedef struct z_stream_s {
|
|||||||
free_func zfree; /* used to free the internal state */
|
free_func zfree; /* used to free the internal state */
|
||||||
voidpf opaque; /* private data object passed to zalloc and zfree */
|
voidpf opaque; /* private data object passed to zalloc and zfree */
|
||||||
|
|
||||||
int data_type; /* best guess about the data type: binary or text */
|
int data_type; /* best guess about the data type: ascii or binary */
|
||||||
uLong adler; /* adler32 value of the uncompressed data */
|
uLong adler; /* adler32 value of the uncompressed data */
|
||||||
uLong reserved; /* reserved for future use */
|
uLong reserved; /* reserved for future use */
|
||||||
} z_stream;
|
} z_stream;
|
||||||
|
|
||||||
typedef z_stream FAR *z_streamp;
|
typedef z_stream FAR *z_streamp;
|
||||||
|
|
||||||
/*
|
|
||||||
gzip header information passed to and from zlib routines. See RFC 1952
|
|
||||||
for more details on the meanings of these fields.
|
|
||||||
*/
|
|
||||||
typedef struct gz_header_s {
|
|
||||||
int text; /* true if compressed data believed to be text */
|
|
||||||
uLong time; /* modification time */
|
|
||||||
int xflags; /* extra flags (not used when writing a gzip file) */
|
|
||||||
int os; /* operating system */
|
|
||||||
Bytef *extra; /* pointer to extra field or Z_NULL if none */
|
|
||||||
uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
|
|
||||||
uInt extra_max; /* space at extra (only when reading header) */
|
|
||||||
Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
|
|
||||||
uInt name_max; /* space at name (only when reading header) */
|
|
||||||
Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
|
|
||||||
uInt comm_max; /* space at comment (only when reading header) */
|
|
||||||
int hcrc; /* true if there was or will be a header crc */
|
|
||||||
int done; /* true when done reading gzip header (not used
|
|
||||||
when writing a gzip file) */
|
|
||||||
} gz_header;
|
|
||||||
|
|
||||||
typedef gz_header FAR *gz_headerp;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The application must update next_in and avail_in when avail_in has
|
The application must update next_in and avail_in when avail_in has
|
||||||
dropped to zero. It must update next_out and avail_out when avail_out
|
dropped to zero. It must update next_out and avail_out when avail_out
|
||||||
@ -189,13 +168,11 @@ typedef gz_header FAR *gz_headerp;
|
|||||||
#define Z_FILTERED 1
|
#define Z_FILTERED 1
|
||||||
#define Z_HUFFMAN_ONLY 2
|
#define Z_HUFFMAN_ONLY 2
|
||||||
#define Z_RLE 3
|
#define Z_RLE 3
|
||||||
#define Z_FIXED 4
|
|
||||||
#define Z_DEFAULT_STRATEGY 0
|
#define Z_DEFAULT_STRATEGY 0
|
||||||
/* compression strategy; see deflateInit2() below for details */
|
/* compression strategy; see deflateInit2() below for details */
|
||||||
|
|
||||||
#define Z_BINARY 0
|
#define Z_BINARY 0
|
||||||
#define Z_TEXT 1
|
#define Z_ASCII 1
|
||||||
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
|
|
||||||
#define Z_UNKNOWN 2
|
#define Z_UNKNOWN 2
|
||||||
/* Possible values of the data_type field (though see inflate()) */
|
/* Possible values of the data_type field (though see inflate()) */
|
||||||
|
|
||||||
@ -269,10 +246,6 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
|||||||
and with zero avail_out, it must be called again after making room in the
|
and with zero avail_out, it must be called again after making room in the
|
||||||
output buffer because there might be more output pending.
|
output buffer because there might be more output pending.
|
||||||
|
|
||||||
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
|
|
||||||
decide how much data to accumualte before producing output, in order to
|
|
||||||
maximize compression.
|
|
||||||
|
|
||||||
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
|
||||||
flushed to the output buffer and the output is aligned on a byte boundary, so
|
flushed to the output buffer and the output is aligned on a byte boundary, so
|
||||||
that the decompressor can get all input data available so far. (In particular
|
that the decompressor can get all input data available so far. (In particular
|
||||||
@ -284,7 +257,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
|||||||
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
|
||||||
restart from this point if previous compressed data has been damaged or if
|
restart from this point if previous compressed data has been damaged or if
|
||||||
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
|
||||||
compression.
|
the compression.
|
||||||
|
|
||||||
If deflate returns with avail_out == 0, this function must be called again
|
If deflate returns with avail_out == 0, this function must be called again
|
||||||
with the same value of the flush parameter and more output space (updated
|
with the same value of the flush parameter and more output space (updated
|
||||||
@ -309,8 +282,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
|||||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||||
so far (that is, total_in bytes).
|
so far (that is, total_in bytes).
|
||||||
|
|
||||||
deflate() may update strm->data_type if it can make a good guess about
|
deflate() may update data_type if it can make a good guess about
|
||||||
the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
|
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
|
||||||
binary. This field is only for information purposes and does not affect
|
binary. This field is only for information purposes and does not affect
|
||||||
the compression algorithm in any manner.
|
the compression algorithm in any manner.
|
||||||
|
|
||||||
@ -392,11 +365,11 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
|||||||
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
|
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
|
||||||
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
|
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
|
||||||
output as possible to the output buffer. Z_BLOCK requests that inflate() stop
|
output as possible to the output buffer. Z_BLOCK requests that inflate() stop
|
||||||
if and when it gets to the next deflate block boundary. When decoding the
|
if and when it get to the next deflate block boundary. When decoding the zlib
|
||||||
zlib or gzip format, this will cause inflate() to return immediately after
|
or gzip format, this will cause inflate() to return immediately after the
|
||||||
the header and before the first block. When doing a raw inflate, inflate()
|
header and before the first block. When doing a raw inflate, inflate() will
|
||||||
will go ahead and process the first block, and will return when it gets to
|
go ahead and process the first block, and will return when it gets to the end
|
||||||
the end of that block, or when it runs out of data.
|
of that block, or when it runs out of data.
|
||||||
|
|
||||||
The Z_BLOCK option assists in appending to or combining deflate streams.
|
The Z_BLOCK option assists in appending to or combining deflate streams.
|
||||||
Also to assist in this, on return inflate() will set strm->data_type to the
|
Also to assist in this, on return inflate() will set strm->data_type to the
|
||||||
@ -428,7 +401,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
|||||||
because Z_BLOCK is used.
|
because Z_BLOCK is used.
|
||||||
|
|
||||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
below), inflate sets strm-adler to the adler32 checksum of the dictionary
|
||||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
strm->adler to the adler32 checksum of all output produced so far (that is,
|
||||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||||
@ -505,8 +478,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
|||||||
16 to windowBits to write a simple gzip header and trailer around the
|
16 to windowBits to write a simple gzip header and trailer around the
|
||||||
compressed data instead of a zlib wrapper. The gzip header will have no
|
compressed data instead of a zlib wrapper. The gzip header will have no
|
||||||
file name, no extra data, no comment, no modification time (set to zero),
|
file name, no extra data, no comment, no modification time (set to zero),
|
||||||
no header crc, and the operating system will be set to 255 (unknown). If a
|
no header crc, and the operating system will be set to 255 (unknown).
|
||||||
gzip stream is being written, strm->adler is a crc32 instead of an adler32.
|
|
||||||
|
|
||||||
The memLevel parameter specifies how much memory should be allocated
|
The memLevel parameter specifies how much memory should be allocated
|
||||||
for the internal compression state. memLevel=1 uses minimum memory but
|
for the internal compression state. memLevel=1 uses minimum memory but
|
||||||
@ -525,9 +497,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
|
|||||||
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
|
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
|
||||||
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
|
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
|
||||||
parameter only affects the compression ratio but not the correctness of the
|
parameter only affects the compression ratio but not the correctness of the
|
||||||
compressed output even if it is not set appropriately. Z_FIXED prevents the
|
compressed output even if it is not set appropriately.
|
||||||
use of dynamic Huffman codes, allowing for a simpler decoder for special
|
|
||||||
applications.
|
|
||||||
|
|
||||||
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
|
||||||
@ -556,9 +526,7 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
|||||||
deflateInit or deflateInit2, a part of the dictionary may in effect be
|
deflateInit or deflateInit2, a part of the dictionary may in effect be
|
||||||
discarded, for example if the dictionary is larger than the window size in
|
discarded, for example if the dictionary is larger than the window size in
|
||||||
deflate or deflate2. Thus the strings most likely to be useful should be
|
deflate or deflate2. Thus the strings most likely to be useful should be
|
||||||
put at the end of the dictionary, not at the front. In addition, the
|
put at the end of the dictionary, not at the front.
|
||||||
current implementation of deflate will use at most the window size minus
|
|
||||||
262 bytes of the provided dictionary.
|
|
||||||
|
|
||||||
Upon return of this function, strm->adler is set to the adler32 value
|
Upon return of this function, strm->adler is set to the adler32 value
|
||||||
of the dictionary; the decompressor may later use this value to determine
|
of the dictionary; the decompressor may later use this value to determine
|
||||||
@ -624,23 +592,6 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
|||||||
if strm->avail_out was zero.
|
if strm->avail_out was zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
|
|
||||||
int good_length,
|
|
||||||
int max_lazy,
|
|
||||||
int nice_length,
|
|
||||||
int max_chain));
|
|
||||||
/*
|
|
||||||
Fine tune deflate's internal compression parameters. This should only be
|
|
||||||
used by someone who understands the algorithm used by zlib's deflate for
|
|
||||||
searching for the best matching string, and even then only by the most
|
|
||||||
fanatic optimizer trying to squeeze out the last compressed bit for their
|
|
||||||
specific input data. Read the deflate.c source code for the meaning of the
|
|
||||||
max_lazy, good_length, nice_length, and max_chain parameters.
|
|
||||||
|
|
||||||
deflateTune() can be called after deflateInit() or deflateInit2(), and
|
|
||||||
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||||
uLong sourceLen));
|
uLong sourceLen));
|
||||||
/*
|
/*
|
||||||
@ -666,30 +617,6 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
|||||||
stream state was inconsistent.
|
stream state was inconsistent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
|
||||||
gz_headerp head));
|
|
||||||
/*
|
|
||||||
deflateSetHeader() provides gzip header information for when a gzip
|
|
||||||
stream is requested by deflateInit2(). deflateSetHeader() may be called
|
|
||||||
after deflateInit2() or deflateReset() and before the first call of
|
|
||||||
deflate(). The text, time, os, extra field, name, and comment information
|
|
||||||
in the provided gz_header structure are written to the gzip header (xflag is
|
|
||||||
ignored -- the extra flags are set according to the compression level). The
|
|
||||||
caller must assure that, if not Z_NULL, name and comment are terminated with
|
|
||||||
a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
|
|
||||||
available there. If hcrc is true, a gzip header crc is included. Note that
|
|
||||||
the current versions of the command-line version of gzip (up through version
|
|
||||||
1.3.x) do not support header crc's, and will report that it is a "multi-part
|
|
||||||
gzip file" and give up.
|
|
||||||
|
|
||||||
If deflateSetHeader is not used, the default gzip header has text false,
|
|
||||||
the time set to zero, and os set to 255, with no extra, name, or comment
|
|
||||||
fields. The gzip header is returned to the default state by deflateReset().
|
|
||||||
|
|
||||||
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
|
|
||||||
stream state was inconsistent.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
||||||
int windowBits));
|
int windowBits));
|
||||||
@ -722,15 +649,14 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
|
|||||||
windowBits can also be greater than 15 for optional gzip decoding. Add
|
windowBits can also be greater than 15 for optional gzip decoding. Add
|
||||||
32 to windowBits to enable zlib and gzip decoding with automatic header
|
32 to windowBits to enable zlib and gzip decoding with automatic header
|
||||||
detection, or add 16 to decode only the gzip format (the zlib format will
|
detection, or add 16 to decode only the gzip format (the zlib format will
|
||||||
return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
|
return a Z_DATA_ERROR).
|
||||||
a crc32 instead of an adler32.
|
|
||||||
|
|
||||||
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||||
memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
|
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
|
||||||
is set to null if there is no error message. inflateInit2 does not perform
|
memLevel). msg is set to null if there is no error message. inflateInit2
|
||||||
any decompression apart from reading the zlib header if present: this will
|
does not perform any decompression apart from reading the zlib header if
|
||||||
be done by inflate(). (So next_in and avail_in may be modified, but next_out
|
present: this will be done by inflate(). (So next_in and avail_in may be
|
||||||
and avail_out are unchanged.)
|
modified, but next_out and avail_out are unchanged.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||||
@ -738,14 +664,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
|||||||
uInt dictLength));
|
uInt dictLength));
|
||||||
/*
|
/*
|
||||||
Initializes the decompression dictionary from the given uncompressed byte
|
Initializes the decompression dictionary from the given uncompressed byte
|
||||||
sequence. This function must be called immediately after a call of inflate,
|
sequence. This function must be called immediately after a call of inflate
|
||||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||||
can be determined from the adler32 value returned by that call of inflate.
|
can be determined from the adler32 value returned by this call of
|
||||||
The compressor and decompressor must use exactly the same dictionary (see
|
inflate. The compressor and decompressor must use exactly the same
|
||||||
deflateSetDictionary). For raw inflate, this function can be called
|
dictionary (see deflateSetDictionary).
|
||||||
immediately after inflateInit2() or inflateReset() and before any call of
|
|
||||||
inflate() to set the dictionary. The application must insure that the
|
|
||||||
dictionary that was used for compression is provided.
|
|
||||||
|
|
||||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||||
parameter is invalid (such as NULL dictionary) or the stream state is
|
parameter is invalid (such as NULL dictionary) or the stream state is
|
||||||
@ -796,64 +719,8 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
|
|||||||
stream state was inconsistent (such as zalloc or state being NULL).
|
stream state was inconsistent (such as zalloc or state being NULL).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
|
|
||||||
int bits,
|
|
||||||
int value));
|
|
||||||
/*
|
/*
|
||||||
This function inserts bits in the inflate input stream. The intent is
|
ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
|
||||||
that this function is used to start inflating at a bit position in the
|
|
||||||
middle of a byte. The provided bits will be used before any bytes are used
|
|
||||||
from next_in. This function should only be used with raw inflate, and
|
|
||||||
should be used before the first inflate() call after inflateInit2() or
|
|
||||||
inflateReset(). bits must be less than or equal to 16, and that many of the
|
|
||||||
least significant bits of value will be inserted in the input.
|
|
||||||
|
|
||||||
inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
|
||||||
stream state was inconsistent.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
|
|
||||||
gz_headerp head));
|
|
||||||
/*
|
|
||||||
inflateGetHeader() requests that gzip header information be stored in the
|
|
||||||
provided gz_header structure. inflateGetHeader() may be called after
|
|
||||||
inflateInit2() or inflateReset(), and before the first call of inflate().
|
|
||||||
As inflate() processes the gzip stream, head->done is zero until the header
|
|
||||||
is completed, at which time head->done is set to one. If a zlib stream is
|
|
||||||
being decoded, then head->done is set to -1 to indicate that there will be
|
|
||||||
no gzip header information forthcoming. Note that Z_BLOCK can be used to
|
|
||||||
force inflate() to return immediately after header processing is complete
|
|
||||||
and before any actual data is decompressed.
|
|
||||||
|
|
||||||
The text, time, xflags, and os fields are filled in with the gzip header
|
|
||||||
contents. hcrc is set to true if there is a header CRC. (The header CRC
|
|
||||||
was valid if done is set to one.) If extra is not Z_NULL, then extra_max
|
|
||||||
contains the maximum number of bytes to write to extra. Once done is true,
|
|
||||||
extra_len contains the actual extra field length, and extra contains the
|
|
||||||
extra field, or that field truncated if extra_max is less than extra_len.
|
|
||||||
If name is not Z_NULL, then up to name_max characters are written there,
|
|
||||||
terminated with a zero unless the length is greater than name_max. If
|
|
||||||
comment is not Z_NULL, then up to comm_max characters are written there,
|
|
||||||
terminated with a zero unless the length is greater than comm_max. When
|
|
||||||
any of extra, name, or comment are not Z_NULL and the respective field is
|
|
||||||
not present in the header, then that field is set to Z_NULL to signal its
|
|
||||||
absence. This allows the use of deflateSetHeader() with the returned
|
|
||||||
structure to duplicate the header. However if those fields are set to
|
|
||||||
allocated memory, then the application will need to save those pointers
|
|
||||||
elsewhere so that they can be eventually freed.
|
|
||||||
|
|
||||||
If inflateGetHeader is not used, then the header information is simply
|
|
||||||
discarded. The header is always checked for validity, including the header
|
|
||||||
CRC if present. inflateReset() will reset the process to discard the header
|
|
||||||
information. The application would need to call inflateGetHeader() again to
|
|
||||||
retrieve the header from the next gzip stream.
|
|
||||||
|
|
||||||
inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
|
|
||||||
stream state was inconsistent.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
|
||||||
unsigned char FAR *window));
|
unsigned char FAR *window));
|
||||||
|
|
||||||
Initialize the internal stream state for decompression using inflateBack()
|
Initialize the internal stream state for decompression using inflateBack()
|
||||||
@ -877,7 +744,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
|||||||
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
|
||||||
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
|
||||||
in_func in, void FAR *in_desc,
|
in_func in, void FAR *in_desc,
|
||||||
out_func out, void FAR *out_desc));
|
out_func out, void FAR *out_desc));
|
||||||
/*
|
/*
|
||||||
@ -946,7 +813,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
|
|||||||
that inflateBack() cannot return Z_OK.
|
that inflateBack() cannot return Z_OK.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
|
ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
|
||||||
/*
|
/*
|
||||||
All memory allocated by inflateBackInit() is freed.
|
All memory allocated by inflateBackInit() is freed.
|
||||||
|
|
||||||
@ -1220,12 +1087,6 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
|||||||
input stream, otherwise zero.
|
input stream, otherwise zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
|
||||||
/*
|
|
||||||
Returns 1 if file is being read directly without decompression, otherwise
|
|
||||||
zero.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||||
/*
|
/*
|
||||||
Flushes all pending output if necessary, closes the compressed file
|
Flushes all pending output if necessary, closes the compressed file
|
||||||
@ -1258,6 +1119,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
|
||||||
return the updated checksum. If buf is NULL, this function returns
|
return the updated checksum. If buf is NULL, this function returns
|
||||||
@ -1273,21 +1135,12 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
|
|||||||
if (adler != original_adler) error();
|
if (adler != original_adler) error();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
|
||||||
z_off_t len2));
|
|
||||||
/*
|
|
||||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
|
||||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
|
||||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
|
||||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||||
/*
|
/*
|
||||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
Update a running crc with the bytes buf[0..len-1] and return the updated
|
||||||
updated CRC-32. If buf is NULL, this function returns the required initial
|
crc. If buf is NULL, this function returns the required initial value
|
||||||
value for the for the crc. Pre- and post-conditioning (one's complement) is
|
for the crc. Pre- and post-conditioning (one's complement) is performed
|
||||||
performed within this function so it shouldn't be done by the application.
|
within this function so it shouldn't be done by the application.
|
||||||
Usage example:
|
Usage example:
|
||||||
|
|
||||||
uLong crc = crc32(0L, Z_NULL, 0);
|
uLong crc = crc32(0L, Z_NULL, 0);
|
||||||
@ -1298,16 +1151,6 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
|||||||
if (crc != original_crc) error();
|
if (crc != original_crc) error();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
|
|
||||||
|
|
||||||
/*
|
|
||||||
Combine two CRC-32 check values into one. For two sequences of bytes,
|
|
||||||
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
|
|
||||||
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
|
|
||||||
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
|
|
||||||
len2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* various hacks, don't look :) */
|
/* various hacks, don't look :) */
|
||||||
|
|
||||||
@ -1324,7 +1167,7 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
|
|||||||
int stream_size));
|
int stream_size));
|
||||||
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
||||||
const char *version, int stream_size));
|
const char *version, int stream_size));
|
||||||
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
|
||||||
unsigned char FAR *window,
|
unsigned char FAR *window,
|
||||||
const char *version,
|
const char *version,
|
||||||
int stream_size));
|
int stream_size));
|
||||||
@ -1346,7 +1189,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
|||||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
ZEXTERN const char * ZEXPORT zError OF((int err));
|
||||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
|
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
|
||||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,143 +0,0 @@
|
|||||||
#include "Binary.h"
|
|
||||||
|
|
||||||
BinaryWriter::BinaryWriter(FILE *fp)
|
|
||||||
{
|
|
||||||
m_Fp = fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BinaryWriter::WriteAddr(void *buffer, size_t size)
|
|
||||||
{
|
|
||||||
if (fwrite(buffer, size, 1, m_Fp) != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteUInt32(uint32_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(uint32_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteInt32(int32_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(int32_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteUInt16(uint16_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(uint16_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteInt16(int16_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(int16_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteUInt8(uint8_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(uint8_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteInt8(int8_t num)
|
|
||||||
{
|
|
||||||
if ( !WriteAddr(&num, sizeof(int8_t)) )
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryWriter::WriteChars(const char buffer[], size_t chars)
|
|
||||||
{
|
|
||||||
if (!chars)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fwrite(buffer, sizeof(char), chars, m_Fp) != chars)
|
|
||||||
throw -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BinaryReader::BinaryReader(FILE *fp)
|
|
||||||
{
|
|
||||||
m_Fp = fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BinaryReader::ReadAddr(void *buffer, size_t size)
|
|
||||||
{
|
|
||||||
if (fread(buffer, size, 1, m_Fp) != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t BinaryReader::ReadUInt32()
|
|
||||||
{
|
|
||||||
uint32_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(uint32_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t BinaryReader::ReadInt32()
|
|
||||||
{
|
|
||||||
int32_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(int32_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t BinaryReader::ReadUInt16()
|
|
||||||
{
|
|
||||||
uint16_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(uint16_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t BinaryReader::ReadInt16()
|
|
||||||
{
|
|
||||||
int16_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(int16_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t BinaryReader::ReadUInt8()
|
|
||||||
{
|
|
||||||
uint8_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(uint8_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t BinaryReader::ReadInt8()
|
|
||||||
{
|
|
||||||
int8_t num;
|
|
||||||
|
|
||||||
if ( !ReadAddr(&num, sizeof(int8_t)) )
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *BinaryReader::ReadChars(char buffer[], size_t chars)
|
|
||||||
{
|
|
||||||
if (!chars)
|
|
||||||
return buffer;
|
|
||||||
|
|
||||||
if (fread(buffer, sizeof(char), chars, m_Fp) != chars)
|
|
||||||
throw -1;
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
#ifndef _INCLUDE_BINARY_H
|
|
||||||
#define _INCLUDE_BINARY_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "amx.h"
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
typedef __int8 int8_t;
|
|
||||||
typedef unsigned __int8 uint8_t;
|
|
||||||
typedef __int16 int16_t;
|
|
||||||
typedef unsigned __int16 uint16_t;
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class BinaryReader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BinaryReader(FILE *fp);
|
|
||||||
//~BinaryReader();
|
|
||||||
public:
|
|
||||||
uint32_t ReadUInt32();
|
|
||||||
int32_t ReadInt32();
|
|
||||||
uint16_t ReadUInt16();
|
|
||||||
int16_t ReadInt16();
|
|
||||||
uint8_t ReadUInt8();
|
|
||||||
int8_t ReadInt8();
|
|
||||||
char *ReadChars(char buffer[], size_t chars);
|
|
||||||
private:
|
|
||||||
bool ReadAddr(void *buffer, size_t size);
|
|
||||||
private:
|
|
||||||
FILE *m_Fp;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinaryWriter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BinaryWriter(FILE *fp);
|
|
||||||
public:
|
|
||||||
void WriteUInt32(uint32_t num);
|
|
||||||
void WriteInt32(int32_t num);
|
|
||||||
void WriteUInt16(uint16_t num);
|
|
||||||
void WriteInt16(int16_t num);
|
|
||||||
void WriteUInt8(uint8_t num);
|
|
||||||
void WriteInt8(int8_t num);
|
|
||||||
void WriteChars(const char buffer[], size_t chars);
|
|
||||||
private:
|
|
||||||
bool WriteAddr(void *buffer, size_t size);
|
|
||||||
private:
|
|
||||||
FILE *m_Fp;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //_INCLUDE_BINARY_H
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
|||||||
#(C)2004-2005 AMX Mod X Development Team
|
|
||||||
# Makefile written by David "BAILOPAN" Anderson
|
|
||||||
|
|
||||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
|
||||||
|
|
||||||
OPT_FLAGS = -O3 -funroll-loops -s -pipe
|
|
||||||
DEBUG_FLAGS = -g -ggdb3
|
|
||||||
CPP = gcc
|
|
||||||
BINARY = amxxpc
|
|
||||||
|
|
||||||
OBJECTS = amx.cpp amxxpc.cpp Binary.cpp
|
|
||||||
|
|
||||||
LINK = -lz /lib/libstdc++.a
|
|
||||||
|
|
||||||
INCLUDE = -I. -L.
|
|
||||||
|
|
||||||
ifeq "$(DEBUG)" "true"
|
|
||||||
BIN_DIR = Debug
|
|
||||||
CFLAGS = $(DEBUG_FLAGS)
|
|
||||||
else
|
|
||||||
BIN_DIR = Release
|
|
||||||
CFLAGS = $(OPT_FLAGS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS += -DLINUX -DNDEBUG -Wno-deprecated -fexceptions -DHAVE_STDINT_H -DAMX_ANSIONLY -fno-rtti -static-libgcc
|
|
||||||
|
|
||||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
|
||||||
|
|
||||||
$(BIN_DIR)/%.o: %.cpp
|
|
||||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
|
||||||
|
|
||||||
all:
|
|
||||||
mkdir -p $(BIN_DIR)
|
|
||||||
$(MAKE) amxxpc
|
|
||||||
|
|
||||||
amxxpc: $(OBJ_LINUX)
|
|
||||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
|
||||||
|
|
||||||
default: all
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf Release/*.o
|
|
||||||
rm -rf Release/$(BINARY)
|
|
||||||
rm -rf Debug/*.o
|
|
||||||
rm -rf Debug/$(BINARY)
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,432 +0,0 @@
|
|||||||
/* Pawn Abstract Machine (for the Pawn language)
|
|
||||||
*
|
|
||||||
* Copyright (c) ITB CompuPhase, 1997-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$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined FREEBSD && !defined __FreeBSD__
|
|
||||||
#define __FreeBSD__
|
|
||||||
#endif
|
|
||||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
|
||||||
#include <sclinux.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef AMX_H_INCLUDED
|
|
||||||
#define AMX_H_INCLUDED
|
|
||||||
|
|
||||||
#if defined HAVE_STDINT_H
|
|
||||||
#include <stdint.h>
|
|
||||||
#else
|
|
||||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
|
||||||
#if defined HAVE_INTTYPES_H
|
|
||||||
#include <inttypes.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#endif
|
|
||||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
|
||||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
|
||||||
* here, these types are probably undefined.
|
|
||||||
*/
|
|
||||||
#if defined __MACH__
|
|
||||||
#include <ppc/types.h>
|
|
||||||
typedef unsigned short int uint16_t;
|
|
||||||
typedef unsigned long int uint32_t;
|
|
||||||
#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
|
|
||||||
#define HAVE_STDINT_H
|
|
||||||
#endif
|
|
||||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
|
||||||
#if !defined __64BIT__
|
|
||||||
#define __64BIT__
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_ALLOCA_H
|
|
||||||
#include <alloca.h>
|
|
||||||
#endif
|
|
||||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
|
||||||
#if !defined alloca
|
|
||||||
#define alloca(n) _alloca(n)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined arraysize
|
|
||||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#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 */
|
|
||||||
#if !defined AMX_NATIVE_CALL
|
|
||||||
#define AMX_NATIVE_CALL
|
|
||||||
#endif
|
|
||||||
/* calling convention for all interface functions and callback functions */
|
|
||||||
#if !defined AMXAPI
|
|
||||||
#if defined STDECL
|
|
||||||
#define AMXAPI __stdcall
|
|
||||||
#elif defined CDECL
|
|
||||||
#define AMXAPI __cdecl
|
|
||||||
#elif defined GCC_HASCLASSVISIBILITY
|
|
||||||
#define AMXAPI __attribute__ ((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define AMXAPI
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if !defined AMXEXPORT
|
|
||||||
#define AMXEXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* File format version Required AMX version
|
|
||||||
* 0 (original version) 0
|
|
||||||
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
|
|
||||||
* 2 (compressed files) 2
|
|
||||||
* 3 (public variables) 2
|
|
||||||
* 4 (opcodes SWAP.pri/alt and PUSHADDR) 4
|
|
||||||
* 5 (tagnames table) 4
|
|
||||||
* 6 (reformatted header) 6
|
|
||||||
* 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 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 */
|
|
||||||
|
|
||||||
#if !defined PAWN_CELL_SIZE
|
|
||||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
|
||||||
#endif
|
|
||||||
#if PAWN_CELL_SIZE==16
|
|
||||||
typedef uint16_t ucell;
|
|
||||||
typedef int16_t cell;
|
|
||||||
#elif PAWN_CELL_SIZE==32
|
|
||||||
typedef uint32_t ucell;
|
|
||||||
typedef int32_t cell;
|
|
||||||
#elif PAWN_CELL_SIZE==64
|
|
||||||
typedef uint64_t ucell;
|
|
||||||
typedef int64_t cell;
|
|
||||||
#else
|
|
||||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
|
||||||
#define UNLIMITED (~1u >> 1)
|
|
||||||
|
|
||||||
struct tagAMX;
|
|
||||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
|
||||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
|
||||||
cell *result, cell *params);
|
|
||||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
|
||||||
#if !defined _FAR
|
|
||||||
#define _FAR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined _MSC_VER
|
|
||||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
|
||||||
* about pragma pack in a header file */
|
|
||||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
|
||||||
#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__) && !defined AMX_NO_ALIGN
|
|
||||||
#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_NATIVE_INFO {
|
|
||||||
const char _FAR *name PACKED;
|
|
||||||
AMX_NATIVE func PACKED;
|
|
||||||
} PACKED AMX_NATIVE_INFO;
|
|
||||||
|
|
||||||
#define AMX_USERNUM 4
|
|
||||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
|
||||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
|
||||||
|
|
||||||
typedef struct tagAMX_FUNCSTUB {
|
|
||||||
ucell address PACKED;
|
|
||||||
char name[sEXPMAX+1] PACKED;
|
|
||||||
} PACKED 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
|
|
||||||
* fields are valid at all times; many fields are cached in local variables.
|
|
||||||
*/
|
|
||||||
typedef struct tagAMX {
|
|
||||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
|
||||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
|
||||||
AMX_CALLBACK callback PACKED;
|
|
||||||
AMX_DEBUG debug PACKED; /* debug callback */
|
|
||||||
/* for external functions a few registers must be accessible from the outside */
|
|
||||||
cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
|
|
||||||
cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
|
|
||||||
cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
|
|
||||||
cell hlw PACKED; /* bottom of the heap: 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 */
|
|
||||||
int flags PACKED; /* current status, see amx_Flags() */
|
|
||||||
/* user data */
|
|
||||||
long usertags[AMX_USERNUM] PACKED;
|
|
||||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
|
||||||
/* native functions can raise an error */
|
|
||||||
int error PACKED;
|
|
||||||
/* passing parameters requires a "count" field */
|
|
||||||
int paramcount;
|
|
||||||
/* the sleep opcode needs to store the full AMX status */
|
|
||||||
cell pri PACKED;
|
|
||||||
cell alt PACKED;
|
|
||||||
cell reset_stk PACKED;
|
|
||||||
cell reset_hea PACKED;
|
|
||||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
|
||||||
/* support variables for the JIT */
|
|
||||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
|
||||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
|
||||||
} PACKED AMX;
|
|
||||||
|
|
||||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
|
||||||
* structure is used internaly.
|
|
||||||
*/
|
|
||||||
typedef struct tagAMX_HEADER {
|
|
||||||
int32_t size PACKED; /* size of the "file" */
|
|
||||||
uint16_t magic PACKED; /* signature */
|
|
||||||
char file_version PACKED; /* file format version */
|
|
||||||
char amx_version PACKED; /* required version of the AMX */
|
|
||||||
int16_t flags PACKED;
|
|
||||||
int16_t defsize PACKED; /* size of a definition record */
|
|
||||||
int32_t cod PACKED; /* initial value of COD - code block */
|
|
||||||
int32_t dat PACKED; /* initial value of DAT - data block */
|
|
||||||
int32_t hea PACKED; /* initial value of HEA - start of the heap */
|
|
||||||
int32_t stp PACKED; /* initial value of STP - stack top */
|
|
||||||
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
|
|
||||||
int32_t publics PACKED; /* offset to the "public functions" table */
|
|
||||||
int32_t natives PACKED; /* offset to the "native functions" table */
|
|
||||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
|
||||||
int32_t pubvars PACKED; /* the "public variables" table */
|
|
||||||
int32_t tags PACKED; /* the "public tagnames" table */
|
|
||||||
int32_t nametable PACKED; /* name table */
|
|
||||||
} PACKED AMX_HEADER;
|
|
||||||
|
|
||||||
//This is always the same for us
|
|
||||||
#define AMX_MAGIC 0xf1e0
|
|
||||||
|
|
||||||
enum {
|
|
||||||
AMX_ERR_NONE,
|
|
||||||
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
|
||||||
AMX_ERR_EXIT, /* forced exit */
|
|
||||||
AMX_ERR_ASSERT, /* assertion failed */
|
|
||||||
AMX_ERR_STACKERR, /* stack/heap collision */
|
|
||||||
AMX_ERR_BOUNDS, /* index out of bounds */
|
|
||||||
AMX_ERR_MEMACCESS, /* invalid memory access */
|
|
||||||
AMX_ERR_INVINSTR, /* invalid instruction */
|
|
||||||
AMX_ERR_STACKLOW, /* stack underflow */
|
|
||||||
AMX_ERR_HEAPLOW, /* heap underflow */
|
|
||||||
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
|
|
||||||
AMX_ERR_NATIVE, /* native function failed */
|
|
||||||
AMX_ERR_DIVIDE, /* divide by zero */
|
|
||||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
|
||||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
|
||||||
|
|
||||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
|
||||||
AMX_ERR_FORMAT, /* invalid file format */
|
|
||||||
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
|
|
||||||
AMX_ERR_NOTFOUND, /* function not found */
|
|
||||||
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
|
|
||||||
AMX_ERR_DEBUG, /* debugger cannot run */
|
|
||||||
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
|
|
||||||
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
|
|
||||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
|
||||||
AMX_ERR_PARAMS, /* parameter error */
|
|
||||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
|
||||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
|
||||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
|
||||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
|
||||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
|
||||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
|
||||||
#define AMX_FLAG_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_EXEC_MAIN -1 /* start at program entry point */
|
|
||||||
#define AMX_EXEC_CONT -2 /* continue from last address */
|
|
||||||
|
|
||||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
|
||||||
|
|
||||||
#if !defined AMX_COMPACTMARGIN
|
|
||||||
#define AMX_COMPACTMARGIN 64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* for native functions that use floating point parameters, the following
|
|
||||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
|
||||||
* changing the bit pattern
|
|
||||||
*/
|
|
||||||
#if PAWN_CELL_SIZE==32
|
|
||||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
|
||||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
|
||||||
#elif PAWN_CELL_SIZE==64
|
|
||||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
|
||||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
|
||||||
#else
|
|
||||||
#error Unsupported cell size
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define amx_StrParam(amx,param,result) \
|
|
||||||
do { \
|
|
||||||
cell *amx_cstr_; int amx_length_; \
|
|
||||||
amx_GetAddr((amx), (param), &amx_cstr_); \
|
|
||||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
|
||||||
if (amx_length_ > 0 && \
|
|
||||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
|
||||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
|
||||||
else (result) = NULL; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
uint16_t * AMXAPI amx_Align16(uint16_t *v);
|
|
||||||
uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
|
||||||
#if defined _I64_MAX || defined HAVE_I64
|
|
||||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
|
||||||
#endif
|
|
||||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
|
||||||
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
|
||||||
int AMXAPI amx_Cleanup(AMX *amx);
|
|
||||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
|
||||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, 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_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
|
||||||
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
|
|
||||||
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
|
|
||||||
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
|
||||||
int AMXAPI amx_GetNative(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_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
|
||||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
|
||||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
|
||||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
|
||||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
|
||||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
|
||||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
|
||||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
|
||||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
|
||||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
|
||||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
|
||||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
|
||||||
int AMXAPI amx_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_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
|
||||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
|
||||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
|
||||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
|
||||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
|
||||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
|
||||||
int AMXAPI amx_StrLen(const 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_UTF8Len(const cell *cstr, int *length);
|
|
||||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
|
||||||
|
|
||||||
#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 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 /* AMX_H_INCLUDED */
|
|
@ -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 PACKED; /* file format version */
|
|
||||||
char amx_version PACKED; /* 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 */
|
|
||||||
} AMX_DBG_HDR PACKED;
|
|
||||||
#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] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_FILE PACKED;
|
|
||||||
|
|
||||||
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 */
|
|
||||||
} AMX_DBG_LINE PACKED;
|
|
||||||
|
|
||||||
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 PACKED; /* kind of symbol (function/variable) */
|
|
||||||
char vclass PACKED; /* class of symbol (global/local) */
|
|
||||||
int16_t dim PACKED; /* number of dimensions */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_SYMBOL PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_SYMDIM {
|
|
||||||
int16_t tag PACKED; /* tag for the array dimension */
|
|
||||||
ucell size PACKED; /* size of the array dimension */
|
|
||||||
} AMX_DBG_SYMDIM PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_TAG {
|
|
||||||
int16_t tag PACKED; /* tag id */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_TAG PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_MACHINE {
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
ucell address PACKED; /* address of state variable */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_MACHINE PACKED;
|
|
||||||
|
|
||||||
typedef struct tagAMX_DBG_STATE {
|
|
||||||
int16_t state PACKED; /* state id */
|
|
||||||
int16_t automaton PACKED; /* automaton id */
|
|
||||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
|
||||||
} AMX_DBG_STATE PACKED;
|
|
||||||
|
|
||||||
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;
|
|
||||||
} AMX_DBG PACKED;
|
|
||||||
|
|
||||||
#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, FILE *fp);
|
|
||||||
|
|
||||||
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,395 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "zlib.h"
|
|
||||||
#include "amx.h"
|
|
||||||
#include "amxdbg.h"
|
|
||||||
#include "amxxpc.h"
|
|
||||||
#include "Binary.h"
|
|
||||||
|
|
||||||
static PRINTF pc_printf = NULL;
|
|
||||||
|
|
||||||
void ReadFileIntoPl(abl *pl, FILE *fp);
|
|
||||||
bool CompressPl(abl *pl);
|
|
||||||
void Pl2Bh(abl *pl, BinPlugin *bh);
|
|
||||||
void WriteBh(BinaryWriter *bw, BinPlugin *bh);
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
struct abl pl32;
|
|
||||||
struct abl pl64;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
printf("debug clamp\n");
|
|
||||||
getchar();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
HINSTANCE lib = NULL;
|
|
||||||
if (FileExists("./amxxpc32.so"))
|
|
||||||
lib = dlmount("./amxxpc32.so");
|
|
||||||
else
|
|
||||||
lib = dlmount("amxxpc32.so");
|
|
||||||
#else
|
|
||||||
HINSTANCE lib = dlmount("amxxpc32.dll");
|
|
||||||
#endif
|
|
||||||
if (!lib)
|
|
||||||
{
|
|
||||||
#ifdef __linux__
|
|
||||||
printf("32bit compiler failed to instantiate: %s\n", dlerror());
|
|
||||||
#else
|
|
||||||
printf("32bit compiler failed to instantiate: %d\n", GetLastError());
|
|
||||||
#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32");
|
|
||||||
pc_printf = (PRINTF)dlsym(lib, "pc_printf");
|
|
||||||
|
|
||||||
if (!sc32 || !pc_printf)
|
|
||||||
{
|
|
||||||
#ifdef __linux__
|
|
||||||
printf("32bit compiler failed to link: %p.\n",sc32);
|
|
||||||
#else
|
|
||||||
printf("32bit compiler failed to link: %d.\n", GetLastError());
|
|
||||||
#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING);
|
|
||||||
pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n");
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
pc_printf("Usage: <file.sma> [options]\n");
|
|
||||||
pc_printf("Use -? or --help to see full options\n\n");
|
|
||||||
getchar();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help"))
|
|
||||||
{
|
|
||||||
show_help();
|
|
||||||
pc_printf("Press any key to continue.\n");
|
|
||||||
getchar();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc32(argc, argv);
|
|
||||||
|
|
||||||
char *file = FindFileName(argc, argv);
|
|
||||||
|
|
||||||
if (file == NULL)
|
|
||||||
{
|
|
||||||
pc_printf("Could not locate the output file.\n");
|
|
||||||
exit(0);
|
|
||||||
} else if (strstr(file, ".asm")) {
|
|
||||||
pc_printf("Assembler output succeeded.\n");
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
FILE *fp = fopen(file, "rb");
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
pc_printf("Could not locate output file %s (compile failed).\n", file);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
ReadFileIntoPl(&pl32, fp);
|
|
||||||
pl32.cellsize = 4;
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink(file);
|
|
||||||
|
|
||||||
HINSTANCE lib64 = NULL;
|
|
||||||
#ifdef __linux__
|
|
||||||
if (FileExists("./amxxpc64.so"))
|
|
||||||
lib64 = dlmount("./amxxpc64.so");
|
|
||||||
else
|
|
||||||
lib64 = dlmount("amxxpc64.so");
|
|
||||||
#else
|
|
||||||
lib64 = dlmount("amxxpc64.dll");
|
|
||||||
#endif
|
|
||||||
if (!lib64)
|
|
||||||
{
|
|
||||||
pc_printf("64bit compiler failed to instantiate.\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
COMPILER sc64 = (COMPILER)dlsym(lib64, "Compile64");
|
|
||||||
|
|
||||||
if (!sc64)
|
|
||||||
{
|
|
||||||
#ifdef __linux__
|
|
||||||
pc_printf("64bit compiler failed to link: %s.\n", dlerror());
|
|
||||||
#else
|
|
||||||
pc_printf("64bit compiler failed to link: %d.\n", GetLastError());
|
|
||||||
#endif
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc64(argc, argv);
|
|
||||||
|
|
||||||
dlclose(lib64);
|
|
||||||
|
|
||||||
if (file == NULL)
|
|
||||||
{
|
|
||||||
pc_printf("Could not locate the output file on second pass.\n");
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
FILE *fp = fopen(file, "rb");
|
|
||||||
if (fp == NULL)
|
|
||||||
{
|
|
||||||
pc_printf("Could not locate output file on second pass (compile failed).\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
ReadFileIntoPl(&pl64, fp);
|
|
||||||
pl64.cellsize = 8;
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////
|
|
||||||
// COMPRSSION
|
|
||||||
/////////////
|
|
||||||
|
|
||||||
CompressPl(&pl32);
|
|
||||||
|
|
||||||
CompressPl(&pl64);
|
|
||||||
|
|
||||||
char *newfile = new char[strlen(file)+3];
|
|
||||||
strcpy(newfile, file);
|
|
||||||
if (!strstr(file, ".amxx") && !strstr(file, ".AMXX"))
|
|
||||||
strcat(newfile, "x");
|
|
||||||
|
|
||||||
FILE *fp = fopen(newfile, "wb");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
pc_printf("Error trying to write file %s.\n", newfile);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BinPlugin bh32, bh64;
|
|
||||||
|
|
||||||
Pl2Bh(&pl32, &bh32);
|
|
||||||
Pl2Bh(&pl64, &bh64);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
BinaryWriter bw(fp);
|
|
||||||
|
|
||||||
bw.WriteUInt32(MAGIC_HEADER2);
|
|
||||||
bw.WriteUInt16(MAGIC_VERSION);
|
|
||||||
bw.WriteUInt8(2);
|
|
||||||
|
|
||||||
//base header
|
|
||||||
int baseaddr = sizeof(int32_t) + sizeof(int16_t) + sizeof(int8_t);
|
|
||||||
//entry is 4 ints and a byte
|
|
||||||
int entrysize = (sizeof(int32_t) * 4) + sizeof(int8_t);
|
|
||||||
//extend this by the two entries we have
|
|
||||||
baseaddr += entrysize * 2;
|
|
||||||
|
|
||||||
bh32.offs = baseaddr;
|
|
||||||
bh64.offs = bh32.offs + bh32.disksize;
|
|
||||||
|
|
||||||
WriteBh(&bw, &bh32);
|
|
||||||
WriteBh(&bw, &bh64);
|
|
||||||
bw.WriteChars(pl32.cmp, pl32.cmpsize);
|
|
||||||
bw.WriteChars(pl64.cmp, pl64.cmpsize);
|
|
||||||
} catch (...) {
|
|
||||||
fclose(fp);
|
|
||||||
unlink(file);
|
|
||||||
pc_printf("Error, failed to write binary\n");
|
|
||||||
dlclose(lib);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
unlink(file);
|
|
||||||
|
|
||||||
pc_printf("Done.\n");
|
|
||||||
|
|
||||||
dlclose(lib);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteBh(BinaryWriter *bw, BinPlugin *bh)
|
|
||||||
{
|
|
||||||
bw->WriteUInt8(bh->cellsize);
|
|
||||||
bw->WriteUInt32(bh->disksize);
|
|
||||||
bw->WriteUInt32(bh->imagesize);
|
|
||||||
bw->WriteUInt32(bh->memsize);
|
|
||||||
bw->WriteUInt32(bh->offs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pl2Bh(abl *pl, BinPlugin *bh)
|
|
||||||
{
|
|
||||||
bh->cellsize = pl->cellsize;
|
|
||||||
bh->disksize = pl->cmpsize;
|
|
||||||
bh->imagesize = pl->size;
|
|
||||||
bh->memsize = pl->stp;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CompressPl(abl *pl)
|
|
||||||
{
|
|
||||||
pl->cmpsize = compressBound(pl->size);
|
|
||||||
pl->cmp = new char[pl->cmpsize];
|
|
||||||
|
|
||||||
int err = compress((Bytef *)(pl->cmp), (uLongf *)&(pl->cmpsize), (const Bytef *)(pl->data), pl->size);
|
|
||||||
|
|
||||||
delete [] pl->data;
|
|
||||||
pl->data = NULL;
|
|
||||||
|
|
||||||
if (err != Z_OK)
|
|
||||||
{
|
|
||||||
pc_printf("internal error - compression failed on first pass: %d\n", err);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//As of Small 3.0, there's extra debug info in the file we need to get out.
|
|
||||||
//Sadly this is placed somewhere really inconvenient and I'm mad.
|
|
||||||
void ReadFileIntoPl(abl *pl, FILE *fp)
|
|
||||||
{
|
|
||||||
AMX_HEADER hdr;
|
|
||||||
AMX_DBG_HDR dbg;
|
|
||||||
fread(&hdr, sizeof(hdr), 1, fp);
|
|
||||||
amx_Align32((uint32_t *)&hdr.stp);
|
|
||||||
amx_Align32((uint32_t *)&hdr.size);
|
|
||||||
pl->stp = hdr.stp;
|
|
||||||
int size = hdr.size;
|
|
||||||
if (hdr.flags & AMX_FLAG_DEBUG)
|
|
||||||
{
|
|
||||||
fseek(fp, hdr.size, SEEK_SET);
|
|
||||||
fread(&dbg, sizeof(dbg), 1, fp);
|
|
||||||
size += dbg.size;
|
|
||||||
}
|
|
||||||
pl->size = size;
|
|
||||||
pl->data = new char[size];
|
|
||||||
rewind(fp);
|
|
||||||
fread(pl->data, 1, size, fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
//we get the full name of the file here
|
|
||||||
//our job is to a] switch the .sma extension to .amx
|
|
||||||
// and to b] strip everything but the trailing name
|
|
||||||
char *swiext(const char *file, const char *ext, int isO)
|
|
||||||
{
|
|
||||||
int i = 0, pos = -1, j = 0;
|
|
||||||
int fileLen = strlen(file);
|
|
||||||
int extLen = strlen(ext);
|
|
||||||
int max = 0, odirFlag = -1;
|
|
||||||
|
|
||||||
for (i=fileLen-1; i>=0; i--)
|
|
||||||
{
|
|
||||||
if (file[i] == '.' && pos == -1)
|
|
||||||
{
|
|
||||||
pos = i+1;
|
|
||||||
}
|
|
||||||
if ((file[i] == '/' || file[i] == '\\') && !isO)
|
|
||||||
{
|
|
||||||
odirFlag = i+1;
|
|
||||||
//realign pos - we've just stripped fileLen-i chars
|
|
||||||
pos -= i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *newbuffer = new char[fileLen+strlen(ext)+2];
|
|
||||||
fileLen += strlen(ext);
|
|
||||||
if (odirFlag == -1)
|
|
||||||
{
|
|
||||||
strcpy(newbuffer, file);
|
|
||||||
} else {
|
|
||||||
strcpy(newbuffer, &(file[odirFlag]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos > -1)
|
|
||||||
{
|
|
||||||
for (i=pos; i<fileLen; i++)
|
|
||||||
{
|
|
||||||
if (j < extLen)
|
|
||||||
newbuffer[i] = ext[j++];
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newbuffer[i] = '\0';
|
|
||||||
} else {
|
|
||||||
strcat(newbuffer, ".");
|
|
||||||
strcat(newbuffer, ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *FindFileName(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
int save = -1;
|
|
||||||
for (i=1; i<argc; i++)
|
|
||||||
{
|
|
||||||
if (argv[i][0] == '-' && argv[i][1] == 'o')
|
|
||||||
{
|
|
||||||
if (argv[i][2] == ' ' || argv[i][2] == '\0')
|
|
||||||
{
|
|
||||||
if (i == argc-1)
|
|
||||||
return NULL;
|
|
||||||
return swiext(&argv[i+1][2], "amx", 1);
|
|
||||||
} else {
|
|
||||||
return swiext(&(argv[i][2]), "amx", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (argv[i][0] != '-')
|
|
||||||
{
|
|
||||||
save = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save>0)
|
|
||||||
{
|
|
||||||
return swiext(argv[save], "amx", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void show_help()
|
|
||||||
{
|
|
||||||
printf("Options:\n");
|
|
||||||
printf("\t-A<num> alignment in bytes of the data segment and the stack\n");
|
|
||||||
printf("\t-a output assembler code\n");
|
|
||||||
printf("\t-C[+/-] compact encoding for output file (default=-)\n");
|
|
||||||
printf("\t-c<name> codepage name or number; e.g. 1252 for Windows Latin-1\n");
|
|
||||||
printf("\t-Dpath active directory path\n");
|
|
||||||
printf("\t-d0 no symbolic information, no run-time checks\n");
|
|
||||||
printf("\t-d1 [default] run-time checks, no symbolic information\n");
|
|
||||||
printf("\t-d2 full debug information and dynamic checking\n");
|
|
||||||
printf("\t-d3 full debug information, dynamic checking, no optimization\n");
|
|
||||||
printf("\t-e<name> set name of error file (quiet compile)\n");
|
|
||||||
printf("\t-H<hwnd> window handle to send a notification message on finish\n");
|
|
||||||
printf("\t-i<name> path for include files\n");
|
|
||||||
printf("\t-l create list file (preprocess only)\n");
|
|
||||||
printf("\t-o<name> set base name of output file\n");
|
|
||||||
printf("\t-p<name> set name of \"prefix\" file\n");
|
|
||||||
printf("\t-r[name] write cross reference report to console or to specified file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
bool FileExists(const char *file)
|
|
||||||
{
|
|
||||||
FILE *fp = fopen(file, "rb");
|
|
||||||
if (!fp)
|
|
||||||
return false;
|
|
||||||
fclose(fp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
#ifndef _AMXXSC_INCLUDE_H
|
|
||||||
#define _AMXXSC_INCLUDE_H
|
|
||||||
|
|
||||||
#define VERSION_STRING "1.60-300"
|
|
||||||
#define VERSION 03000
|
|
||||||
#define MAGIC_HEADER 0x414D5842
|
|
||||||
#define MAGIC_HEADER2 0x414D5858
|
|
||||||
#define MAGIC_VERSION 0x0300
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
# include <dlfcn.h>
|
|
||||||
#else
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
# define dlmount(x) dlopen(x, RTLD_NOW|RTLD_GLOBAL)
|
|
||||||
typedef void* HINSTANCE;
|
|
||||||
#else
|
|
||||||
# define dlsym(x, s) GetProcAddress(x, s)
|
|
||||||
# define dlmount(x) LoadLibrary(x)
|
|
||||||
# define dlclose(x) FreeLibrary(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "zlib.h"
|
|
||||||
#include "Binary.h"
|
|
||||||
|
|
||||||
typedef int (*COMPILER)(int argc, char **argv);
|
|
||||||
typedef int (*PRINTF)(const char *message, ...);
|
|
||||||
|
|
||||||
char *FindFileName(int argc, char **argv);
|
|
||||||
char *swiext(const char *file, const char *ext);
|
|
||||||
void show_help();
|
|
||||||
|
|
||||||
|
|
||||||
struct ablhdr
|
|
||||||
{
|
|
||||||
int magic;
|
|
||||||
char size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct abl
|
|
||||||
{
|
|
||||||
long stp;
|
|
||||||
char cellsize;
|
|
||||||
int size;
|
|
||||||
long cmpsize;
|
|
||||||
char *data;
|
|
||||||
char *cmp;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BinHeader
|
|
||||||
{
|
|
||||||
int32_t magic;
|
|
||||||
int16_t version;
|
|
||||||
int8_t plugins;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BinPlugin
|
|
||||||
{
|
|
||||||
int8_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
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
bool FileExists(const char *file);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif //_AMXXSC_INCLUDE_H
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user