fakemeta support

memory reports
printing GPL on startup
no .def file needed under windows anymore
This commit is contained in:
Pavol Marko 2004-04-22 10:50:47 +00:00
parent 81e7de4a2e
commit c088c4835f

View File

@ -29,9 +29,9 @@
* version. * version.
*/ */
#include <extdll.h> #include <time.h>
#include <meta_api.h>
#include "amxmodx.h" #include "amxmodx.h"
#include "fakemeta.h"
plugin_info_t Plugin_info = { plugin_info_t Plugin_info = {
META_INTERFACE_VERSION, // ifvers META_INTERFACE_VERSION, // ifvers
@ -85,6 +85,15 @@ float g_game_restarting;
float g_game_timeleft; float g_game_timeleft;
float g_task_time; float g_task_time;
float g_auth_time; float g_auth_time;
#ifdef MEMORY_TEST
float g_next_memreport_time;
unsigned int g_memreport_count;
String g_memreport_dir;
bool g_memreport_enabled;
#define MEMREPORT_INTERVAL 1200.0f /* 20 mins */
#endif // MEMORY_TEST
hudtextparms_t g_hudset; hudtextparms_t g_hudset;
//int g_edict_point; //int g_edict_point;
int g_players_num; int g_players_num;
@ -113,9 +122,12 @@ int FF_PluginEnd = -1;
int FF_InconsistentFile = -1; int FF_InconsistentFile = -1;
int FF_ClientAuthorized = -1; int FF_ClientAuthorized = -1;
// fake metamod api
CFakeMeta g_FakeMeta;
// Precache stuff from force consistency calls // Precache stuff from force consistency calls
// or check for pointed files won't be done // or check for pointed files won't be done
int PrecacheModel(char *s) { int C_PrecacheModel(char *s) {
if ( !g_forcedmodules ){ if ( !g_forcedmodules ){
g_forcedmodules = true; g_forcedmodules = true;
for(CList<ForceObject>::iterator a = g_forcemodels.begin(); a ; ++a){ for(CList<ForceObject>::iterator a = g_forcemodels.begin(); a ; ++a){
@ -126,7 +138,7 @@ int PrecacheModel(char *s) {
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
} }
int PrecacheSound(char *s) { int C_PrecacheSound(char *s) {
if ( !g_forcedsounds ) { if ( !g_forcedsounds ) {
g_forcedsounds = true; g_forcedsounds = true;
for(CList<ForceObject>::iterator a = g_forcesounds.begin(); a ; ++a){ for(CList<ForceObject>::iterator a = g_forcesounds.begin(); a ; ++a){
@ -143,7 +155,7 @@ int PrecacheSound(char *s) {
} }
// On InconsistentFile call forward function from plugins // On InconsistentFile call forward function from plugins
int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ) int C_InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message )
{ {
if (FF_InconsistentFile < 0) if (FF_InconsistentFile < 0)
RETURN_META_VALUE(MRES_IGNORED, FALSE); RETURN_META_VALUE(MRES_IGNORED, FALSE);
@ -209,7 +221,7 @@ const char* get_localinfo( const char* name , const char* def )
// Load AMX modules for new native functions // Load AMX modules for new native functions
// Initialize AMX stuff and load it's plugins from plugins.ini list // Initialize AMX stuff and load it's plugins from plugins.ini list
// Call precache forward function from plugins // Call precache forward function from plugins
int Spawn( edict_t *pent ) { int C_Spawn( edict_t *pent ) {
if ( g_initialized ) RETURN_META_VALUE(MRES_IGNORED, 0); if ( g_initialized ) RETURN_META_VALUE(MRES_IGNORED, 0);
@ -227,7 +239,7 @@ int Spawn( edict_t *pent ) {
if (g_log_dir.empty()) if (g_log_dir.empty())
{ {
g_log_dir.set(get_localinfo("amxx_logs", "addons/amxx/logs")); g_log_dir.set(get_localinfo("amxx_logs", "addons/amxx/logs"));
AMXXLOG_MakeNewLogFile(); AMXXLOG_MapChange();
} }
// ###### Initialize task manager // ###### Initialize task manager
@ -267,6 +279,10 @@ int Spawn( edict_t *pent ) {
g_game_timeleft = g_bmod_dod ? 1 : 0; g_game_timeleft = g_bmod_dod ? 1 : 0;
g_task_time = gpGlobals->time + 99999.0; g_task_time = gpGlobals->time + 99999.0;
g_auth_time = gpGlobals->time + 99999.0; g_auth_time = gpGlobals->time + 99999.0;
#ifdef MEMORY_TEST
g_next_memreport_time = gpGlobals->time + 99999.0;
#endif
g_players_num = 0; g_players_num = 0;
// Set server flags // Set server flags
@ -336,7 +352,7 @@ struct sUserMsg {
}; };
int RegUserMsg_Post(const char *pszName, int iSize) int C_RegUserMsg_Post(const char *pszName, int iSize)
{ {
for (int i = 0; g_user_msg[ i ].name; ++i ) for (int i = 0; g_user_msg[ i ].name; ++i )
{ {
@ -366,7 +382,7 @@ Much more later after precache. All is precached, server
will be flaged as ready to use so call will be flaged as ready to use so call
plugin_init forward function from plugins plugin_init forward function from plugins
*/ */
void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ){ void C_ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ){
int id; int id;
for (int i = 0; g_user_msg[ i ].name; ++i ) for (int i = 0; g_user_msg[ i ].name; ++i )
@ -389,7 +405,7 @@ void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ){
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ){ void C_ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ){
// g_edict_point = (int)pEdictList; // g_edict_point = (int)pEdictList;
@ -407,11 +423,17 @@ void ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ){
g_task_time = gpGlobals->time; g_task_time = gpGlobals->time;
g_auth_time = gpGlobals->time; g_auth_time = gpGlobals->time;
#ifdef MEMORY_TEST
g_next_memreport_time = gpGlobals->time + MEMREPORT_INTERVAL;
g_memreport_count = 0;
g_memreport_enabled = true;
#endif
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
// Call plugin_end forward function from plugins. // Call plugin_end forward function from plugins.
void ServerDeactivate() { void C_ServerDeactivate() {
for(int i = 1; i <= gpGlobals->maxClients; ++i){ for(int i = 1; i <= gpGlobals->maxClients; ++i){
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
@ -432,7 +454,7 @@ void ServerDeactivate() {
// After all clear whole AMX configuration // After all clear whole AMX configuration
// However leave AMX modules which are loaded only once // However leave AMX modules which are loaded only once
void ServerDeactivate_Post() { void C_ServerDeactivate_Post() {
g_initialized = false; g_initialized = false;
@ -459,7 +481,7 @@ void ServerDeactivate_Post() {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
BOOL ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ){ BOOL C_ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ){
CPlayer* pPlayer = GET_PLAYER_POINTER(pEntity); CPlayer* pPlayer = GET_PLAYER_POINTER(pEntity);
if (!pPlayer->bot) { if (!pPlayer->bot) {
@ -481,7 +503,7 @@ BOOL ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszA
RETURN_META_VALUE(MRES_IGNORED, TRUE); RETURN_META_VALUE(MRES_IGNORED, TRUE);
} }
void ClientDisconnect( edict_t *pEntity ) { void C_ClientDisconnect( edict_t *pEntity ) {
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity); CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
if (pPlayer->ingame) { if (pPlayer->ingame) {
executeForwards(FF_ClientDisconnect, pPlayer->index); executeForwards(FF_ClientDisconnect, pPlayer->index);
@ -491,7 +513,7 @@ void ClientDisconnect( edict_t *pEntity ) {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void ClientPutInServer_Post( edict_t *pEntity ) { void C_ClientPutInServer_Post( edict_t *pEntity ) {
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity); CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
if (!pPlayer->bot) { if (!pPlayer->bot) {
pPlayer->PutInServer(); pPlayer->PutInServer();
@ -503,7 +525,7 @@ void ClientPutInServer_Post( edict_t *pEntity ) {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer ) { void C_ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer ) {
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity); CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
executeForwards(FF_ClientInfoChanged, pPlayer->index); executeForwards(FF_ClientInfoChanged, pPlayer->index);
@ -534,7 +556,7 @@ void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer ) {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void ClientCommand( edict_t *pEntity ) { void C_ClientCommand( edict_t *pEntity ) {
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity); CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
META_RES result = MRES_IGNORED; META_RES result = MRES_IGNORED;
cell ret = 0; cell ret = 0;
@ -637,7 +659,7 @@ void ClientCommand( edict_t *pEntity ) {
RETURN_META( result ); RETURN_META( result );
} }
void StartFrame_Post( void ) { void C_StartFrame_Post( void ) {
if (g_auth_time < gpGlobals->time ) if (g_auth_time < gpGlobals->time )
{ {
@ -668,7 +690,48 @@ void StartFrame_Post( void ) {
} }
#ifdef MEMORY_TEST
if (g_memreport_enabled && g_next_memreport_time <= gpGlobals->time)
{
g_next_memreport_time = gpGlobals->time + MEMREPORT_INTERVAL;
if (g_memreport_count == 0)
{
// make new directory
time_t td;
time(&td);
tm *curTime = localtime(&td);
int i = 0;
mkdir(build_pathname("%s/memreports", get_localinfo("amxx_basedir", "addons/amxx")));
while (true)
{
char buffer[256];
sprintf(buffer, "%s/memreports/D%02d%02d%03d", get_localinfo("amxx_basedir", "addons/amxx"), curTime->tm_mon + 1, curTime->tm_mday, i);
if (mkdir(build_pathname(buffer)) < 0)
{
if (errno == EEXIST)
{
// good
++i;
continue;
}
else
{
// bad
g_memreport_enabled = false;
AMXXLOG_Log("[AMXX] Fatal error: Can't create directory for memreport files (%s)", buffer);
break;
}
}
g_memreport_dir.set(buffer);
// g_memreport_dir should be valid now
break;
}
}
m_dumpMemoryReport(build_pathname("%s/r%03d", g_memreport_dir.str(), g_memreport_count));
AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d\") (interval %f)", g_memreport_count + 1, g_memreport_dir.str(), g_memreport_count, MEMREPORT_INTERVAL);
g_memreport_count++;
}
#endif // MEMORY_TEST
if (g_task_time > gpGlobals->time) if (g_task_time > gpGlobals->time)
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
@ -712,7 +775,7 @@ void StartFrame_Post( void ) {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) { void C_MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) {
if (ed) if (ed)
{ {
@ -746,47 +809,47 @@ void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t
g_events.parserInit(msg_type, &gpGlobals->time, mPlayer ,mPlayerIndex); g_events.parserInit(msg_type, &gpGlobals->time, mPlayer ,mPlayerIndex);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteByte_Post(int iValue) { void C_WriteByte_Post(int iValue) {
g_events.parseValue(iValue); g_events.parseValue(iValue);
if (function) (*function)((void *)&iValue); if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteChar_Post(int iValue) { void C_WriteChar_Post(int iValue) {
g_events.parseValue(iValue); g_events.parseValue(iValue);
if (function) (*function)((void *)&iValue); if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteShort_Post(int iValue) { void C_WriteShort_Post(int iValue) {
g_events.parseValue(iValue); g_events.parseValue(iValue);
if (function) (*function)((void *)&iValue); if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteLong_Post(int iValue) { void C_WriteLong_Post(int iValue) {
g_events.parseValue(iValue); g_events.parseValue(iValue);
if (function) (*function)((void *)&iValue); if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteAngle_Post(float flValue) { void C_WriteAngle_Post(float flValue) {
g_events.parseValue(flValue); g_events.parseValue(flValue);
if (function) (*function)((void *)&flValue); if (function) (*function)((void *)&flValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteCoord_Post(float flValue) { void C_WriteCoord_Post(float flValue) {
g_events.parseValue(flValue); g_events.parseValue(flValue);
if (function) (*function)((void *)&flValue); if (function) (*function)((void *)&flValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteString_Post(const char *sz) { void C_WriteString_Post(const char *sz) {
g_events.parseValue(sz); g_events.parseValue(sz);
if (function) (*function)((void *)sz); if (function) (*function)((void *)sz);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void WriteEntity_Post(int iValue) { void C_WriteEntity_Post(int iValue) {
g_events.parseValue(iValue); g_events.parseValue(iValue);
if (function) (*function)((void *)&iValue); if (function) (*function)((void *)&iValue);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void MessageEnd_Post(void) { void C_MessageEnd_Post(void) {
g_events.executeEvents(); g_events.executeEvents();
#if 0 // ######### this is done by call above #if 0 // ######### this is done by call above
@ -820,31 +883,31 @@ void MessageEnd_Post(void) {
if (endfunction) (*endfunction)(NULL); if (endfunction) (*endfunction)(NULL);
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
const char *Cmd_Args( void ) { const char *C_Cmd_Args( void ) {
if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (g_fakecmd.argc>1)?g_fakecmd.args:NULL); if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (g_fakecmd.argc>1)?g_fakecmd.args:NULL);
RETURN_META_VALUE(MRES_IGNORED, NULL); RETURN_META_VALUE(MRES_IGNORED, NULL);
} }
const char *Cmd_Argv( int argc ) { const char *C_Cmd_Argv( int argc ) {
if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (argc<3)?g_fakecmd.argv[argc]:""); if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, (argc<3)?g_fakecmd.argv[argc]:"");
RETURN_META_VALUE(MRES_IGNORED, NULL); RETURN_META_VALUE(MRES_IGNORED, NULL);
} }
int Cmd_Argc( void ) { int C_Cmd_Argc( void ) {
if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, g_fakecmd.argc ); if (g_fakecmd.fake) RETURN_META_VALUE(MRES_SUPERCEDE, g_fakecmd.argc );
RETURN_META_VALUE(MRES_IGNORED, 0); RETURN_META_VALUE(MRES_IGNORED, 0);
} }
// Grenade has been thrown. // Grenade has been thrown.
// Only here we may find out who is an owner. // Only here we may find out who is an owner.
void SetModel(edict_t *e, const char *m){ void C_SetModel(edict_t *e, const char *m){
if(e->v.owner&&m[7]=='w'&&m[8]=='_'&&m[9]=='h') if(e->v.owner&&m[7]=='w'&&m[8]=='_'&&m[9]=='h')
g_grenades.put( e , 1.75, 4, GET_PLAYER_POINTER(e->v.owner) ); g_grenades.put( e , 1.75, 4, GET_PLAYER_POINTER(e->v.owner) );
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
// Save at what part of body a player is aiming // Save at what part of body a player is aiming
void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *e, TraceResult *ptr) { void C_TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *e, TraceResult *ptr) {
if ( e && ( e->v.flags & (FL_CLIENT | FL_FAKECLIENT) ) ) { if ( e && ( e->v.flags & (FL_CLIENT | FL_FAKECLIENT) ) ) {
CPlayer* pPlayer = GET_PLAYER_POINTER(e); CPlayer* pPlayer = GET_PLAYER_POINTER(e);
if (ptr->pHit&&(ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT) )) if (ptr->pHit&&(ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT) ))
@ -855,7 +918,7 @@ void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
void AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...) { void C_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...) {
if ( atype != at_logged ) RETURN_META(MRES_IGNORED); if ( atype != at_logged ) RETURN_META(MRES_IGNORED);
@ -938,6 +1001,7 @@ C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_
else else
LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor); LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor);
} }
// :NOTE: Don't call modules query here (g_FakeMeta.Meta_Query), because we don't know modules yet. Do it in Meta_Attach
return(TRUE); return(TRUE);
} }
@ -952,6 +1016,9 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post; gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
gMetaFunctionTable.pfnGetEngineFunctions = GetEngineFunctions; gMetaFunctionTable.pfnGetEngineFunctions = GetEngineFunctions;
gMetaFunctionTable.pfnGetEngineFunctions_Post = GetEngineFunctions_Post; gMetaFunctionTable.pfnGetEngineFunctions_Post = GetEngineFunctions_Post;
//gMetaFunctionTable.pfnGetNewDLLFunctions = GetNewDLLFunctions;
//gMetaFunctionTable.pfnGetNewDLLFunctions_Post = GetNewDLLFunctions_Post;
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS)); memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
gpGamedllFuncs=pGamedllFuncs; gpGamedllFuncs=pGamedllFuncs;
CVAR_REGISTER(&init_amxmodx_version); CVAR_REGISTER(&init_amxmodx_version);
@ -968,6 +1035,12 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
a = &gameDir[i]; a = &gameDir[i];
g_mod_name.set(a); g_mod_name.set(a);
// ###### Print short GPL
print_srvconsole( "\n AMX Mod X version %s Copyright (c) 2004 AMX Mod X Development Team \n"
" AMX Mod X comes with ABSOLUTELY NO WARRANTY; for details type `amxx gpl'.\n", AMX_VERSION);
print_srvconsole( " This is free software and you are welcome to redistribute it under \n"
" certain conditions; type 'amxx gpl' for details.\n \n");
// ###### Load custom path configuration // ###### Load custom path configuration
Vault amx_config; Vault amx_config;
amx_config.setSource(build_pathname("%s", get_localinfo("amxx_cfg", "addons/amxx/configs/core.ini"))); amx_config.setSource(build_pathname("%s", get_localinfo("amxx_cfg", "addons/amxx/configs/core.ini")));
@ -984,10 +1057,11 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
// ###### Initialize logging here // ###### Initialize logging here
AMXXLOG_Init(); AMXXLOG_Init();
g_log_dir.set(get_localinfo("amxx_logs", "addons/amxx/logs")); g_log_dir.set(get_localinfo("amxx_logs", "addons/amxx/logs"));
AMXXLOG_MakeNewLogFile(); AMXXLOG_MapChange();
// ###### Now attach metamod modules // ###### Now attach metamod modules
attachMetaModModules( get_localinfo("amxx_modules", "addons/amxx/modules.ini") ); // This will also call modules Meta_Query and Meta_Attach functions
attachMetaModModules(now, get_localinfo("amxx_modules", "addons/amxx/modules.ini") );
return(TRUE); return(TRUE);
} }
@ -1016,50 +1090,111 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) {
dettachModules(); dettachModules();
// ###### Now dettach metamod modules // ###### Now dettach metamod modules
dettachMetaModModules( get_localinfo("amxx_modules", "addons/amxx/modules.ini") ); g_FakeMeta.Meta_Detach(now, reason);
g_FakeMeta.ReleasePlugins();
return(TRUE); return(TRUE);
} }
C_DLLEXPORT void WINAPI GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) { #ifdef __linux__
// linux prototype
C_DLLEXPORT void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) {
#else
#ifdef _MSC_VER
// MSVC: Simulate __stdcall calling convention
C_DLLEXPORT __declspec(naked) void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
{
__asm // Prolog
{
// Save ebp
push ebp
// Set stack frame pointer
mov ebp, esp
// Allocate space for local variables
// The MSVC compiler gives us the needed size in __LOCAL_SIZE.
sub esp, __LOCAL_SIZE
// Push registers
push ebx
push esi
push edi
}
#else // _MSC_VER
#ifdef __GNUC__
// GCC can also work with this
C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals )
{
#else // __GNUC__
// compiler not known
#error There is no support (yet) for your compiler. Please use MSVC or GCC compilers or contact the AMX Mod X dev team.
#endif // __GNUC__
#endif // _MSC_VER
#endif // __linux__
// ** Function core <--
memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t));
gpGlobals = pGlobals; gpGlobals = pGlobals;
// --> ** Function core
#ifdef _MSC_VER
// Epilog
if (sizeof(int*) == 8)
{ // 64 bit
__asm
{
// Pop registers
pop edi
pop esi
pop ebx
// Restore stack frame pointer
mov esp, ebp
// Restore ebp
pop ebp
// 2 * sizeof(int*) = 16 on 64 bit
ret 16
}
}
else
{ // 32 bit
__asm
{
// Pop registers
pop edi
pop esi
pop ebx
// Restore stack frame pointer
mov esp, ebp
// Restore ebp
pop ebp
// 2 * sizeof(int*) = 8 on 32 bit
ret 8
}
}
#endif // #ifdef _MSC_VER
} }
DLL_FUNCTIONS gFunctionTable; DLL_FUNCTIONS gFunctionTable;
C_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ){ C_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ){
gFunctionTable.pfnSpawn = Spawn; gFunctionTable.pfnSpawn = C_Spawn;
gFunctionTable.pfnClientCommand = ClientCommand; gFunctionTable.pfnClientCommand = C_ClientCommand;
gFunctionTable.pfnServerDeactivate = ServerDeactivate; gFunctionTable.pfnServerDeactivate = C_ServerDeactivate;
gFunctionTable.pfnClientDisconnect = ClientDisconnect; gFunctionTable.pfnClientDisconnect = C_ClientDisconnect;
gFunctionTable.pfnInconsistentFile = InconsistentFile; gFunctionTable.pfnInconsistentFile = C_InconsistentFile;
gFunctionTable.pfnServerActivate = ServerActivate; gFunctionTable.pfnServerActivate = C_ServerActivate;
if(*interfaceVersion!=INTERFACE_VERSION) { return g_FakeMeta.GetEntityAPI2(pFunctionTable, interfaceVersion, &gFunctionTable);
LOG_ERROR(PLID, "GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
*interfaceVersion = INTERFACE_VERSION;
return(FALSE);
}
memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) );
return(TRUE);
} }
DLL_FUNCTIONS gFunctionTable_Post; DLL_FUNCTIONS gFunctionTable_Post;
C_DLLEXPORT int GetEntityAPI2_Post( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ) { C_DLLEXPORT int GetEntityAPI2_Post( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ) {
gFunctionTable_Post.pfnClientPutInServer = ClientPutInServer_Post; gFunctionTable_Post.pfnClientPutInServer = C_ClientPutInServer_Post;
gFunctionTable_Post.pfnClientUserInfoChanged = ClientUserInfoChanged_Post; gFunctionTable_Post.pfnClientUserInfoChanged = C_ClientUserInfoChanged_Post;
gFunctionTable_Post.pfnServerActivate = ServerActivate_Post; gFunctionTable_Post.pfnServerActivate = C_ServerActivate_Post;
gFunctionTable_Post.pfnClientConnect = ClientConnect_Post; gFunctionTable_Post.pfnClientConnect = C_ClientConnect_Post;
gFunctionTable_Post.pfnStartFrame = StartFrame_Post; gFunctionTable_Post.pfnStartFrame = C_StartFrame_Post;
gFunctionTable_Post.pfnServerDeactivate = ServerDeactivate_Post; gFunctionTable_Post.pfnServerDeactivate = C_ServerDeactivate_Post;
if(*interfaceVersion!=INTERFACE_VERSION) { return g_FakeMeta.GetEntityAPI2_Post(pFunctionTable, interfaceVersion, &gFunctionTable_Post);
LOG_ERROR(PLID, "GetEntityAPI2_Post version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
*interfaceVersion = INTERFACE_VERSION;
return(FALSE);
}
memcpy( pFunctionTable, &gFunctionTable_Post, sizeof( DLL_FUNCTIONS ) );
return(TRUE);
} }
enginefuncs_t meta_engfuncs; enginefuncs_t meta_engfuncs;
@ -1067,7 +1202,7 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
if ( stricmp(g_mod_name.str(),"cstrike") == 0 || stricmp(g_mod_name.str(),"czero")==0 ) if ( stricmp(g_mod_name.str(),"cstrike") == 0 || stricmp(g_mod_name.str(),"czero")==0 )
{ {
meta_engfuncs.pfnSetModel = SetModel; meta_engfuncs.pfnSetModel = C_SetModel;
g_bmod_cstrike = true; g_bmod_cstrike = true;
} }
else else
@ -1076,12 +1211,14 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
g_bmod_dod = !stricmp(g_mod_name.str(),"dod"); g_bmod_dod = !stricmp(g_mod_name.str(),"dod");
} }
meta_engfuncs.pfnCmd_Argc = Cmd_Argc; meta_engfuncs.pfnCmd_Argc = C_Cmd_Argc;
meta_engfuncs.pfnCmd_Argv = Cmd_Argv; meta_engfuncs.pfnCmd_Argv = C_Cmd_Argv;
meta_engfuncs.pfnCmd_Args = Cmd_Args; meta_engfuncs.pfnCmd_Args = C_Cmd_Args;
meta_engfuncs.pfnPrecacheModel = PrecacheModel; meta_engfuncs.pfnPrecacheModel = C_PrecacheModel;
meta_engfuncs.pfnPrecacheSound = PrecacheSound; meta_engfuncs.pfnPrecacheSound = C_PrecacheSound;
return g_FakeMeta.GetEngineFunctions(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs);
/*
if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) { if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) {
LOG_ERROR(PLID, "GetEngineFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION); LOG_ERROR(PLID, "GetEngineFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
*interfaceVersion = ENGINE_INTERFACE_VERSION; *interfaceVersion = ENGINE_INTERFACE_VERSION;
@ -1089,25 +1226,28 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
} }
memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t)); memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
return(TRUE); return(TRUE);
*/
} }
enginefuncs_t meta_engfuncs_post; enginefuncs_t meta_engfuncs_post;
C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion ) { C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion ) {
meta_engfuncs_post.pfnTraceLine = TraceLine_Post; meta_engfuncs_post.pfnTraceLine = C_TraceLine_Post;
meta_engfuncs_post.pfnMessageBegin = MessageBegin_Post; meta_engfuncs_post.pfnMessageBegin = C_MessageBegin_Post;
meta_engfuncs_post.pfnMessageEnd = MessageEnd_Post; meta_engfuncs_post.pfnMessageEnd = C_MessageEnd_Post;
meta_engfuncs_post.pfnWriteByte = WriteByte_Post; meta_engfuncs_post.pfnWriteByte = C_WriteByte_Post;
meta_engfuncs_post.pfnWriteChar = WriteChar_Post; meta_engfuncs_post.pfnWriteChar = C_WriteChar_Post;
meta_engfuncs_post.pfnWriteShort = WriteShort_Post; meta_engfuncs_post.pfnWriteShort = C_WriteShort_Post;
meta_engfuncs_post.pfnWriteLong = WriteLong_Post; meta_engfuncs_post.pfnWriteLong = C_WriteLong_Post;
meta_engfuncs_post.pfnWriteAngle = WriteAngle_Post; meta_engfuncs_post.pfnWriteAngle = C_WriteAngle_Post;
meta_engfuncs_post.pfnWriteCoord = WriteCoord_Post; meta_engfuncs_post.pfnWriteCoord = C_WriteCoord_Post;
meta_engfuncs_post.pfnWriteString = WriteString_Post; meta_engfuncs_post.pfnWriteString = C_WriteString_Post;
meta_engfuncs_post.pfnWriteEntity = WriteEntity_Post; meta_engfuncs_post.pfnWriteEntity = C_WriteEntity_Post;
meta_engfuncs_post.pfnAlertMessage = AlertMessage_Post; meta_engfuncs_post.pfnAlertMessage = C_AlertMessage_Post;
meta_engfuncs_post.pfnRegUserMsg = RegUserMsg_Post; meta_engfuncs_post.pfnRegUserMsg = C_RegUserMsg_Post;
return g_FakeMeta.GetEngineFunctions_Post(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs_post);
/*
if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) { if(*interfaceVersion!=ENGINE_INTERFACE_VERSION) {
LOG_ERROR(PLID, "GetEngineFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION); LOG_ERROR(PLID, "GetEngineFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION);
*interfaceVersion = ENGINE_INTERFACE_VERSION; *interfaceVersion = ENGINE_INTERFACE_VERSION;
@ -1115,4 +1255,17 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
} }
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t)); memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return(TRUE); return(TRUE);
*/
}
NEW_DLL_FUNCTIONS gNewDLLFunctionTable;
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
return g_FakeMeta.GetNewDLLFunctions(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable);
}
NEW_DLL_FUNCTIONS gNewDLLFunctionTable_Post;
C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
return g_FakeMeta.GetNewDLLFunctions_Post(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable_Post);
} }