2004-03-05 21:03:14 +00:00
/* 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 .
*/
2004-01-31 20:56:22 +00:00
2004-10-29 20:35:23 +00:00
# ifdef __linux__
# include <sys/mman.h>
# endif
2004-03-24 01:35:44 +00:00
# include "amxmodx.h"
2004-01-31 20:56:22 +00:00
# include "osdep.h" // sleep, etc
# include "CFile.h"
2004-07-21 20:00:10 +00:00
# include "amxxfile.h"
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > g_modules ;
2004-01-31 20:56:22 +00:00
CList < CScript , AMX * > g_loadedscripts ;
2004-04-03 19:15:06 +00:00
CModule * g_CurrentlyCalledModule = NULL ; // The module we are in at the moment; NULL otherwise
2004-04-29 17:16:28 +00:00
// also NULL for non-amxx modules
// This is needed so we know which module called a function
2004-04-03 19:15:06 +00:00
ModuleCallReason g_ModuleCallReason ;
2004-01-31 20:56:22 +00:00
extern const char * no_function ; // stupid work around
2004-03-31 18:02:37 +00:00
2004-01-31 20:56:22 +00:00
void report_error ( int code , char * fmt , . . . )
{
va_list argptr ;
char string [ 256 ] ;
* string = 0 ;
va_start ( argptr , fmt ) ;
vsnprintf ( string , 255 , fmt , argptr ) ;
string [ 255 ] = 0 ;
va_end ( argptr ) ;
if ( * string ) {
2004-06-28 18:12:26 +00:00
AMXXLOG_Log ( " Error: " ) ;
2004-03-31 18:02:37 +00:00
AMXXLOG_Log ( string ) ;
2004-01-31 20:56:22 +00:00
}
2004-06-28 18:12:26 +00:00
else
{
AMXXLOG_Log ( " !!! There was an unexpected module error. " ) ;
AMXXLOG_Log ( " The server may not work correctly. " ) ;
}
2004-01-31 20:56:22 +00:00
}
void print_srvconsole ( char * fmt , . . . )
{
2004-04-29 17:16:28 +00:00
va_list argptr ;
char string [ 256 ] ;
va_start ( argptr , fmt ) ;
vsnprintf ( string , 255 , fmt , argptr ) ;
string [ 255 ] = 0 ;
va_end ( argptr ) ;
SERVER_PRINT ( string ) ;
2004-01-31 20:56:22 +00:00
}
void * alloc_amxmemory ( void * * p , int size )
{
* p = new unsigned char [ size ] ;
return * p ;
}
void free_amxmemory ( void * * ptr )
{
delete [ ] * ptr ;
* ptr = 0 ;
}
2004-09-08 07:05:16 +00:00
int load_amxscript ( AMX * amx , void * * program , const char * filename , char error [ 64 ] , int debug )
2004-07-21 20:00:10 +00:00
{
* error = 0 ;
2004-07-22 14:55:16 +00:00
CAmxxReader reader ( filename , SMALL_CELL_SIZE / 8 ) ;
2004-07-21 20:00:10 +00:00
if ( reader . GetStatus ( ) = = CAmxxReader : : Err_None )
{
size_t bufSize = reader . GetBufferSize ( ) ;
if ( bufSize ! = 0 )
{
* program = ( void * ) ( new char [ bufSize ] ) ;
if ( ! * program )
{
strcpy ( error , " Failed to allocate memory " ) ;
return ( amx - > error = AMX_ERR_MEMORY ) ;
}
reader . GetSection ( * program ) ;
}
}
2004-01-31 20:56:22 +00:00
2004-07-21 20:00:10 +00:00
switch ( reader . GetStatus ( ) )
{
case CAmxxReader : : Err_None :
break ;
case CAmxxReader : : Err_FileOpen :
strcpy ( error , " Plugin file open error " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
case CAmxxReader : : Err_FileRead :
strcpy ( error , " Plugin file read error " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
case CAmxxReader : : Err_InvalidParam :
strcpy ( error , " Internal error: Invalid parameter " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
case CAmxxReader : : Err_FileInvalid :
strcpy ( error , " Invalid Plugin " ) ;
return ( amx - > error = AMX_ERR_FORMAT ) ;
2004-07-22 14:55:16 +00:00
case CAmxxReader : : Err_SectionNotFound :
strcpy ( error , " Searched section not found (.amxx) " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
case CAmxxReader : : Err_DecompressorInit :
strcpy ( error , " Decompressor initialization failed " ) ;
return ( amx - > error = AMX_ERR_INIT ) ;
case CAmxxReader : : Err_Decompress :
strcpy ( error , " Internal error: Decompress " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
2004-08-24 04:30:13 +00:00
case CAmxxReader : : Err_OldFile :
strcpy ( error , " Plugin uses deprecated format. Update compiler " ) ;
2004-07-21 20:00:10 +00:00
default :
strcpy ( error , " Unknown error " ) ;
return ( amx - > error = AMX_ERR_NOTFOUND ) ;
}
// check for magic
AMX_HEADER * hdr = ( AMX_HEADER * ) * program ;
uint16_t magic = hdr - > magic ;
amx_Align16 ( & magic ) ;
if ( magic ! = AMX_MAGIC )
{
strcpy ( error , " Invalid Plugin " ) ;
return ( amx - > error = AMX_ERR_FORMAT ) ;
}
2004-09-17 00:27:28 +00:00
if ( ( int ) CVAR_GET_FLOAT ( " amx_debug " ) > = 2 | | debug )
2004-09-08 07:05:16 +00:00
{
//automatic debug mode
hdr - > flags | = AMX_FLAG_LINEOPS ;
2004-09-14 19:27:55 +00:00
hdr - > flags | = AMX_FLAG_DEBUG ;
2004-09-08 07:05:16 +00:00
}
2004-07-21 20:00:10 +00:00
int err ;
memset ( amx , 0 , sizeof ( * amx ) ) ;
2004-04-29 17:16:28 +00:00
if ( ( err = amx_Init ( amx , * program ) ) ! = AMX_ERR_NONE )
{
sprintf ( error , " Load error %d (invalid file format or version) " , err ) ;
return ( amx - > error = AMX_ERR_INIT ) ;
}
2004-01-31 20:56:22 +00:00
# ifdef JIT
2004-04-29 17:16:28 +00:00
void * np = new char [ amx - > code_size ] ;
void * rt = new char [ amx - > reloc_size ] ;
if ( ! np | | ( ! rt & & amx - > reloc_size > 0 ) )
{
delete [ ] np ;
delete [ ] rt ;
strcpy ( error , " Failed to initialize plugin " ) ;
return ( amx - > error = AMX_ERR_INIT ) ;
}
2004-10-29 20:35:23 +00:00
if ( ( err = amx_InitJIT ( amx , rt , np ) ) = = AMX_ERR_NONE )
2004-04-29 17:16:28 +00:00
{
//amx->base = (unsigned char FAR *)realloc( np, amx->code_size );
2004-10-29 20:35:23 +00:00
# ifndef __linux__
2004-04-29 17:16:28 +00:00
amx - > base = new unsigned char [ amx - > code_size ] ;
2004-10-29 20:35:23 +00:00
# else
posix_memalign ( ( void * * ) & ( amx - > base ) , sysconf ( _SC_PAGESIZE ) , amx - > code_size ) ;
mprotect ( ( void * ) amx - > base , amx - > code_size , PROT_READ | PROT_WRITE | PROT_EXEC ) ;
# endif
2004-04-29 17:16:28 +00:00
if ( amx - > base )
memcpy ( amx - > base , np , amx - > code_size ) ;
delete [ ] np ;
delete [ ] rt ;
delete [ ] * program ;
( * program ) = amx - > base ;
if ( * program = = 0 ) {
strcpy ( error , " Failed to allocate memory " ) ;
return ( amx - > error = AMX_ERR_MEMORY ) ;
}
}
else
{
delete [ ] np ;
delete [ ] rt ;
2004-10-29 20:35:23 +00:00
sprintf ( error , " Failed to initialize plugin (%d) " , err ) ;
2004-04-29 17:16:28 +00:00
return ( amx - > error = AMX_ERR_INIT_JIT ) ;
2004-01-31 20:56:22 +00:00
}
# endif
2004-04-29 17:16:28 +00:00
CScript * aa = new CScript ( amx , * program , filename ) ;
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
if ( aa = = 0 )
{
strcpy ( error , " Failed to allocate memory " ) ;
return ( amx - > error = AMX_ERR_MEMORY ) ;
}
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
g_loadedscripts . put ( aa ) ;
2004-07-23 16:55:53 +00:00
amx - > sysreq_d = 0 ;
2004-04-29 17:16:28 +00:00
return set_amxnatives ( amx , error ) ;
2004-01-31 20:56:22 +00:00
}
2004-09-12 04:03:54 +00:00
const char * StrCaseStr ( const char * as , const char * bs )
{
static char a [ 256 ] ;
static char b [ 256 ] ;
unsigned int i = 0 ;
unsigned int len = strlen ( as ) ;
if ( len > 254 )
len = 254 ;
for ( i = 0 ; i < len ; i + + )
{
a [ i ] = tolower ( as [ i ] ) ;
}
a [ len ] = 0 ;
len = strlen ( bs ) ;
if ( len > 254 )
len = 254 ;
for ( i = 0 ; i < len ; i + + )
{
b [ i ] = tolower ( bs [ i ] ) ;
}
b [ len ] = 0 ;
return strstr ( a , b ) ;
}
2004-09-09 05:16:53 +00:00
//BAILOPAN
int CheckModules ( AMX * amx , char error [ 64 ] )
{
2004-09-10 15:52:48 +00:00
int idx = 0 , flag = - 1 ;
2004-09-09 05:16:53 +00:00
if ( amx_FindPublic ( amx , " plugin_modules " , & idx ) = = AMX_ERR_NONE )
{
cell retVal = 0 ;
int err = 0 ;
if ( ( err = amx_Exec ( amx , & retVal , idx , 0 ) ) = = AMX_ERR_NONE )
{
unsigned int i = 0 ;
while ( ! CurModuleList . empty ( ) )
{
if ( ! flag )
{
CurModuleList . pop ( ) ;
continue ;
}
//assume module is not found
flag = 0 ;
2004-09-12 03:48:21 +00:00
for ( CList < CModule , const char * > : : iterator pMod = g_modules . begin ( ) ; pMod ; + + pMod )
2004-09-09 05:16:53 +00:00
{
if ( strcmpi ( CurModuleList . front ( ) . c_str ( ) , " dbi " ) = = 0 )
{
2004-09-12 04:03:54 +00:00
if ( StrCaseStr ( ( * pMod ) . getName ( ) , " sql " ) | | strstr ( ( * pMod ) . getName ( ) , " dbi " ) )
2004-09-09 05:16:53 +00:00
{
// the module checks in
flag = 1 ;
break ;
}
} else {
if ( strcmpi ( ( * pMod ) . getName ( ) , CurModuleList . front ( ) . c_str ( ) ) = = 0 )
{
flag = 1 ;
break ;
}
}
}
//module was not found
if ( ! flag )
{
sprintf ( error , " Module \" %s \" required for plugin. Check modules.ini. " , CurModuleList . front ( ) . c_str ( ) ) ;
}
CurModuleList . pop ( ) ;
}
} else {
AMXXLOG_Log ( " [AMXX] Run time error %d on line %ld during module check. " , err , amx - > curline ) ;
//could not execute
return - 1 ; //bad! very bad!
}
} else {
return - 1 ;
}
return flag ;
}
2004-01-31 20:56:22 +00:00
int set_amxnatives ( AMX * amx , char error [ 64 ] )
{
2004-09-12 03:48:21 +00:00
for ( CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ; a ; + + a )
2004-01-31 20:56:22 +00:00
{
for ( CList < AMX_NATIVE_INFO * > : : iterator cc =
2004-03-31 18:02:37 +00:00
( * a ) . m_Natives . begin ( ) ; cc ; + + cc )
2004-01-31 20:56:22 +00:00
amx_Register ( amx , * cc , - 1 ) ;
}
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
amx_Register ( amx , string_Natives , - 1 ) ;
amx_Register ( amx , float_Natives , - 1 ) ;
amx_Register ( amx , file_Natives , - 1 ) ;
amx_Register ( amx , amxmod_Natives , - 1 ) ;
amx_Register ( amx , power_Natives , - 1 ) ;
amx_Register ( amx , time_Natives , - 1 ) ;
amx_Register ( amx , vault_Natives , - 1 ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
if ( amx_Register ( amx , core_Natives , - 1 ) ! = AMX_ERR_NONE )
{
2004-09-10 15:52:48 +00:00
//HACKHACK - if we get here, nullify the plugin's native table
//then reregister the one native we need
// - BAILOPAN
String save ;
save . assign ( no_function ) ;
amx_NullNativeTable ( amx ) ;
AMX_NATIVE_INFO p [ ] = {
{ " require_module " , require_module } ,
{ NULL , NULL } ,
} ;
amx_Register ( amx , p , - 1 ) ;
2004-09-12 04:35:24 +00:00
if ( CheckModules ( amx , error ) = = - 1 | | * error = = 0 )
2004-09-09 05:16:53 +00:00
{
2004-09-10 15:52:48 +00:00
sprintf ( error , " Plugin uses an unknown function (name \" %s \" ) - check your modules.ini. " , save . c_str ( ) ) ;
2004-09-09 05:16:53 +00:00
}
2004-01-31 20:56:22 +00:00
return ( amx - > error = AMX_ERR_NATIVE ) ;
}
2004-04-29 17:16:28 +00:00
2004-09-09 05:16:53 +00:00
CheckModules ( amx , error ) ;
2004-01-31 20:56:22 +00:00
return AMX_ERR_NONE ;
}
int unload_amxscript ( AMX * amx , void * * program )
{
2004-04-29 17:16:28 +00:00
CList < CScript , AMX * > : : iterator a = g_loadedscripts . find ( amx ) ;
if ( a ) a . remove ( ) ;
delete [ ] * program ;
* program = 0 ;
return AMX_ERR_NONE ;
2004-01-31 20:56:22 +00:00
}
AMX * get_amxscript ( int id , void * * code , const char * * filename )
{
CList < CScript , AMX * > : : iterator a = g_loadedscripts . begin ( ) ;
while ( a & & id - - )
+ + a ;
if ( a ) {
* filename = ( * a ) . getName ( ) ;
* code = ( * a ) . getCode ( ) ;
return ( * a ) . getAMX ( ) ;
}
return 0 ;
}
const char * get_amxscriptname ( AMX * amx )
{
CList < CScript , AMX * > : : iterator a = g_loadedscripts . find ( amx ) ;
return a ? ( * a ) . getName ( ) : " " ;
}
void get_modname ( char * buffer )
{
2004-08-13 08:46:04 +00:00
strcpy ( buffer , g_mod_name . c_str ( ) ) ;
2004-01-31 20:56:22 +00:00
}
char * build_pathname ( char * fmt , . . . )
{
static char string [ 256 ] ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
int b ;
int a = b = snprintf ( string , 255 ,
# ifndef __linux__
" %s \\ " ,
# else
" %s/ " ,
# endif
2004-08-13 08:46:04 +00:00
g_mod_name . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
va_list argptr ;
va_start ( argptr , fmt ) ;
a + = vsnprintf ( & string [ a ] , 255 - a , fmt , argptr ) ;
string [ a ] = 0 ;
va_end ( argptr ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
char * path = & string [ b ] ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
while ( * path )
{
# ifndef __linux__
if ( * path = = ' / ' ) * path = ' \\ ' ;
# else
if ( * path = = ' \\ ' ) * path = ' / ' ;
# endif
+ + path ;
}
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
return string ;
}
2004-03-05 18:32:29 +00:00
// build pathname based on addons dir
char * build_pathname_addons ( char * fmt , . . . )
{
static char string [ 256 ] ;
2004-04-29 17:16:28 +00:00
2004-03-05 18:32:29 +00:00
va_list argptr ;
va_start ( argptr , fmt ) ;
vsnprintf ( string , 255 , fmt , argptr ) ;
va_end ( argptr ) ;
2004-04-29 17:16:28 +00:00
2004-03-05 18:32:29 +00:00
char * path = string ;
2004-04-29 17:16:28 +00:00
2004-03-05 18:32:29 +00:00
while ( * path )
{
# ifndef __linux__
if ( * path = = ' / ' ) * path = ' \\ ' ;
# else
if ( * path = = ' \\ ' ) * path = ' / ' ;
# endif
+ + path ;
}
2004-04-29 17:16:28 +00:00
2004-03-05 18:32:29 +00:00
return string ;
}
2004-01-31 20:56:22 +00:00
int add_amxnatives ( module_info_s * info , AMX_NATIVE_INFO * natives )
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
while ( a )
{
if ( ( * a ) . getInfo ( ) = = info )
{
AMX_NATIVE_INFO * * aa = new AMX_NATIVE_INFO * ( natives ) ;
if ( aa = = 0 ) return AMX_ERR_NATIVE ;
2004-03-31 18:02:37 +00:00
( * a ) . m_Natives . put ( aa ) ;
2004-01-31 20:56:22 +00:00
return AMX_ERR_NONE ;
}
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
+ + a ;
}
2004-04-29 17:16:28 +00:00
return AMX_ERR_NATIVE ;
2004-01-31 20:56:22 +00:00
}
bool validFile ( const char * file )
{
2004-04-29 17:16:28 +00:00
const char * a = 0 ;
while ( * file )
if ( * file + + = = ' . ' )
a = file ;
2004-01-31 20:56:22 +00:00
# ifndef __linux__
2004-04-29 17:16:28 +00:00
return ( a & & ! strcmp ( a , " dll " ) ) ;
2004-01-31 20:56:22 +00:00
# else
2004-04-29 17:16:28 +00:00
return ( a & & ! strcmp ( a , " so " ) ) ;
2004-01-31 20:56:22 +00:00
# endif
}
2004-09-12 03:48:21 +00:00
void ConvertModuleName ( const char * pathString , String & path )
{
# if SMALL_CELL_SIZE==64
char * ptr = strstr ( pathString , " i386 " ) ;
if ( ptr )
{
//attempt to fix the binary name
* ptr = 0 ;
path . assign ( pathString ) ;
path . append ( " amd64.so " ) ;
} else {
ptr = strstr ( pathString , " .dll " ) ;
if ( ptr )
{
* ptr = 0 ;
path . assign ( pathString ) ;
path . append ( " _amd64.so " ) ;
} else {
ptr = strstr ( pathString , " .so " ) ;
if ( ptr )
{
path . assign ( pathString ) ;
} else {
//no extension at all
path . assign ( pathString ) ;
path . append ( " _amd64.so " ) ;
}
}
}
# else
2004-09-12 07:18:54 +00:00
# ifdef __linux__
2004-09-12 03:48:21 +00:00
char * ptr = strstr ( pathString , " amd64 " ) ;
if ( ptr )
{
//attempt to fix the binary name
* ptr = 0 ;
path . assign ( pathString ) ;
path . append ( " i386.so " ) ;
} else {
ptr = strstr ( pathString , " .dll " ) ;
if ( ptr )
{
* ptr = 0 ;
path . assign ( pathString ) ;
path . append ( " _i386.so " ) ;
} else {
2004-09-12 07:18:54 +00:00
//check to see if this file even has an extension
2004-09-12 03:48:21 +00:00
ptr = strstr ( pathString , " .so " ) ;
if ( ptr )
{
path . assign ( pathString ) ;
} else {
path . assign ( pathString ) ;
path . append ( " _i386.so " ) ;
}
}
}
2004-09-12 07:18:54 +00:00
# else
char * ptr = strstr ( pathString , " .dll " ) ;
if ( ptr )
{
path . assign ( pathString ) ;
} else {
//prevent this from loading .so too
ptr = strstr ( pathString , " .so " ) ;
if ( ptr )
{
int i = 0 , len = strlen ( pathString ) , c = - 1 ;
for ( i = len - 1 ; i > = 0 ; i - - )
{
//cut off at first _
if ( pathString [ i ] = = ' _ ' )
{
//make sure this is a valid _
if ( i = = len - 1 | | strncmp ( & ( pathString [ i + 1 ] ) , " amxx " , 4 ) = = 0 )
break ;
c = i ;
break ;
}
}
* ptr = 0 ;
if ( c = = - 1 )
{
path . assign ( pathString ) ;
path . append ( " .dll " ) ;
} else {
ptr = ( char * ) & ( pathString [ c ] ) ;
* ptr = 0 ;
path . assign ( pathString ) ;
path . append ( " .dll " ) ;
}
} else {
path . assign ( pathString ) ;
path . append ( " .dll " ) ;
}
}
# endif //__linux__
# endif //SMALL_CELL_SIZE==64
2004-09-12 03:48:21 +00:00
}
2004-01-31 20:56:22 +00:00
int loadModules ( const char * filename )
{
2004-09-12 03:48:21 +00:00
FILE * fp = fopen ( build_pathname ( " %s " , filename ) , " rt " ) ;
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
if ( ! fp )
{
AMXXLOG_Log ( " [AMXX] Modules list not found (file \" %s \" ) " , filename ) ;
return 0 ;
}
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
char moduleName [ 256 ] ;
char pathString [ 512 ] ;
String line ;
2004-04-29 17:16:28 +00:00
int loaded = 0 ;
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
String path ;
while ( ! feof ( fp ) )
2004-04-29 17:16:28 +00:00
{
2004-09-12 03:48:21 +00:00
if ( ! line . _fread ( fp ) | | line . size ( ) < 1 )
continue ;
line . trim ( ) ;
2004-04-29 17:16:28 +00:00
* moduleName = 0 ;
2004-09-12 03:48:21 +00:00
if ( sscanf ( line . c_str ( ) , " %s " , moduleName ) = = EOF )
continue ;
if ( moduleName [ 0 ] = = ' ; ' )
2004-04-29 17:16:28 +00:00
continue ;
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
char * pathname = build_pathname ( " %s/%s " , get_localinfo ( " amxx_modulesdir " , " addons/amxmodx/modules " ) , moduleName ) ;
strcpy ( pathString , pathname ) ;
path . assign ( " " ) ;
ConvertModuleName ( pathString , path ) ;
if ( ! validFile ( path . c_str ( ) ) )
continue ;
CList < CModule , const char * > : : iterator a = g_modules . find ( path . c_str ( ) ) ;
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
if ( a ) continue ; // already loaded
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
CModule * cc = new CModule ( path . c_str ( ) ) ;
2004-01-31 20:56:22 +00:00
2004-10-03 17:04:29 +00:00
if ( cc = = 0 )
{
fclose ( fp ) ;
return loaded ;
}
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
cc - > queryModule ( ) ;
switch ( cc - > getStatusValue ( ) ) {
2004-01-31 20:56:22 +00:00
case MODULE_BADLOAD :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Module is not a valid library (file \" %s \" ) " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-01-31 20:56:22 +00:00
case MODULE_NOINFO :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Couldn't find info. about module (file \" %s \" ) " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-01-31 20:56:22 +00:00
case MODULE_NOQUERY :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Couldn't find \" AMX_Query \" or \" AMXX_Query \" (file \" %s \" ) " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-01-31 20:56:22 +00:00
case MODULE_NOATTACH :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Couldn't find \" %s \" (file \" %s \" ) " , cc - > isAmxx ( ) ? " AMXX_Attach " : " AMX_Attach " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-01-31 20:56:22 +00:00
case MODULE_OLD :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Module has a different interface version (file \" %s \" ) " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-03-31 18:02:37 +00:00
case MODULE_NEWER :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Module has a newer interface version (file \" %s \" ). Please download a new amxmodx. " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-03-31 18:02:37 +00:00
case MODULE_INTERROR :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Internal error during module load (file \" %s \" ) " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
case MODULE_NOT64BIT :
2004-09-12 03:48:21 +00:00
report_error ( 1 , " [AMXX] Module \" %s \" is not 64 bit compatible. " , path . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
break ;
2004-01-31 20:56:22 +00:00
default :
2004-04-29 17:16:28 +00:00
+ + loaded ;
}
2004-01-31 20:56:22 +00:00
2004-04-29 17:16:28 +00:00
g_modules . put ( cc ) ;
2004-09-12 03:48:21 +00:00
2004-04-29 17:16:28 +00:00
}
2004-01-31 20:56:22 +00:00
2004-09-12 03:48:21 +00:00
fclose ( fp ) ;
2004-04-29 17:16:28 +00:00
return loaded ;
2004-01-31 20:56:22 +00:00
}
2004-06-30 04:27:55 +00:00
void detachModules ( )
2004-01-31 20:56:22 +00:00
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
while ( a )
{
( * a ) . detachModule ( ) ;
a . remove ( ) ;
}
}
2004-06-30 04:27:55 +00:00
void detachReloadModules ( )
2004-01-31 20:56:22 +00:00
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
while ( a )
{
if ( ( * a ) . isReloadable ( ) )
{
( * a ) . detachModule ( ) ;
a . remove ( ) ;
continue ;
}
+ + a ;
}
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
}
void attachModules ( )
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ;
2004-04-29 17:16:28 +00:00
2004-01-31 20:56:22 +00:00
while ( a )
{
2004-03-31 18:02:37 +00:00
bool retVal = ( * a ) . attachModule ( ) ;
if ( ( * a ) . isAmxx ( ) & & ! retVal )
{
switch ( ( * a ) . getStatusValue ( ) )
{
case MODULE_FUNCNOTPRESENT :
report_error ( 1 , " [AMXX] Module requested a not exisitng function (file \" %s \" )%s%s%s " , ( * a ) . getFilename ( ) , ( * a ) . getMissingFunc ( ) ? " (func \" " : " " ,
( * a ) . getMissingFunc ( ) ? ( * a ) . getMissingFunc ( ) : " " , ( * a ) . getMissingFunc ( ) ? " \" ) " : " " ) ;
break ;
case MODULE_INTERROR :
report_error ( 1 , " [AMXX] Internal error during module load (file \" %s \" ) " , ( * a ) . getFilename ( ) ) ;
break ;
case MODULE_BADLOAD :
report_error ( 1 , " [AMXX] Module is not a valid library (file \" %s \" ) " , ( * a ) . getFilename ( ) ) ;
break ;
default :
break ;
}
}
2004-01-31 20:56:22 +00:00
+ + a ;
}
}
const char * strip_name ( const char * a )
{
2004-04-29 17:16:28 +00:00
const char * ret = a ;
while ( * a ) {
if ( * a = = ' / ' | | * a = = ' \\ ' ) {
ret = + + a ;
continue ;
}
+ + a ;
}
return ret ;
2004-01-31 20:56:22 +00:00
}
2004-04-21 19:11:20 +00:00
void attachMetaModModules ( PLUG_LOADTIME now , const char * filename )
2004-01-31 20:56:22 +00:00
{
2004-04-29 17:16:28 +00:00
File fp ( build_pathname ( " %s " , filename ) , " r " ) ;
if ( ! fp )
{
AMXXLOG_Log ( " [AMXX] Modules list not found (file \" %s \" ) " , filename ) ;
return ;
}
char line [ 256 ] , moduleName [ 256 ] ;
2004-09-12 03:48:21 +00:00
String modPath , mmPath ;
2004-04-29 17:16:28 +00:00
DLHANDLE module ;
while ( fp . getline ( line , 255 ) )
{
* moduleName = 0 ;
sscanf ( line , " %s " , moduleName ) ;
2004-09-12 03:48:21 +00:00
if ( ! isalnum ( * moduleName ) )
2004-04-29 17:16:28 +00:00
continue ;
2004-09-12 03:48:21 +00:00
char * pathname = build_pathname ( " %s/%s " , get_localinfo ( " amxx_modulesdir " , " addons/amxmodx/modules " ) , line ) ;
char * mmpathname = build_pathname_addons ( " %s/%s " , get_localinfo ( " amxx_modulesdir " , " addons/amxmodx/modules " ) , line ) ;
ConvertModuleName ( pathname , modPath ) ;
ConvertModuleName ( mmpathname , mmPath ) ;
2004-09-12 07:18:54 +00:00
CList < CFakeMeta : : CFakeMetaPlugin > : : iterator iter = g_FakeMeta . m_Plugins . begin ( ) ;
//prevent double loading
int foundFlag = 0 ;
while ( iter )
{
if ( strcmp ( ( * iter ) . GetPath ( ) , mmPath . c_str ( ) ) = = 0 )
{
foundFlag = 1 ;
break ;
}
+ + iter ;
}
if ( foundFlag )
continue ;
2004-09-12 03:48:21 +00:00
module = DLLOAD ( modPath . c_str ( ) ) ; // link dll
2004-04-29 17:16:28 +00:00
if ( module )
2004-01-31 20:56:22 +00:00
{
2004-04-29 17:16:28 +00:00
int a = ( int ) DLPROC ( module , " Meta_Attach " ) ;
DLFREE ( module ) ;
if ( a )
{
2004-09-12 03:48:21 +00:00
g_FakeMeta . AddPlugin ( mmPath . c_str ( ) ) ;
2004-04-29 17:16:28 +00:00
}
2004-01-31 20:56:22 +00:00
}
2004-04-29 17:16:28 +00:00
}
2004-07-03 13:48:53 +00:00
g_FakeMeta . Meta_Query ( gpMetaUtilFuncs ) ;
g_FakeMeta . Meta_Attach ( now , gpMetaGlobals , gpGamedllFuncs ) ;
2004-01-31 20:56:22 +00:00
}
2004-03-27 17:01:18 +00:00
// Get the number of running modules
int countModules ( CountModulesMode mode )
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator iter ;
2004-03-27 17:01:18 +00:00
int num ;
switch ( mode )
{
case CountModules_All :
return g_modules . size ( ) ;
case CountModules_Running :
iter = g_modules . begin ( ) ;
num = 0 ;
while ( iter )
{
if ( ( * iter ) . getStatusValue ( ) = = MODULE_LOADED )
+ + num ;
+ + iter ;
}
return num ;
case CountModules_Stopped :
iter = g_modules . begin ( ) ;
num = 0 ;
while ( iter )
{
if ( ( * iter ) . getStatusValue ( ) ! = MODULE_LOADED )
+ + num ;
+ + iter ;
}
return num ;
}
return 0 ;
}
2004-03-31 18:02:37 +00:00
2004-04-03 19:15:06 +00:00
// Call all modules' AMXX_PluginsLoaded functions
void modules_callPluginsLoaded ( )
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator iter = g_modules . begin ( ) ;
2004-05-03 19:46:49 +00:00
while ( iter )
2004-04-03 19:15:06 +00:00
{
( * iter ) . CallPluginsLoaded ( ) ;
2004-05-03 19:46:49 +00:00
+ + iter ;
2004-04-03 19:15:06 +00:00
}
}
2004-03-31 18:02:37 +00:00
// new functions
int MNF_AddNatives ( AMX_NATIVE_INFO * natives )
{
2004-09-12 03:48:21 +00:00
CList < CModule , const char * > : : iterator a = g_modules . begin ( ) ;
2004-04-29 17:16:28 +00:00
2004-04-03 19:15:06 +00:00
if ( ! g_CurrentlyCalledModule | | g_ModuleCallReason ! = ModuleCall_Attach )
return FALSE ; // may only be called from attach
2004-03-31 18:02:37 +00:00
// This is needed so that CList can free it ;]
AMX_NATIVE_INFO * * pPtr = new AMX_NATIVE_INFO * ( natives ) ;
if ( ! pPtr )
2004-04-03 19:15:06 +00:00
return FALSE ;
2004-03-31 18:02:37 +00:00
2004-04-03 19:15:06 +00:00
g_CurrentlyCalledModule - > m_Natives . put ( pPtr ) ;
return TRUE ;
}
const char * MNF_GetModname ( void )
{
// :TODO: Do we have to do this??
static char buffer [ 64 ] ;
2004-08-13 08:46:04 +00:00
strcpy ( buffer , g_mod_name . c_str ( ) ) ;
2004-04-03 19:15:06 +00:00
return buffer ;
}
AMX * MNF_GetAmxScript ( int id )
{
CList < CScript , AMX * > : : iterator iter = g_loadedscripts . begin ( ) ;
while ( iter & & id - - )
+ + iter ;
2004-08-13 11:20:05 +00:00
if ( iter = = NULL )
2004-08-13 11:05:38 +00:00
return NULL ;
2004-04-03 19:15:06 +00:00
return ( * iter ) . getAMX ( ) ;
}
const char * MNF_GetAmxScriptName ( int id )
{
CList < CScript , AMX * > : : iterator iter = g_loadedscripts . begin ( ) ;
while ( iter & & id - - )
+ + iter ;
2004-08-13 11:20:05 +00:00
if ( iter = = NULL )
2004-08-13 10:46:13 +00:00
return NULL ;
2004-04-03 19:15:06 +00:00
return ( * iter ) . getName ( ) ;
}
int MNF_FindAmxScriptByName ( const char * name )
{
CList < CScript , AMX * > : : iterator iter = g_loadedscripts . begin ( ) ;
bool found = false ;
int i = 0 ;
while ( iter )
{
if ( stricmp ( ( * iter ) . getName ( ) , name ) = = 0 )
{
found = true ;
break ;
}
+ + iter ;
+ + i ;
}
if ( ! found )
return - 1 ;
return i ;
}
int MNF_FindAmxScriptByAmx ( const AMX * amx )
{
CList < CScript , AMX * > : : iterator iter = g_loadedscripts . begin ( ) ;
bool found = false ;
int i = 0 ;
while ( iter )
{
if ( amx = = ( * iter ) . getAMX ( ) )
{
found = true ;
break ;
}
+ + iter ;
+ + i ;
}
if ( ! found )
return - 1 ;
return i ;
}
char * MNF_GetAmxString ( AMX * amx , cell amx_addr , int bufferId , int * pLen )
{
int len ;
char * retVal = get_amxstring ( amx , amx_addr , bufferId , len ) ;
if ( pLen )
* pLen = len ;
return retVal ;
2004-03-31 18:02:37 +00:00
}
2004-04-03 19:15:06 +00:00
int MNF_GetAmxStringLen ( const cell * ptr )
{
register int c = 0 ;
while ( ptr [ c ] )
+ + c ;
return c ;
}
char * MNF_FormatAmxString ( AMX * amx , cell * params , int startParam , int * pLen )
{
int len ;
char * retVal = format_amxstring ( amx , params , startParam , len ) ;
if ( pLen )
* pLen = len ;
return retVal ;
}
2004-09-01 21:13:30 +00:00
int MNF_GetPlayerFlags ( int id )
{
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
CPlayer * pPlayer = GET_PLAYER_POINTER_I ( id ) ;
return ( pPlayer - > flags [ 0 ] ) ;
}
2004-04-03 19:15:06 +00:00
void MNF_CopyAmxMemory ( cell * dest , const cell * src , int len )
{
memcpy ( ( void * ) dest , ( const void * ) src , ( size_t ) len * sizeof ( cell ) ) ;
}
2004-04-21 19:11:20 +00:00
int MNF_IsPlayerValid ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
2004-04-21 19:11:20 +00:00
return 0 ;
CPlayer * pPlayer = GET_PLAYER_POINTER_I ( id ) ;
return ( pPlayer - > initialized ) ? 1 : 0 ;
}
const char * MNF_GetPlayerName ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return NULL ;
2004-08-13 08:46:04 +00:00
return GET_PLAYER_POINTER_I ( id ) - > name . c_str ( ) ;
2004-04-21 19:11:20 +00:00
}
const char * MNF_GetPlayerIP ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return NULL ;
2004-08-13 08:46:04 +00:00
return GET_PLAYER_POINTER_I ( id ) - > ip . c_str ( ) ;
2004-04-21 19:11:20 +00:00
}
int MNF_IsPlayerInGame ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > ingame ? 1 : 0 ;
}
int MNF_IsPlayerBot ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > IsBot ( ) ? 1 : 0 ;
}
int MNF_IsPlayerAuthorized ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > authorized ? 1 : 0 ;
}
float MNF_GetPlayerTime ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0.0f ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > time ;
}
float MNF_GetPlayerPlayTime ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0.0f ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > playtime ;
}
int MNF_GetPlayerCurweapon ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > current ;
}
int MNF_GetPlayerTeamID ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > teamId ;
}
int MNF_GetPlayerDeaths ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > deaths ;
}
int MNF_GetPlayerMenu ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > menu ;
}
int MNF_GetPlayerKeys ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > keys ;
}
int MNF_IsPlayerAlive ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > IsAlive ( ) ? 1 : 0 ;
}
float MNF_GetPlayerFrags ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0.0f ;
2004-04-21 19:11:20 +00:00
return GET_PLAYER_POINTER_I ( id ) - > pEdict - > v . frags ;
}
int MNF_IsPlayerConnecting ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
CPlayer * pPlayer = GET_PLAYER_POINTER_I ( id ) ;
return ( ! pPlayer - > ingame & & pPlayer - > initialized & & ( GETPLAYERUSERID ( pPlayer - > pEdict ) > 0 ) ) ? 1 : 0 ;
}
int MNF_IsPlayerHLTV ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return ( GET_PLAYER_POINTER_I ( id ) - > pEdict - > v . flags & FL_PROXY ) ? 1 : 0 ;
}
float MNF_GetPlayerArmor ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0.0f ;
2004-04-21 19:11:20 +00:00
return ( GET_PLAYER_POINTER_I ( id ) - > pEdict - > v . armorvalue ) ;
}
float MNF_GetPlayerHealth ( int id )
{
2004-05-28 11:27:50 +00:00
if ( id < 1 | | id > gpGlobals - > maxClients )
return 0 ;
2004-04-21 19:11:20 +00:00
return ( GET_PLAYER_POINTER_I ( id ) - > pEdict - > v . health ) ;
}
2004-04-24 20:05:08 +00:00
void MNF_HiddenStuff ( )
{
// :TODO:
}
2004-04-29 17:16:28 +00:00
cell MNF_RealToCell ( REAL x )
{
return * ( cell * ) & x ;
}
REAL MNF_CellToReal ( cell x )
{
return * ( REAL * ) & x ;
}
2004-07-08 16:02:01 +00:00
void MNF_Log ( const char * fmt , . . . )
{
// :TODO: Overflow possible here
char msg [ 3072 ] ;
va_list arglst ;
va_start ( arglst , fmt ) ;
vsprintf ( msg , fmt , arglst ) ;
va_end ( arglst ) ;
AMXXLOG_Log ( " %s " , msg ) ;
}
2004-07-28 19:28:36 +00:00
2004-09-15 21:21:46 +00:00
//by BAILOPAN
// generic error printing routine
void GenericError ( AMX * amx , int err , int line , char buf [ ] , const char * file )
{
static const char * amx_errs [ ] =
{
NULL ,
" forced exit " ,
" assertion failed " ,
" stack error " ,
" index out of bounds " ,
" memory access " ,
" invalid instruction " ,
" stack low " ,
" heap low " ,
" callback " ,
" native " ,
" divide " ,
" sleep " ,
NULL ,
NULL ,
NULL ,
" out of memory " , //16
" bad file format " ,
" bad file version " ,
" function not found " ,
" invalid entry point " ,
" debugger cannot run " ,
" plugin un or re-initialized " ,
" userdata table full " ,
" JIT failed to initialize " ,
" parameter error " ,
" domain error " ,
} ;
//does this plugin have line ops?
const char * geterr = NULL ;
if ( err > 26 | | err < 0 )
geterr = NULL ;
else
geterr = amx_errs [ err ] ;
if ( ! ( amx - > flags & AMX_FLAG_LINEOPS ) )
{
if ( geterr = = NULL )
{
sprintf ( buf , " Run time error %d (plugin \" %s \" - debug not enabled). " , err , g_plugins . findPluginFast ( amx ) - > getName ( ) ) ;
} else {
sprintf ( buf , " Run time error %d (%s) (plugin \" %s \" ) - debug not enabled. " , err , geterr , g_plugins . findPluginFast ( amx ) - > getName ( ) ) ;
}
} else {
if ( geterr = = NULL )
{
sprintf ( buf , " Run time error %d on line %d (%s \" %s \" ). " , err , line , ( file ? " file " : " plugin " ) , ( file ? file : g_plugins . findPluginFast ( amx ) - > getName ( ) ) ) ;
} else {
2004-10-29 00:21:44 +00:00
if ( err = = AMX_ERR_NATIVE & & amx - > userdata [ 2 ] )
2004-10-29 01:49:00 +00:00
{
2004-10-29 00:21:44 +00:00
geterr = ( char * ) ( amx - > userdata [ 2 ] ) ;
2004-10-29 01:49:00 +00:00
sprintf ( buf , " Native error in \" %s \" on line %d (%s \" %s \" ). " , geterr , line , ( file ? " file " : " plugin " ) , ( file ? file : g_plugins . findPluginFast ( amx ) - > getName ( ) ) ) ;
} else {
sprintf ( buf , " Run time error %d (%s) on line %d (%s \" %s \" ). " , err , geterr , line , ( file ? " file " : " plugin " ) , ( file ? file : g_plugins . findPluginFast ( amx ) - > getName ( ) ) ) ;
}
2004-09-15 21:21:46 +00:00
}
}
}
//by BAILOPAN
// debugger engine front end
void LogError ( AMX * amx , int err , const char * fmt , . . . )
{
//does this plugin have debug info?
va_list arg ;
AMX_DBG * dbg = ( AMX_DBG * ) ( amx - > userdata [ 0 ] ) ;
static char buf [ 1024 ] ;
static char vbuf [ 1024 ] ;
* buf = 0 ;
* vbuf = 0 ;
va_start ( arg , fmt ) ;
vsprintf ( vbuf , fmt , arg ) ;
va_end ( arg ) ;
if ( ! dbg | | ! ( dbg - > tail ) )
{
2004-10-04 20:36:21 +00:00
if ( dbg & & amx - > curfile < dbg - > numFiles & & amx - > curfile > = 0 )
{
GenericError ( amx , err , amx - > curline , buf , dbg - > files [ amx - > curfile ] ) ;
} else {
GenericError ( amx , err , amx - > curline , buf , NULL ) ;
}
2004-10-04 05:50:28 +00:00
AMXXLOG_Log ( " [AMXX] %s " , buf ) ;
2004-10-04 22:56:36 +00:00
if ( * vbuf )
{
AMXXLOG_Log ( " %s " , vbuf ) ;
}
2004-10-29 01:49:00 +00:00
if ( ! dbg )
{
AMXXLOG_Log ( " [AMXX] To enable debug mode, add \" debug \" after the plugin name in plugins.ini (without quotes). " ) ;
}
2004-09-15 21:21:46 +00:00
} else {
AMX_TRACE * t = dbg - > tail ;
AMX_DEBUGCALL tracer = ( AMX_DEBUGCALL ) ( amx - > userdata [ 1 ] ) ;
//actuall
cell line = amx - > curline ;
cell file = amx - > curfile ;
int i = 0 ;
2004-10-04 05:50:28 +00:00
GenericError ( amx , err , line , buf , NULL ) ;
2004-09-17 00:27:28 +00:00
AMXXLOG_Log ( " [AMXX] %s " , buf ) ;
if ( * vbuf )
{
2004-10-04 05:50:28 +00:00
AMXXLOG_Log ( " %s " , vbuf ) ;
2004-09-17 00:27:28 +00:00
}
2004-09-15 21:21:46 +00:00
AMXXLOG_Log ( " [AMXX] Debug Trace => " ) ;
//log the error right away
2004-10-04 05:50:28 +00:00
if ( file > = dbg - > numFiles | | file < 0 )
{
AMXXLOG_Log ( " [AMXX] [%d] Line %d, File \" %s \" " , i + + , line , g_plugins . findPluginFast ( amx ) - > getName ( ) ) ;
} else {
AMXXLOG_Log ( " [AMXX] [%d] Line %d, File \" %s \" " , i + + , line , dbg - > files [ file ] ) ;
}
2004-09-15 21:21:46 +00:00
while ( t ! = NULL )
{
line = t - > line ;
file = t - > file ;
if ( file > = dbg - > numFiles )
{
2004-09-17 00:27:28 +00:00
AMXXLOG_Log ( " [AMXX] [%d] Line %d, File \" %s \" " , i + + , line , g_plugins . findPluginFast ( amx ) - > getName ( ) ) ;
2004-09-15 21:21:46 +00:00
} else {
2004-09-17 00:27:28 +00:00
AMXXLOG_Log ( " [AMXX] [%d] Line %d, File \" %s \" " , i + + , line , dbg - > files [ file ] ) ;
2004-09-15 21:21:46 +00:00
}
if ( tracer )
( tracer ) ( amx , 1 ) ; //pop
t = dbg - > tail ;
}
}
}
2004-07-28 19:28:36 +00:00
void MNF_MergeDefinitionFile ( const char * file )
{
g_langMngr . MergeDefinitionFile ( file ) ;
}
2004-09-05 22:09:45 +00:00
edict_t * MNF_GetPlayerEdict ( int id )
{
if ( id < 1 | | id > gpGlobals - > maxClients )
return NULL ;
return ( GET_PLAYER_POINTER_I ( id ) - > pEdict ) ;
}
2004-09-10 20:58:55 +00:00
const char * MNF_Format ( const char * fmt , . . . )
{
va_list ap ;
va_start ( ap , fmt ) ;
const char * retVal = g_langMngr . FormatString ( fmt , ap ) ;
va_end ( ap ) ;
return retVal ;
}
2004-09-14 16:18:52 +00:00
const char * MNF_GetPlayerTeam ( int id )
{
if ( id < 1 | | id > gpGlobals - > maxClients )
return NULL ;
return ( GET_PLAYER_POINTER_I ( id ) - > team . c_str ( ) ) ;
}
2004-09-11 21:52:18 +00:00
# ifndef MEMORY_TEST
void * MNF_Allocator ( const char * sourceFile , const unsigned int sourceLine , const char * sourceFunc , const unsigned int allocationType , const size_t reportedSize )
{
return malloc ( reportedSize ) ;
}
void * MNF_Reallocator ( const char * sourceFile , const unsigned int sourceLine , const char * sourceFunc , const unsigned int reallocationType , const size_t reportedSize , void * reportedAddress )
{
return realloc ( reportedAddress , reportedSize ) ;
}
void MNF_Deallocator ( const char * sourceFile , const unsigned int sourceLine , const char * sourceFunc , const unsigned int deallocationType , void * reportedAddress )
{
free ( reportedAddress ) ;
}
# endif
2004-09-18 13:37:46 +00:00
// 09/18/2004 : added these two funcs that default to copyBack=false so we don't break all modules
cell MNF_PrepareCellArray ( cell * ptr , unsigned int size )
{
return prepareCellArray ( ptr , size , false ) ;
}
cell MNF_PrepareCharArray ( char * ptr , unsigned int size )
{
return prepareCharArray ( ptr , size , false ) ;
}
2004-03-31 18:02:37 +00:00
// Fnptr Request function for the new interface
const char * g_LastRequestedFunc = NULL ;
2004-04-03 19:15:06 +00:00
# define REGISTER_FUNC(name, func) { name, (void*)func },
2004-03-31 18:02:37 +00:00
void * Module_ReqFnptr ( const char * funcName )
{
// func table
struct Func_s
{
const char * name ;
void * ptr ;
} ;
static Func_s functions [ ] = {
2004-04-03 19:15:06 +00:00
// Misc
2004-07-28 19:28:36 +00:00
REGISTER_FUNC ( " BuildPathname " , build_pathname )
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " PrintSrvConsole " , print_srvconsole )
REGISTER_FUNC ( " GetModname " , MNF_GetModname )
2004-07-08 16:02:01 +00:00
REGISTER_FUNC ( " Log " , MNF_Log )
2004-09-15 21:28:20 +00:00
REGISTER_FUNC ( " LogError " , LogError )
2004-07-28 19:28:36 +00:00
REGISTER_FUNC ( " MergeDefinitionFile " , MNF_MergeDefinitionFile )
2004-09-10 20:58:55 +00:00
REGISTER_FUNC ( " Format " , MNF_Format )
2004-04-29 17:16:28 +00:00
// Amx scripts loading / unloading / managing
REGISTER_FUNC ( " GetAmxScript " , MNF_GetAmxScript )
REGISTER_FUNC ( " GetAmxScriptName " , MNF_GetAmxScriptName )
REGISTER_FUNC ( " FindAmxScriptByName " , MNF_FindAmxScriptByName )
REGISTER_FUNC ( " FindAmxScriptByAmx " , MNF_FindAmxScriptByAmx )
REGISTER_FUNC ( " LoadAmxScript " , load_amxscript )
REGISTER_FUNC ( " UnloadAmxScript " , unload_amxscript )
// String / mem in amx scripts support
REGISTER_FUNC ( " SetAmxString " , set_amxstring )
REGISTER_FUNC ( " GetAmxString " , MNF_GetAmxString )
REGISTER_FUNC ( " GetAmxStringLen " , MNF_GetAmxStringLen )
REGISTER_FUNC ( " FormatAmxString " , MNF_FormatAmxString )
REGISTER_FUNC ( " CopyAmxMemory " , MNF_CopyAmxMemory )
REGISTER_FUNC ( " GetAmxAddr " , get_amxaddr )
// other amx stuff
REGISTER_FUNC ( " amx_Exec " , amx_Exec )
REGISTER_FUNC ( " amx_Execv " , amx_Execv )
REGISTER_FUNC ( " amx_Allot " , amx_Allot )
REGISTER_FUNC ( " amx_FindPublic " , amx_FindPublic )
2004-08-24 04:30:13 +00:00
REGISTER_FUNC ( " amx_FindNative " , amx_FindNative )
2004-04-29 17:16:28 +00:00
// Natives / Forwards
REGISTER_FUNC ( " AddNatives " , MNF_AddNatives )
REGISTER_FUNC ( " RaiseAmxError " , amx_RaiseError )
REGISTER_FUNC ( " RegisterForward " , registerForward )
2004-05-05 18:43:33 +00:00
REGISTER_FUNC ( " RegisterSPForward " , registerSPForward )
REGISTER_FUNC ( " RegisterSPForwardByName " , registerSPForwardByName )
REGISTER_FUNC ( " UnregisterSPForward " , unregisterSPForward )
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " ExecuteForward " , executeForwards )
2004-09-18 13:37:46 +00:00
REGISTER_FUNC ( " PrepareCellArray " , MNF_PrepareCellArray )
REGISTER_FUNC ( " PrepareCharArray " , MNF_PrepareCharArray )
REGISTER_FUNC ( " PrepareCellArrayA " , prepareCellArray )
REGISTER_FUNC ( " PrepareCharArrayA " , prepareCharArray )
2004-04-29 17:16:28 +00:00
// Player
2004-09-01 21:13:30 +00:00
REGISTER_FUNC ( " GetPlayerFlags " , MNF_GetPlayerFlags )
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " IsPlayerValid " , MNF_IsPlayerValid )
REGISTER_FUNC ( " GetPlayerName " , MNF_GetPlayerName )
REGISTER_FUNC ( " GetPlayerIP " , MNF_GetPlayerIP )
REGISTER_FUNC ( " IsPlayerInGame " , MNF_IsPlayerInGame )
REGISTER_FUNC ( " IsPlayerBot " , MNF_IsPlayerBot )
REGISTER_FUNC ( " IsPlayerAuthorized " , MNF_IsPlayerAuthorized )
REGISTER_FUNC ( " GetPlayerTime " , MNF_GetPlayerTime )
REGISTER_FUNC ( " GetPlayerPlayTime " , MNF_GetPlayerPlayTime )
REGISTER_FUNC ( " GetPlayerCurweapon " , MNF_GetPlayerCurweapon )
REGISTER_FUNC ( " GetPlayerTeamID " , MNF_GetPlayerTeamID )
2004-09-14 16:18:52 +00:00
REGISTER_FUNC ( " GetPlayerTeam " , MNF_GetPlayerTeam )
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " GetPlayerDeaths " , MNF_GetPlayerDeaths )
REGISTER_FUNC ( " GetPlayerFrags " , MNF_GetPlayerFrags )
REGISTER_FUNC ( " GetPlayerMenu " , MNF_GetPlayerMenu )
REGISTER_FUNC ( " GetPlayerKeys " , MNF_GetPlayerKeys )
REGISTER_FUNC ( " IsPlayerAlive " , MNF_IsPlayerAlive )
REGISTER_FUNC ( " IsPlayerConnecting " , MNF_IsPlayerConnecting )
REGISTER_FUNC ( " IsPlayerHLTV " , MNF_IsPlayerHLTV )
REGISTER_FUNC ( " GetPlayerArmor " , MNF_GetPlayerArmor )
REGISTER_FUNC ( " GetPlayerHealth " , MNF_GetPlayerHealth )
2004-09-05 22:09:45 +00:00
REGISTER_FUNC ( " GetPlayerEdict " , MNF_GetPlayerEdict )
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " CellToReal " , MNF_CellToReal )
REGISTER_FUNC ( " RealToCell " , MNF_RealToCell )
2004-04-21 19:11:20 +00:00
# ifdef MEMORY_TEST
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " Allocator " , m_allocator )
REGISTER_FUNC ( " Deallocator " , m_deallocator )
REGISTER_FUNC ( " Reallocator " , m_reallocator )
2004-09-11 21:52:18 +00:00
# else
REGISTER_FUNC ( " Allocator " , MNF_Allocator )
REGISTER_FUNC ( " Deallocator " , MNF_Deallocator )
REGISTER_FUNC ( " Reallocator " , MNF_Reallocator )
2004-04-21 19:11:20 +00:00
# endif // MEMORY_TEST
2004-04-24 20:05:08 +00:00
2004-04-29 17:16:28 +00:00
REGISTER_FUNC ( " Haha_HiddenStuff " , MNF_HiddenStuff )
2004-03-31 18:02:37 +00:00
} ;
// code
2004-05-03 19:46:49 +00:00
if ( ! g_CurrentlyCalledModule | | g_ModuleCallReason ! = ModuleCall_Attach )
{
return NULL ;
}
2004-03-31 18:02:37 +00:00
g_LastRequestedFunc = funcName ;
2004-04-21 19:11:20 +00:00
for ( unsigned int i = 0 ; i < ( sizeof ( functions ) / sizeof ( Func_s ) ) ; + + i )
2004-03-31 18:02:37 +00:00
{
if ( strcmp ( funcName , functions [ i ] . name ) = = 0 )
return functions [ i ] . ptr ;
}
return NULL ;
2004-09-02 02:16:38 +00:00
}