added some support for the new module interface
This commit is contained in:
parent
79e214a6ea
commit
b9c9e9d100
|
@ -47,6 +47,7 @@ typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||||
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);
|
||||||
|
|
||||||
// Old
|
// Old
|
||||||
// These functions are needed since Small Abstract Machine 2.5.0
|
// These functions are needed since Small Abstract Machine 2.5.0
|
||||||
|
@ -176,9 +177,11 @@ bool CModule::attachModule()
|
||||||
|
|
||||||
if (!AttachFunc_New)
|
if (!AttachFunc_New)
|
||||||
return false;
|
return false;
|
||||||
g_CurrentlyAttachedModule = this;
|
g_ModuleCallReason = ModuleCall_Attach;
|
||||||
|
g_CurrentlyCalledModule = this;
|
||||||
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
||||||
g_CurrentlyAttachedModule = NULL;
|
g_CurrentlyCalledModule = NULL;
|
||||||
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
|
|
||||||
switch (retVal)
|
switch (retVal)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +236,12 @@ bool CModule::queryModule()
|
||||||
{
|
{
|
||||||
m_Amxx = true;
|
m_Amxx = true;
|
||||||
int ifVers = AMXX_INTERFACE_VERSION;
|
int ifVers = AMXX_INTERFACE_VERSION;
|
||||||
switch ((*queryFunc_New)(&ifVers, &m_InfoNew))
|
g_ModuleCallReason = ModuleCall_Query;
|
||||||
|
g_CurrentlyCalledModule = this;
|
||||||
|
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||||
|
g_CurrentlyCalledModule = NULL;
|
||||||
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
|
switch (retVal)
|
||||||
{
|
{
|
||||||
case AMXX_PARAM:
|
case AMXX_PARAM:
|
||||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.str(), getVersion());
|
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.str(), getVersion());
|
||||||
|
@ -309,7 +317,13 @@ bool CModule::detachModule()
|
||||||
{
|
{
|
||||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||||
if (detachFunc_New)
|
if (detachFunc_New)
|
||||||
|
{
|
||||||
|
g_ModuleCallReason = ModuleCall_Detach;
|
||||||
|
g_CurrentlyCalledModule = this;
|
||||||
(*detachFunc_New)();
|
(*detachFunc_New)();
|
||||||
|
g_CurrentlyCalledModule = NULL;
|
||||||
|
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -322,6 +336,20 @@ bool CModule::detachModule()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CModule::CallPluginsLoaded()
|
||||||
|
{
|
||||||
|
if (m_Status != MODULE_LOADED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_Handle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
|
||||||
|
if (!func)
|
||||||
|
return;
|
||||||
|
func();
|
||||||
|
}
|
||||||
|
|
||||||
const char* CModule::getStatus() const
|
const char* CModule::getStatus() const
|
||||||
{
|
{
|
||||||
switch(m_Status)
|
switch(m_Status)
|
||||||
|
|
|
@ -99,6 +99,7 @@ public:
|
||||||
inline bool isAmxx() const { return m_Amxx; }
|
inline bool isAmxx() const { return m_Amxx; }
|
||||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||||
inline const char *getFilename() const { return m_Filename.str(); }
|
inline const char *getFilename() const { return m_Filename.str(); }
|
||||||
|
void CModule::CallPluginsLoaded();
|
||||||
|
|
||||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,9 +38,11 @@
|
||||||
CList<CModule> g_modules;
|
CList<CModule> g_modules;
|
||||||
CList<CScript,AMX*> g_loadedscripts;
|
CList<CScript,AMX*> g_loadedscripts;
|
||||||
|
|
||||||
CModule *g_CurrentlyAttachedModule = NULL; // The module we are attaching at the moment; NULL otherwise
|
CModule *g_CurrentlyCalledModule = NULL; // The module we are in at the moment; NULL otherwise
|
||||||
// also NULL for non-amxx modules
|
// also NULL for non-amxx modules
|
||||||
// This is needed so we know which module called a function
|
// This is needed so we know which module called a function
|
||||||
|
ModuleCallReason g_ModuleCallReason;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -614,26 +616,133 @@ int countModules(CountModulesMode mode)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call all modules' AMXX_PluginsLoaded functions
|
||||||
|
void modules_callPluginsLoaded()
|
||||||
|
{
|
||||||
|
for (CList<CModule>::iterator iter = g_modules.begin(); iter; ++iter)
|
||||||
|
{
|
||||||
|
(*iter).CallPluginsLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// new functions
|
// new functions
|
||||||
// :TODO: Add functions
|
|
||||||
|
|
||||||
int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
int MNF_AddNatives(AMX_NATIVE_INFO* natives)
|
||||||
{
|
{
|
||||||
CList<CModule>::iterator a = g_modules.begin();
|
CList<CModule>::iterator a = g_modules.begin();
|
||||||
|
|
||||||
if (!g_CurrentlyAttachedModule)
|
if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
|
||||||
return AMX_ERR_NATIVE; // not possible tho ;]
|
return FALSE; // may only be called from attach
|
||||||
|
|
||||||
// This is needed so that CList can free it ;]
|
// This is needed so that CList can free it ;]
|
||||||
AMX_NATIVE_INFO** pPtr = new AMX_NATIVE_INFO*(natives);
|
AMX_NATIVE_INFO** pPtr = new AMX_NATIVE_INFO*(natives);
|
||||||
if (!pPtr)
|
if (!pPtr)
|
||||||
return AMX_ERR_NONE;
|
return FALSE;
|
||||||
|
|
||||||
g_CurrentlyAttachedModule->m_Natives.put(pPtr);
|
g_CurrentlyCalledModule->m_Natives.put(pPtr);
|
||||||
return AMX_ERR_NONE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *MNF_GetModname(void)
|
||||||
|
{
|
||||||
|
// :TODO: Do we have to do this??
|
||||||
|
static char buffer[64];
|
||||||
|
strcpy(buffer, g_mod_name.str());
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
AMX *MNF_GetAmxScript(int id)
|
||||||
|
{
|
||||||
|
CList<CScript,AMX*>::iterator iter = g_loadedscripts.begin();
|
||||||
|
while (iter && id--)
|
||||||
|
++iter;
|
||||||
|
|
||||||
|
return (*iter).getAMX();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *MNF_GetAmxScriptName(int id)
|
||||||
|
{
|
||||||
|
CList<CScript,AMX*>::iterator iter = g_loadedscripts.begin();
|
||||||
|
while (iter && id--)
|
||||||
|
++iter;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MNF_CopyAmxMemory(cell * dest, const cell * src, int len)
|
||||||
|
{
|
||||||
|
memcpy((void*)dest, (const void *)src, (size_t)len*sizeof(cell));
|
||||||
|
}
|
||||||
|
|
||||||
// Fnptr Request function for the new interface
|
// Fnptr Request function for the new interface
|
||||||
const char *g_LastRequestedFunc = NULL;
|
const char *g_LastRequestedFunc = NULL;
|
||||||
|
#define REGISTER_FUNC(name, func) { name, (void*)func },
|
||||||
void *Module_ReqFnptr(const char *funcName)
|
void *Module_ReqFnptr(const char *funcName)
|
||||||
{
|
{
|
||||||
// func table
|
// func table
|
||||||
|
@ -643,7 +752,35 @@ void *Module_ReqFnptr(const char *funcName)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
};
|
};
|
||||||
static Func_s functions[] = {
|
static Func_s functions[] = {
|
||||||
{ "AddNatives", MNF_AddNatives },
|
// Misc
|
||||||
|
REGISTER_FUNC("BuildPathname", build_pathname)
|
||||||
|
REGISTER_FUNC("PrintSrvConsole", print_srvconsole)
|
||||||
|
REGISTER_FUNC("GetModname", MNF_GetModname)
|
||||||
|
REGISTER_FUNC("Log", AMXXLOG_Log)
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// Natives / Forwards
|
||||||
|
REGISTER_FUNC("AddNatives", MNF_AddNatives)
|
||||||
|
REGISTER_FUNC("RaiseAmxError", amx_RaiseError)
|
||||||
|
REGISTER_FUNC("RegisterForward", registerForward)
|
||||||
|
REGISTER_FUNC("ExecuteForward", executeForwards)
|
||||||
|
REGISTER_FUNC("PrepareCellArray", prepareCellArray)
|
||||||
|
REGISTER_FUNC("PrepareCharArray", prepareCharArray)
|
||||||
};
|
};
|
||||||
|
|
||||||
// code
|
// code
|
||||||
|
|
Loading…
Reference in New Issue
Block a user