diff --git a/amxmodx/amx.h b/amxmodx/amx.h index c2781635..bcd661e2 100755 --- a/amxmodx/amx.h +++ b/amxmodx/amx.h @@ -46,14 +46,15 @@ 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__ + // evilspy's fix for mingw + #if defined __GNUC__ typedef long long int64_t; typedef unsigned long long uint64_t; #define HAVE_I64 + #elif defined __WIN32__ || defined _WIN32 || defined WIN32 + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #define HAVE_I64 #endif #endif #endif diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 5ffcb2d8..614b4cdd 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -37,9 +37,11 @@ #include #include #endif +#include //tolower, etc #include "string.h" #include #include +#include "mm_pextensions.h" // metamod-p extensions #ifdef MEMORY_TEST #include "mmgr/mmgr.h" @@ -134,6 +136,7 @@ struct fakecmd_t { bool fake; }; +extern pextension_funcs_t *gpMetaPExtFuncs; extern CLog g_log; extern CPluginMngr g_plugins; extern CTaskMngr g_tasksMngr; diff --git a/amxmodx/fakemeta.cpp b/amxmodx/fakemeta.cpp index 3f00c6d9..40faa3a2 100755 --- a/amxmodx/fakemeta.cpp +++ b/amxmodx/fakemeta.cpp @@ -2354,6 +2354,14 @@ void FakeMeta_New_CVarRegister(cvar_t *pCVar) int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs) { + //using metamod p-extensions? + if(gpMetaPExtFuncs) + { + //load plugins in meta_attach + m_Status = PL_OPENED; + return 1; + } + // Load the library // We don't have to DLCLOSE here. m_Handle = DLOPEN(build_pathname("%s", m_Path.c_str())); @@ -2419,6 +2427,18 @@ int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs) 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) { + m_Status = PL_FAILED; + return 0; + } + + m_Status = PL_RUNNING; + return 1; + } + if (!m_Handle) return 0; META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach"); @@ -2443,6 +2463,19 @@ int CFakeMeta::CFakeMetaPlugin::Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reaso { if (!m_Handle) 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; + } + META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach"); if (!detachFn) { @@ -2533,6 +2566,11 @@ void CFakeMeta::ReleasePlugins() bool CFakeMeta::AddCorePlugin() { + // evilspy: + // not needed when using metamod p-extensions + if(gpMetaPExtFuncs) + return true; + // Check whether there already is a core plugin if (m_Plugins.begin() && strcmp((*m_Plugins.begin()).GetPath(), "[AMXX Core]") == 0) return true; @@ -2596,6 +2634,14 @@ int CFakeMeta::GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion = INTERFACE_VERSION; return(FALSE); } + + // evilspy: + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) ); + return TRUE; + } + memcpy( pFunctionTable, &g_DllFunctionTable, sizeof( DLL_FUNCTIONS ) ); // Make sure there is a core plugin @@ -2625,6 +2671,14 @@ int CFakeMeta::GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/ *interfaceVersion = INTERFACE_VERSION; return(FALSE); } + + // evilspy + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) ); + return TRUE; + } + memcpy( pFunctionTable, &g_DllFunctionTable_Post, sizeof( DLL_FUNCTIONS ) ); // Make sure there is a core plugin @@ -2654,6 +2708,14 @@ int CFakeMeta::GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inter *interfaceVersion = ENGINE_INTERFACE_VERSION; return FALSE; } + + // evilspy: + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) ); + return TRUE; + } + memcpy( pengfuncsFromEngine, &g_EngineFunctionTable, sizeof( enginefuncs_t ) ); // Make sure there is a core plugin @@ -2682,6 +2744,14 @@ int CFakeMeta::GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int * *interfaceVersion = ENGINE_INTERFACE_VERSION; return FALSE; } + + // evilspy: + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) ); + return TRUE; + } + memcpy( pengfuncsFromEngine, &g_EngineFunctionTable_Post, sizeof( enginefuncs_t ) ); // Make sure there is a core plugin @@ -2717,6 +2787,14 @@ int CFakeMeta::GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *int *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; return(FALSE); } + + // evilspy: + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) ); + return TRUE; + } + memcpy( pNewFunctionTable, &g_NewDllFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) ); // Make sure there is a core plugin @@ -2752,6 +2830,14 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; return(FALSE); } + + // evilspy: + //using metamod p-extensions? + if(gpMetaPExtFuncs) { + 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 diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index ea5355e4..9b179a95 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -50,6 +50,7 @@ gamedll_funcs_t *gpGamedllFuncs; mutil_funcs_t *gpMetaUtilFuncs; enginefuncs_t g_engfuncs; globalvars_t *gpGlobals; +pextension_funcs_t *gpMetaPExtFuncs; funEventCall modMsgsEnd[MAX_REG_MSGS]; funEventCall modMsgs[MAX_REG_MSGS]; @@ -1042,10 +1043,24 @@ C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_ 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); } + + // We can set this to null here because Meta_PExtGiveFnptrs is called after this + gpMetaPExtFuncs = NULL; + // :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); } +// evilspy's patch for mm-p ext support +// this is called right after Meta_Query +C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) { + if(interfaceVersion Plugin_info.loadable) { diff --git a/amxmodx/mm_pextensions.h b/amxmodx/mm_pextensions.h new file mode 100755 index 00000000..fe006843 --- /dev/null +++ b/amxmodx/mm_pextensions.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2004 Jussi Kivilinna + * + * This file is part of "Metamod All-Mod-Support"-patch for Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_PEXTENSIONS_H +#define MM_PEXTENSIONS_H + +#include "plinfo.h" // plid_t +#include "meta_api.h" // PLUG_LOADTIME +/* + + How to use: + 1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file. + 'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call. + 2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION' + and pointer to extension function table. + 3. Meta_PExtGiveFnptrs should return plugin's interface version. + 4. !NOTE! Metamod will not stop loading plugin even if plugin returns + interface version greater than current. Plugin should disable itself in + this kind of situation. + + Example: + #include "mm_pextensions.h" + + pextension_funcs_t *gpMetaPExtFuncs; + + int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) { + if(interfaceVersion < META_PEXT_VERSION) { + LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!"); + gpMetaPExtFuncs = NULL; + + return(META_PEXT_VERSION); + } + + gpMetaPExtFuncs = pMetaPExtFuncs; + + return(META_PEXT_VERSION); + } + + Callback functions: + - int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle); + Parses 'cmdline' as metamod would parse 'meta load ' 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 ' 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 */