mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 22:35:37 +03:00
Initial import of replacement Library system - Backwards compat tested!
Updated new SDK (bumped vers number, kept backwards compat) Improved module path resolving
This commit is contained in:
parent
576680eaf9
commit
dad00a2eb6
@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
#include "libraries.h"
|
||||||
|
|
||||||
#ifndef FAR
|
#ifndef FAR
|
||||||
#define FAR
|
#define FAR
|
||||||
@ -41,6 +42,8 @@ typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo
|
|||||||
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
||||||
typedef int (FAR *DETACHMOD_NEW)(void);
|
typedef int (FAR *DETACHMOD_NEW)(void);
|
||||||
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
||||||
|
typedef void (*PLUGINSUNLOADED_NEW)(void);
|
||||||
|
typedef void (*PLUGINSUNLOADING_NEW)(void);
|
||||||
|
|
||||||
// *****************************************************
|
// *****************************************************
|
||||||
// class CModule
|
// class CModule
|
||||||
@ -126,7 +129,7 @@ bool CModule::attachModule()
|
|||||||
{
|
{
|
||||||
case AMXX_OK:
|
case AMXX_OK:
|
||||||
m_Status = MODULE_LOADED;
|
m_Status = MODULE_LOADED;
|
||||||
return true;
|
break;
|
||||||
case AMXX_PARAM:
|
case AMXX_PARAM:
|
||||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||||
m_Status = MODULE_INTERROR;
|
m_Status = MODULE_INTERROR;
|
||||||
@ -144,6 +147,13 @@ bool CModule::attachModule()
|
|||||||
m_Status = MODULE_BADLOAD;
|
m_Status = MODULE_BADLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_Status == MODULE_LOADED)
|
||||||
|
{
|
||||||
|
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
|
||||||
|
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,10 +194,36 @@ bool CModule::queryModule()
|
|||||||
return false;
|
return false;
|
||||||
case AMXX_IFVERS:
|
case AMXX_IFVERS:
|
||||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||||
m_Status = MODULE_OLD;
|
{
|
||||||
else
|
//backwards compat for new defs
|
||||||
|
if (ifVers == 3)
|
||||||
|
{
|
||||||
|
g_ModuleCallReason = ModuleCall_Query;
|
||||||
|
g_CurrentlyCalledModule = this;
|
||||||
|
retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||||
|
g_CurrentlyCalledModule = NULL;
|
||||||
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
|
if (retVal == AMXX_OK)
|
||||||
|
{
|
||||||
|
m_InfoNew.library = m_InfoNew.logtag;
|
||||||
|
if (StrCaseStr(m_InfoNew.library, "sql")
|
||||||
|
|| StrCaseStr(m_InfoNew.library, "dbi"))
|
||||||
|
{
|
||||||
|
m_InfoNew.libclass = "DBI";
|
||||||
|
} else {
|
||||||
|
m_InfoNew.libclass = "";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
m_Status = MODULE_OLD;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
m_Status = MODULE_NEWER;
|
m_Status = MODULE_NEWER;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
case AMXX_OK:
|
case AMXX_OK:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -217,6 +253,8 @@ bool CModule::detachModule()
|
|||||||
if (m_Status != MODULE_LOADED)
|
if (m_Status != MODULE_LOADED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
RemoveLibraries(this);
|
||||||
|
|
||||||
if (m_Amxx)
|
if (m_Amxx)
|
||||||
{
|
{
|
||||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||||
@ -244,6 +282,38 @@ bool CModule::detachModule()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CModule::CallPluginsUnloaded()
|
||||||
|
{
|
||||||
|
if (m_Status != MODULE_LOADED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_Handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
|
||||||
|
|
||||||
|
if (!func)
|
||||||
|
return;
|
||||||
|
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CModule::CallPluginsUnloading()
|
||||||
|
{
|
||||||
|
if (m_Status != MODULE_LOADED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_Handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
|
||||||
|
|
||||||
|
if (!func)
|
||||||
|
return;
|
||||||
|
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
void CModule::CallPluginsLoaded()
|
void CModule::CallPluginsLoaded()
|
||||||
{
|
{
|
||||||
if (m_Status != MODULE_LOADED)
|
if (m_Status != MODULE_LOADED)
|
||||||
|
@ -59,6 +59,8 @@ struct amxx_module_info_s
|
|||||||
const char *version;
|
const char *version;
|
||||||
int reload; // reload on mapchange when nonzero
|
int reload; // reload on mapchange when nonzero
|
||||||
const char *logtag; //added in version 2
|
const char *logtag; //added in version 2
|
||||||
|
const char *library; // added in version 4
|
||||||
|
const char *libclass; // added in version 4
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AMXX_OK 0 /* no error */
|
#define AMXX_OK 0 /* no error */
|
||||||
@ -66,7 +68,7 @@ struct amxx_module_info_s
|
|||||||
#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 4
|
||||||
|
|
||||||
class CModule
|
class CModule
|
||||||
{
|
{
|
||||||
@ -110,6 +112,8 @@ public:
|
|||||||
inline bool IsMetamod() { return m_Metamod; }
|
inline bool IsMetamod() { return m_Metamod; }
|
||||||
|
|
||||||
void CallPluginsLoaded();
|
void CallPluginsLoaded();
|
||||||
|
void CallPluginsUnloaded();
|
||||||
|
void CallPluginsUnloading();
|
||||||
|
|
||||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "binlog.h"
|
#include "binlog.h"
|
||||||
|
#include "libraries.h"
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
@ -3716,43 +3717,18 @@ static cell AMX_NATIVE_CALL module_exists(AMX *amx, cell *params)
|
|||||||
int len;
|
int len;
|
||||||
char *module = get_amxstring(amx, params[1], 0, len);
|
char *module = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
CList<CModule, const char *>::iterator a;
|
if (!FindLibrary(module, LibType_Library))
|
||||||
|
return FindLibrary(module, LibType_Class);
|
||||||
|
|
||||||
bool isdbi = false, found = false;
|
return true;
|
||||||
const amxx_module_info_s *info;
|
}
|
||||||
|
|
||||||
if (stricmp(module, "dbi") == 0)
|
static cell AMX_NATIVE_CALL LibraryExists(AMX *amx, cell *params)
|
||||||
isdbi = true;
|
{
|
||||||
|
int len;
|
||||||
|
char *library = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
for (a = g_modules.begin(); a; ++a)
|
return FindLibrary(library, static_cast<LibType>(params[2]));
|
||||||
{
|
|
||||||
if ((*a).getStatusValue() == MODULE_LOADED)
|
|
||||||
{
|
|
||||||
info = (*a).getInfoNew();
|
|
||||||
if (info)
|
|
||||||
{
|
|
||||||
if (isdbi)
|
|
||||||
{
|
|
||||||
if (info->logtag && (StrCaseStr(info->logtag, "sql") || StrCaseStr(info->logtag, "dbi")))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (info->logtag && (stricmp(info->logtag, module) == 0))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
|
||||||
found = LibraryExists(module);
|
|
||||||
|
|
||||||
return (found ? 1 : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL set_fail_state(AMX *amx, cell *params)
|
||||||
@ -4242,5 +4218,6 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
|||||||
{"ExecuteForward", ExecuteForward},
|
{"ExecuteForward", ExecuteForward},
|
||||||
{"PrepareArray", PrepareArray},
|
{"PrepareArray", PrepareArray},
|
||||||
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
||||||
|
{"LibraryExists", LibraryExists},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -263,6 +263,8 @@ enum CountModulesMode
|
|||||||
|
|
||||||
int countModules(CountModulesMode mode);
|
int countModules(CountModulesMode mode);
|
||||||
void modules_callPluginsLoaded();
|
void modules_callPluginsLoaded();
|
||||||
|
void modules_callPluginsUnloaded();
|
||||||
|
void modules_callPluginsUnloading();
|
||||||
|
|
||||||
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
||||||
char* build_pathname(char *fmt, ...);
|
char* build_pathname(char *fmt, ...);
|
||||||
|
@ -506,6 +506,7 @@ void C_ServerDeactivate_Post()
|
|||||||
g_xvars.clear();
|
g_xvars.clear();
|
||||||
g_plugins.clear();
|
g_plugins.clear();
|
||||||
ClearPluginLibraries();
|
ClearPluginLibraries();
|
||||||
|
modules_callPluginsUnloaded();
|
||||||
|
|
||||||
for (unsigned int i=0; i<g_hudsync.size(); i++)
|
for (unsigned int i=0; i<g_hudsync.size(); i++)
|
||||||
delete [] g_hudsync[i];
|
delete [] g_hudsync[i];
|
||||||
@ -1295,12 +1296,17 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
|||||||
g_cvars.clear();
|
g_cvars.clear();
|
||||||
g_langMngr.Clear();
|
g_langMngr.Clear();
|
||||||
|
|
||||||
|
modules_callPluginsUnloaded();
|
||||||
|
|
||||||
detachModules();
|
detachModules();
|
||||||
|
|
||||||
g_log.CloseFile();
|
g_log.CloseFile();
|
||||||
|
|
||||||
Module_UncacheFunctions();
|
Module_UncacheFunctions();
|
||||||
|
|
||||||
|
ClearLibraries(LibSource_Plugin);
|
||||||
|
ClearLibraries(LibSource_Module);
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "optimizer.h"
|
#include "optimizer.h"
|
||||||
#include "binlog.h"
|
#include "binlog.h"
|
||||||
|
#include "libraries.h"
|
||||||
|
|
||||||
CList<CModule, const char*> g_modules;
|
CList<CModule, const char*> g_modules;
|
||||||
CList<CScript, AMX*> g_loadedscripts;
|
CList<CScript, AMX*> g_loadedscripts;
|
||||||
@ -427,68 +428,61 @@ const char *StrCaseStr(const char *as, const char *bs)
|
|||||||
int CheckModules(AMX *amx, char error[128])
|
int CheckModules(AMX *amx, char error[128])
|
||||||
{
|
{
|
||||||
int numLibraries = amx_GetLibraries(amx);
|
int numLibraries = amx_GetLibraries(amx);
|
||||||
char buffer[32];
|
char buffer[64];
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
bool isdbi = false;
|
|
||||||
|
|
||||||
CList<CModule, const char *>::iterator a;
|
|
||||||
|
|
||||||
const amxx_module_info_s *info;
|
|
||||||
|
|
||||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||||
|
|
||||||
for (int i = 0; i < numLibraries; i++)
|
for (int i = 0; i < numLibraries; i++)
|
||||||
{
|
{
|
||||||
amx_GetLibrary(amx, i, buffer, sizeof(buffer) - 1);
|
amx_GetLibrary(amx, i, buffer, sizeof(buffer) - 1);
|
||||||
found = false;
|
|
||||||
|
|
||||||
if (stricmp(buffer, "float") == 0)
|
if (stricmp(buffer, "float") == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
isdbi = false;
|
LibDecoder dcd;
|
||||||
|
LibType expect;
|
||||||
|
bool found = false;
|
||||||
|
const char *search = NULL;
|
||||||
|
|
||||||
if (stricmp(buffer, "dbi") == 0)
|
DecodeLibCmdString(buffer, dcd);
|
||||||
isdbi = true;
|
|
||||||
|
|
||||||
for (a = g_modules.begin(); a; ++a)
|
switch (dcd.cmd)
|
||||||
{
|
{
|
||||||
if ((*a).getStatusValue() == MODULE_LOADED)
|
case LibCmd_ReqLib:
|
||||||
{
|
search = dcd.param1;
|
||||||
info = (*a).getInfoNew();
|
expect = LibType_Library;
|
||||||
|
break;
|
||||||
if (info)
|
case LibCmd_ExpectLib:
|
||||||
{
|
search = dcd.param2;
|
||||||
if (isdbi)
|
expect = LibType_Library;
|
||||||
{
|
break;
|
||||||
if (info->logtag && (StrCaseStr(info->logtag, "sql") || StrCaseStr(info->logtag, "dbi")))
|
case LibCmd_ReqClass:
|
||||||
{
|
search = dcd.param1;
|
||||||
found = true;
|
expect = LibType_Class;
|
||||||
break;
|
break;
|
||||||
}
|
case LibCmd_ExpectClass:
|
||||||
} else {
|
search = dcd.param2;
|
||||||
if (info->logtag && (stricmp(info->logtag, buffer) == 0))
|
expect = LibType_Class;
|
||||||
{
|
break;
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!search)
|
||||||
found = LibraryExists(buffer);
|
continue;
|
||||||
|
|
||||||
|
found = FindLibrary(search, expect);
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
if (pHandler->HandleModule(buffer))
|
if (pHandler->HandleModule(search))
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
sprintf(error, "Module \"%s\" required for plugin. Check modules.ini.", buffer);
|
const char *type = "Module/Library";
|
||||||
|
if (expect == LibType_Class)
|
||||||
|
type = "Module/Library Class";
|
||||||
|
sprintf(error, "%s \"%s\" required for plugin. Check modules.ini.", type, search);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -735,130 +729,202 @@ char* build_pathname_addons(char *fmt, ...)
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validFile(const char* file)
|
#if defined WIN32
|
||||||
{
|
#define SEPCHAR '\\'
|
||||||
const char* a = 0;
|
#elif defined __linux__
|
||||||
|
#define SEPCHAR '/'
|
||||||
while (*file)
|
|
||||||
if (*file++ == '.')
|
|
||||||
a = file;
|
|
||||||
#ifndef __linux__
|
|
||||||
return (a && !strcmp(a, "dll"));
|
|
||||||
#else
|
|
||||||
return (a && !strcmp(a, "so"));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool ConvertModuleName(const char *pathString, String &path)
|
||||||
|
{
|
||||||
|
String local;
|
||||||
|
|
||||||
|
local.assign(pathString);
|
||||||
|
char *tmpname = const_cast<char *>(local.c_str());
|
||||||
|
char *orig_path = tmpname;
|
||||||
|
|
||||||
|
path.clear();
|
||||||
|
|
||||||
|
size_t len = local.size();
|
||||||
|
if (!len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* run to filename instead of dir */
|
||||||
|
char *ptr = tmpname;
|
||||||
|
ptr = tmpname + len - 1;
|
||||||
|
while (ptr >= tmpname && *ptr != SEPCHAR)
|
||||||
|
ptr--;
|
||||||
|
if (ptr >= tmpname)
|
||||||
|
{
|
||||||
|
*ptr++ = '\0';
|
||||||
|
tmpname = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool foundAmxx = false;
|
||||||
|
int iDigit = '3';
|
||||||
|
ptr = tmpname;
|
||||||
|
while (*ptr)
|
||||||
|
{
|
||||||
|
while (*ptr && *ptr != '_')
|
||||||
|
ptr++;
|
||||||
|
if (strncmp(ptr, "_amxx", 5) == 0)
|
||||||
|
{
|
||||||
|
char *p = ptr + 5;
|
||||||
|
if (strncmp(p, ".dll", 4) == 0)
|
||||||
|
{
|
||||||
|
foundAmxx = true;
|
||||||
|
break;
|
||||||
|
} else if (p[0] == '_') {
|
||||||
|
p++;
|
||||||
|
if (strncmp(p, "amd64.so", 8) == 0)
|
||||||
|
{
|
||||||
|
foundAmxx = true;
|
||||||
|
break;
|
||||||
|
} else if (p[0] == 'i') {
|
||||||
|
p++;
|
||||||
|
if (isdigit(p[0]) && p[1] == '8' && p[2] == '6')
|
||||||
|
{
|
||||||
|
iDigit = p[0];
|
||||||
|
foundAmxx = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (p[0] == '\0') {
|
||||||
|
foundAmxx = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (*ptr && *ptr == '_')
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundAmxx)
|
||||||
|
{
|
||||||
|
ptr = tmpname + strlen(tmpname); - 1;
|
||||||
|
while (ptr >= tmpname && *ptr != '.')
|
||||||
|
ptr--;
|
||||||
|
if (ptr > tmpname && *ptr == '.')
|
||||||
|
{
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
path.assign(orig_path);
|
||||||
|
path.append(SEPCHAR);
|
||||||
|
path.append(tmpname);
|
||||||
|
path.append("_amxx");
|
||||||
|
#if defined __linux__
|
||||||
|
#if defined AMD64 || PAWN_CELL_SIZE==64
|
||||||
|
path.append("amd64");
|
||||||
|
#else
|
||||||
|
path.append("i");
|
||||||
|
path.append(iDigit);
|
||||||
|
path.append("86");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined WIN32
|
||||||
|
path.append(".dll");
|
||||||
|
#elif defined __linux__
|
||||||
|
path.append(".so");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FILE *fp = fopen(path.c_str(), "rb");
|
||||||
|
if (!fp)
|
||||||
|
return false;
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertModuleName(const char *pathString, String &path)
|
bool LoadModule(const char *shortname, PLUG_LOADTIME now)
|
||||||
{
|
{
|
||||||
#if PAWN_CELL_SIZE==64
|
char pathString[512];
|
||||||
char *ptr = strstr(pathString, "i386");
|
String path;
|
||||||
|
|
||||||
if (ptr)
|
build_pathname_r(
|
||||||
|
pathString,
|
||||||
|
sizeof(pathString)-1,
|
||||||
|
"%s/%s",
|
||||||
|
get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"),
|
||||||
|
shortname);
|
||||||
|
|
||||||
|
if (!ConvertModuleName(pathString, path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CList<CModule, const char *>::iterator a = g_modules.find(path.c_str());
|
||||||
|
|
||||||
|
if (a)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CModule* cc = new CModule(path.c_str());
|
||||||
|
|
||||||
|
cc->queryModule();
|
||||||
|
|
||||||
|
switch (cc->getStatusValue())
|
||||||
{
|
{
|
||||||
//attempt to fix the binary name
|
case MODULE_BADLOAD:
|
||||||
*ptr = 0;
|
report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", path.c_str());
|
||||||
path.assign(pathString);
|
break;
|
||||||
path.append("amd64.so");
|
case MODULE_NOINFO:
|
||||||
} else {
|
report_error(1, "[AMXX] Couldn't find info about module (file \"%s\")", path.c_str());
|
||||||
ptr = strstr(pathString, ".dll");
|
break;
|
||||||
|
case MODULE_NOQUERY:
|
||||||
if (ptr)
|
report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path.c_str());
|
||||||
{
|
break;
|
||||||
*ptr = 0;
|
case MODULE_NOATTACH:
|
||||||
path.assign(pathString);
|
report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", cc->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path.c_str());
|
||||||
path.append("_amd64.so");
|
break;
|
||||||
} else {
|
case MODULE_OLD:
|
||||||
ptr = strstr(pathString, ".so");
|
report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path.c_str());
|
||||||
|
break;
|
||||||
if (ptr)
|
case MODULE_NEWER:
|
||||||
{
|
report_error(1, "[AMXX] Module has a newer interface version (file \"%s\"). Please download a new amxmodx.", path.c_str());
|
||||||
path.assign(pathString);
|
break;
|
||||||
} else {
|
case MODULE_INTERROR:
|
||||||
//no extension at all
|
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", path.c_str());
|
||||||
path.assign(pathString);
|
break;
|
||||||
path.append("_amd64.so");
|
case MODULE_NOT64BIT:
|
||||||
}
|
report_error(1, "[AMXX] Module \"%s\" is not 64 bit compatible.", path.c_str());
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef __linux__
|
g_modules.put(cc);
|
||||||
char *ptr = strstr(pathString, "amd64");
|
|
||||||
|
|
||||||
if (ptr)
|
if (cc->IsMetamod())
|
||||||
{
|
{
|
||||||
//attempt to fix the binary name
|
char *mmpathname = build_pathname_addons(
|
||||||
*ptr = 0;
|
"%s/%s",
|
||||||
path.assign(pathString);
|
get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"),
|
||||||
path.append("i386.so");
|
shortname);
|
||||||
} else {
|
ConvertModuleName(mmpathname, path);
|
||||||
ptr = strstr(pathString, ".dll");
|
cc->attachMetamod(path.c_str(), now);
|
||||||
|
|
||||||
if (ptr)
|
|
||||||
{
|
|
||||||
*ptr = 0;
|
|
||||||
path.assign(pathString);
|
|
||||||
path.append("_i386.so");
|
|
||||||
} else {
|
|
||||||
//check to see if this file even has an extension
|
|
||||||
ptr = strstr(pathString, ".so");
|
|
||||||
|
|
||||||
if (ptr)
|
|
||||||
{
|
|
||||||
path.assign(pathString);
|
|
||||||
} else {
|
|
||||||
path.assign(pathString);
|
|
||||||
path.append("_i386.so");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
char *ptr = const_cast<char*>(strstr(pathString, ".dll"));
|
|
||||||
|
|
||||||
if (ptr)
|
bool retVal = cc->attachModule();
|
||||||
|
|
||||||
|
if (cc->isAmxx() && !retVal)
|
||||||
{
|
{
|
||||||
path.assign(pathString);
|
switch (cc->getStatusValue())
|
||||||
} else {
|
|
||||||
//prevent this from loading .so too
|
|
||||||
ptr = const_cast<char*>(strstr(pathString, ".so"));
|
|
||||||
|
|
||||||
if (ptr)
|
|
||||||
{
|
{
|
||||||
int i = 0, len = strlen(pathString), c = -1;
|
case MODULE_FUNCNOTPRESENT:
|
||||||
|
report_error(1, "[AMXX] Module requested a not exisitng function (file \"%s\")%s%s%s", cc->getFilename(), cc->getMissingFunc() ? " (func \"" : "",
|
||||||
for (i = len - 1; i >= 0; i--)
|
cc->getMissingFunc() ? cc->getMissingFunc() : "", cc->getMissingFunc() ? "\")" : "");
|
||||||
{
|
break;
|
||||||
//cut off at first _
|
case MODULE_INTERROR:
|
||||||
if (pathString[i] == '_')
|
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", cc->getFilename());
|
||||||
{
|
break;
|
||||||
//make sure this is a valid _
|
case MODULE_BADLOAD:
|
||||||
if (i == len - 1 || strncmp(&(pathString[i + 1]), "amxx", 4) == 0)
|
report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", cc->getFilename());
|
||||||
break;
|
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
#endif //__linux__
|
|
||||||
#endif //PAWN_CELL_SIZE==64
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadModules(const char* filename, PLUG_LOADTIME now)
|
int loadModules(const char* filename, PLUG_LOADTIME now)
|
||||||
@ -872,7 +938,6 @@ int loadModules(const char* filename, PLUG_LOADTIME now)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char moduleName[256];
|
char moduleName[256];
|
||||||
char pathString[512];
|
|
||||||
String line;
|
String line;
|
||||||
int loaded = 0;
|
int loaded = 0;
|
||||||
|
|
||||||
@ -892,91 +957,8 @@ int loadModules(const char* filename, PLUG_LOADTIME now)
|
|||||||
if (moduleName[0] == ';')
|
if (moduleName[0] == ';')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char* pathname = build_pathname("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), moduleName);
|
if (LoadModule(moduleName, now))
|
||||||
strcpy(pathString, pathname);
|
loaded++;
|
||||||
|
|
||||||
path.assign("");
|
|
||||||
|
|
||||||
ConvertModuleName(pathString, path);
|
|
||||||
|
|
||||||
if (!validFile(path.c_str()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CList<CModule, const char *>::iterator a = g_modules.find(path.c_str());
|
|
||||||
|
|
||||||
if (a)
|
|
||||||
continue; // already loaded
|
|
||||||
|
|
||||||
CModule* cc = new CModule(path.c_str());
|
|
||||||
|
|
||||||
if (cc == 0)
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
cc->queryModule();
|
|
||||||
|
|
||||||
switch (cc->getStatusValue())
|
|
||||||
{
|
|
||||||
case MODULE_BADLOAD:
|
|
||||||
report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_NOINFO:
|
|
||||||
report_error(1, "[AMXX] Couldn't find info. about module (file \"%s\")", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_NOQUERY:
|
|
||||||
report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_NOATTACH:
|
|
||||||
report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", cc->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_OLD:
|
|
||||||
report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_NEWER:
|
|
||||||
report_error(1, "[AMXX] Module has a newer interface version (file \"%s\"). Please download a new amxmodx.", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_INTERROR:
|
|
||||||
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", path.c_str());
|
|
||||||
break;
|
|
||||||
case MODULE_NOT64BIT:
|
|
||||||
report_error(1, "[AMXX] Module \"%s\" is not 64 bit compatible.", path.c_str());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
++loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_modules.put(cc);
|
|
||||||
|
|
||||||
if (cc->IsMetamod())
|
|
||||||
{
|
|
||||||
char* mmpathname = build_pathname_addons("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), line.c_str());
|
|
||||||
|
|
||||||
ConvertModuleName(mmpathname, path);
|
|
||||||
cc->attachMetamod(path.c_str(), now);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool retVal = cc->attachModule();
|
|
||||||
|
|
||||||
if (cc->isAmxx() && !retVal)
|
|
||||||
{
|
|
||||||
switch (cc->getStatusValue())
|
|
||||||
{
|
|
||||||
case MODULE_FUNCNOTPRESENT:
|
|
||||||
report_error(1, "[AMXX] Module requested a not exisitng function (file \"%s\")%s%s%s", cc->getFilename(), cc->getMissingFunc() ? " (func \"" : "",
|
|
||||||
cc->getMissingFunc() ? cc->getMissingFunc() : "", cc->getMissingFunc() ? "\")" : "");
|
|
||||||
break;
|
|
||||||
case MODULE_INTERROR:
|
|
||||||
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", cc->getFilename());
|
|
||||||
break;
|
|
||||||
case MODULE_BADLOAD:
|
|
||||||
report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", cc->getFilename());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -1080,6 +1062,29 @@ void modules_callPluginsLoaded()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//same for unloaded
|
||||||
|
void modules_callPluginsUnloaded()
|
||||||
|
{
|
||||||
|
CList<CModule, const char *>::iterator iter = g_modules.begin();
|
||||||
|
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
(*iter).CallPluginsUnloaded();
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void modules_callPluginsUnloading()
|
||||||
|
{
|
||||||
|
CList<CModule, const char *>::iterator iter = g_modules.begin();
|
||||||
|
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
(*iter).CallPluginsUnloading();
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// new functions
|
// new functions
|
||||||
int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
||||||
{
|
{
|
||||||
@ -1493,6 +1498,21 @@ void MNF_MergeDefinitionFile(const char *file)
|
|||||||
g_langMngr.MergeDefinitionFile(file);
|
g_langMngr.MergeDefinitionFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MNF_FindLibrary(const char *name, LibType type)
|
||||||
|
{
|
||||||
|
return FindLibrary(name, type) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MFN_AddLibraries(const char *name, LibType type, void *parent)
|
||||||
|
{
|
||||||
|
return AddLibrariesFromString(name, type, LibSource_Module, parent) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MNF_RemoveLibraries(void *parent)
|
||||||
|
{
|
||||||
|
return RemoveLibraries(parent);
|
||||||
|
}
|
||||||
|
|
||||||
edict_t* MNF_GetPlayerEdict(int id)
|
edict_t* MNF_GetPlayerEdict(int id)
|
||||||
{
|
{
|
||||||
if (id < 1 || id > gpGlobals->maxClients)
|
if (id < 1 || id > gpGlobals->maxClients)
|
||||||
@ -1732,6 +1752,10 @@ void Module_CacheFunctions()
|
|||||||
REGISTER_FUNC("RegAuthFunc", MNF_RegAuthorizeFunc);
|
REGISTER_FUNC("RegAuthFunc", MNF_RegAuthorizeFunc);
|
||||||
REGISTER_FUNC("UnregAuthFunc", MNF_UnregAuthorizeFunc);
|
REGISTER_FUNC("UnregAuthFunc", MNF_UnregAuthorizeFunc);
|
||||||
|
|
||||||
|
REGISTER_FUNC("FindLibrary", MNF_FindLibrary);
|
||||||
|
REGISTER_FUNC("AddLibraries", MFN_AddLibraries);
|
||||||
|
REGISTER_FUNC("RemoveLibraries", MNF_RemoveLibraries);
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
REGISTER_FUNC("Allocator", m_allocator)
|
REGISTER_FUNC("Allocator", m_allocator)
|
||||||
REGISTER_FUNC("Deallocator", m_deallocator)
|
REGISTER_FUNC("Deallocator", m_deallocator)
|
||||||
|
@ -72,6 +72,7 @@ typedef enum
|
|||||||
} PlayerProp;
|
} PlayerProp;
|
||||||
|
|
||||||
int CheckModules(AMX *amx, char error[128]);
|
int CheckModules(AMX *amx, char error[128]);
|
||||||
|
bool LoadModule(const char *shortname, PLUG_LOADTIME now);
|
||||||
const char *StrCaseStr(const char *as, const char *bs);
|
const char *StrCaseStr(const char *as, const char *bs);
|
||||||
|
|
||||||
class Debugger;
|
class Debugger;
|
||||||
@ -79,7 +80,6 @@ Debugger *DisableDebugHandler(AMX *amx);
|
|||||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
||||||
|
|
||||||
bool DirExists(const char *dir);
|
bool DirExists(const char *dir);
|
||||||
|
|
||||||
const char* GetFileName(AMX *amx);
|
const char* GetFileName(AMX *amx);
|
||||||
|
|
||||||
#endif // __MODULES_H__
|
#endif // __MODULES_H__
|
||||||
|
@ -415,6 +415,9 @@
|
|||||||
AssemblerOutput="4"/>
|
AssemblerOutput="4"/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libraries.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.cpp">
|
RelativePath="..\md5.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -542,6 +545,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\format.h">
|
RelativePath="..\format.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libraries.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\md5.h">
|
RelativePath="..\md5.h">
|
||||||
</File>
|
</File>
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "sh_stack.h"
|
#include "sh_stack.h"
|
||||||
#include "natives.h"
|
#include "natives.h"
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
|
#include "libraries.h"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -47,7 +48,6 @@
|
|||||||
CStack<int> g_ErrorStk;
|
CStack<int> g_ErrorStk;
|
||||||
CVector<regnative *> g_RegNatives;
|
CVector<regnative *> g_RegNatives;
|
||||||
CStack<regnative *> g_NativeStack;
|
CStack<regnative *> g_NativeStack;
|
||||||
CVector<String> g_Libraries;
|
|
||||||
static char g_errorStr[512] = {0};
|
static char g_errorStr[512] = {0};
|
||||||
bool g_Initialized = false;
|
bool g_Initialized = false;
|
||||||
|
|
||||||
@ -343,7 +343,7 @@ static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
|||||||
int len;
|
int len;
|
||||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
char *lib = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
AddPluginLibrary(lib);
|
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -396,27 +396,9 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
|||||||
return 1;
|
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()
|
void ClearPluginLibraries()
|
||||||
{
|
{
|
||||||
g_Libraries.clear();
|
ClearLibraries(LibSource_Plugin);
|
||||||
|
|
||||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||||
{
|
{
|
||||||
delete [] g_RegNatives[i]->pfn;
|
delete [] g_RegNatives[i]->pfn;
|
||||||
|
@ -61,9 +61,7 @@ extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
|||||||
extern "C" int amxx_DynaCodesize();
|
extern "C" int amxx_DynaCodesize();
|
||||||
|
|
||||||
AMX_NATIVE_INFO *BuildNativeTable();
|
AMX_NATIVE_INFO *BuildNativeTable();
|
||||||
void AddPluginLibrary(const char *name);
|
|
||||||
void ClearPluginLibraries();
|
void ClearPluginLibraries();
|
||||||
bool LibraryExists(const char *name);
|
|
||||||
|
|
||||||
//I couldn't resist :)
|
//I couldn't resist :)
|
||||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
extern AMX_NATIVE_INFO g_NativeNatives[];
|
||||||
|
@ -2430,7 +2430,9 @@ static amxx_module_info_s g_ModuleInfo =
|
|||||||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
0,
|
0,
|
||||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||||
MODULE_LOGTAG
|
MODULE_LOGTAG,
|
||||||
|
MODULE_LIBRARY,
|
||||||
|
MODULE_LIBCLASS
|
||||||
};
|
};
|
||||||
|
|
||||||
// Storage for the requested functions
|
// Storage for the requested functions
|
||||||
@ -2506,6 +2508,9 @@ PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
|||||||
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||||
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||||
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||||
|
PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||||
|
PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||||
|
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||||
|
|
||||||
// *** 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)
|
||||||
@ -2620,6 +2625,10 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||||||
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
|
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
|
||||||
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
|
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
|
||||||
|
|
||||||
|
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
|
||||||
|
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
|
||||||
|
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
// Memory
|
// Memory
|
||||||
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
|
||||||
@ -2654,6 +2663,20 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
|
|||||||
return AMXX_OK;
|
return AMXX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT void AMXX_PluginsUnloaded()
|
||||||
|
{
|
||||||
|
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||||
|
FN_AMXX_PLUGINSUNLOADED();
|
||||||
|
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||||
|
}
|
||||||
|
|
||||||
|
C_DLLEXPORT void AMXX_PluginsUnloading()
|
||||||
|
{
|
||||||
|
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||||
|
FN_AMXX_PLUGINSUNLOADING();
|
||||||
|
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||||
|
}
|
||||||
|
|
||||||
// Advanced MF functions
|
// Advanced MF functions
|
||||||
void MF_Log(const char *fmt, ...)
|
void MF_Log(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -2743,6 +2766,9 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||||||
MF_PlayerPropAddr(0, 0);
|
MF_PlayerPropAddr(0, 0);
|
||||||
MF_RegAuthFunc(NULL);
|
MF_RegAuthFunc(NULL);
|
||||||
MF_UnregAuthFunc(NULL);
|
MF_UnregAuthFunc(NULL);
|
||||||
|
MF_FindLibrary(NULL, LibType_Class);
|
||||||
|
MF_AddLibraries(NULL, LibType_Class, NULL);
|
||||||
|
MF_RemoveLibraries(NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -34,7 +34,8 @@
|
|||||||
// module interface version was 1
|
// module interface version was 1
|
||||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
// 2 - added logtag to struct (amxx1.1-rc1)
|
||||||
// 3 - added new tagAMX structure (amxx1.5)
|
// 3 - added new tagAMX structure (amxx1.5)
|
||||||
#define AMXX_INTERFACE_VERSION 3
|
// 4 - added new 'library' setting for direct loading
|
||||||
|
#define AMXX_INTERFACE_VERSION 4
|
||||||
|
|
||||||
// amxx module info
|
// amxx module info
|
||||||
struct amxx_module_info_s
|
struct amxx_module_info_s
|
||||||
@ -44,6 +45,8 @@ struct amxx_module_info_s
|
|||||||
const char *version;
|
const char *version;
|
||||||
int reload; // reload on mapchange when nonzero
|
int reload; // reload on mapchange when nonzero
|
||||||
const char *logtag; // added in version 2
|
const char *logtag; // added in version 2
|
||||||
|
const char *library; // added in version 4
|
||||||
|
const char *libclass; // added in version 4
|
||||||
};
|
};
|
||||||
|
|
||||||
// return values from functions called by amxx
|
// return values from functions called by amxx
|
||||||
@ -2032,6 +2035,14 @@ void FN_AMXX_DETACH(void);
|
|||||||
void FN_AMXX_PLUGINSLOADED(void);
|
void FN_AMXX_PLUGINSLOADED(void);
|
||||||
#endif // FN_AMXX_PLUGINSLOADED
|
#endif // FN_AMXX_PLUGINSLOADED
|
||||||
|
|
||||||
|
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||||
|
void FN_AMXX_PLUGINSUNLOADING(void);
|
||||||
|
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||||
|
|
||||||
|
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||||
|
void FN_AMXX_PLUGINSUNLOADED(void);
|
||||||
|
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||||
|
|
||||||
// *** Types ***
|
// *** Types ***
|
||||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
|
|
||||||
@ -2078,6 +2089,12 @@ enum PlayerProp
|
|||||||
Player_NewmenuPage, //int
|
Player_NewmenuPage, //int
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum LibType
|
||||||
|
{
|
||||||
|
LibType_Library,
|
||||||
|
LibType_Class
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
||||||
|
|
||||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||||
@ -2159,6 +2176,9 @@ typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
|||||||
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
|
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
|
||||||
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
|
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||||
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
|
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||||
|
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
|
||||||
|
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
|
||||||
|
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
|
||||||
|
|
||||||
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;
|
||||||
@ -2226,6 +2246,9 @@ extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
|||||||
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||||
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||||
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||||
|
extern PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||||
|
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||||
|
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||||
|
|
||||||
#ifdef MAY_NEVER_BE_DEFINED
|
#ifdef MAY_NEVER_BE_DEFINED
|
||||||
// Function prototypes for intellisense and similar systems
|
// Function prototypes for intellisense and similar systems
|
||||||
@ -2290,6 +2313,9 @@ int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
|
|||||||
void * MF_PlayerPropAddr (int id, int prop) { }
|
void * MF_PlayerPropAddr (int id, int prop) { }
|
||||||
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
|
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
|
||||||
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
|
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
|
||||||
|
int MF_FindLibrary (const char *name, LibType type) { }
|
||||||
|
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
|
||||||
|
size_t MF_RemoveLibraries (void *parent) { }
|
||||||
#endif // MAY_NEVER_BE_DEFINED
|
#endif // MAY_NEVER_BE_DEFINED
|
||||||
|
|
||||||
#define MF_AddNatives g_fn_AddNatives
|
#define MF_AddNatives g_fn_AddNatives
|
||||||
@ -2359,6 +2385,9 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|||||||
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
|
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
|
||||||
#define MF_RegAuthFunc g_fn_RegAuthFunc
|
#define MF_RegAuthFunc g_fn_RegAuthFunc
|
||||||
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
|
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
|
||||||
|
#define MF_FindLibrary g_fn_FindLibrary;
|
||||||
|
#define MF_AddLibraries g_fn_AddLibraries;
|
||||||
|
#define MF_RemoveLibraries g_fn_RemoveLibraries;
|
||||||
|
|
||||||
#ifdef MEMORY_TEST
|
#ifdef MEMORY_TEST
|
||||||
/*** Memory ***/
|
/*** Memory ***/
|
||||||
|
@ -3,12 +3,24 @@
|
|||||||
#ifndef __MODULECONFIG_H__
|
#ifndef __MODULECONFIG_H__
|
||||||
#define __MODULECONFIG_H__
|
#define __MODULECONFIG_H__
|
||||||
|
|
||||||
// Module info
|
/** Module info
|
||||||
|
* -The logtag is the tag that the module's log messages will be
|
||||||
|
* prepended with.
|
||||||
|
* -The library is the name that the #pragma library
|
||||||
|
* message will have prepended.
|
||||||
|
* -The library class is the class of libraries that
|
||||||
|
* a module belongs to (like DBI). Keep it "" to
|
||||||
|
* ignore.
|
||||||
|
* -For both library and library class, you can use a comma
|
||||||
|
* to add multiple entries.
|
||||||
|
*/
|
||||||
#define MODULE_NAME "--ENTER NAME HERE--"
|
#define MODULE_NAME "--ENTER NAME HERE--"
|
||||||
#define MODULE_VERSION "--ENTER VERSION HERE--"
|
#define MODULE_VERSION "--ENTER VERSION HERE--"
|
||||||
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
|
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
|
||||||
#define MODULE_URL "--ENTER URL HERE--"
|
#define MODULE_URL "--ENTER URL HERE--"
|
||||||
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
|
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
|
||||||
|
#define MODULE_LIBRARY "--ENTER LIBRARY HERE--"
|
||||||
|
#define MODULE_LIBCLASS ""
|
||||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||||
#define MODULE_RELOAD_ON_MAPCHANGE
|
#define MODULE_RELOAD_ON_MAPCHANGE
|
||||||
|
|
||||||
@ -34,18 +46,32 @@
|
|||||||
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
||||||
// #define NO_MSVC8_AUTO_COMPAT
|
// #define NO_MSVC8_AUTO_COMPAT
|
||||||
|
|
||||||
// - AMXX Init functions
|
/**
|
||||||
// Also consider using FN_META_*
|
* AMXX Init functions
|
||||||
// AMXX query
|
* Also consider using FN_META_*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** AMXX query */
|
||||||
//#define FN_AMXX_QUERY OnAmxxQuery
|
//#define FN_AMXX_QUERY OnAmxxQuery
|
||||||
// AMXX attach
|
|
||||||
// Do native functions init here (MF_AddNatives)
|
/** AMXX attach
|
||||||
|
* Do native functions init here (MF_AddNatives)
|
||||||
|
*/
|
||||||
//#define FN_AMXX_ATTACH OnAmxxAttach
|
//#define FN_AMXX_ATTACH OnAmxxAttach
|
||||||
// AMXX detach
|
|
||||||
|
/** AMXX Detach (unload) */
|
||||||
//#define FN_AMXX_DETACH OnAmxxDetach
|
//#define FN_AMXX_DETACH OnAmxxDetach
|
||||||
// All plugins loaded
|
|
||||||
// Do forward functions init here (MF_RegisterForward)
|
/** All plugins loaded
|
||||||
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
* Do forward functions init here (MF_RegisterForward)
|
||||||
|
*/
|
||||||
|
//#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||||
|
|
||||||
|
/** All plugins are about to be unloaded */
|
||||||
|
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
||||||
|
|
||||||
|
/** All plguins are now unloaded */
|
||||||
|
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||||
|
|
||||||
/**** METAMOD ****/
|
/**** METAMOD ****/
|
||||||
// If your module doesn't use metamod, you may close the file now :)
|
// If your module doesn't use metamod, you may close the file now :)
|
||||||
|
Loading…
Reference in New Issue
Block a user