From b9c9e9d100d2dd2163cfbe0f6d5d20607030bae3 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Sat, 3 Apr 2004 19:15:06 +0000 Subject: [PATCH] added some support for the new module interface --- amxmodx/CModule.cpp | 34 +++++++++- amxmodx/CModule.h | 1 + amxmodx/modules.cpp | 153 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 177 insertions(+), 11 deletions(-) diff --git a/amxmodx/CModule.cpp b/amxmodx/CModule.cpp index 789c7efb..6604e7f9 100755 --- a/amxmodx/CModule.cpp +++ b/amxmodx/CModule.cpp @@ -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 *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/); typedef int (FAR *DETACHMOD_NEW)(void); +typedef void (FAR *PLUGINSLOADED_NEW)(void); // Old // These functions are needed since Small Abstract Machine 2.5.0 @@ -176,9 +177,11 @@ bool CModule::attachModule() if (!AttachFunc_New) return false; - g_CurrentlyAttachedModule = this; + g_ModuleCallReason = ModuleCall_Attach; + g_CurrentlyCalledModule = this; int retVal = (*AttachFunc_New)(Module_ReqFnptr); - g_CurrentlyAttachedModule = NULL; + g_CurrentlyCalledModule = NULL; + g_ModuleCallReason = ModuleCall_NotCalled; switch (retVal) { @@ -233,7 +236,12 @@ bool CModule::queryModule() { m_Amxx = true; 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: 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"); if (detachFunc_New) + { + g_ModuleCallReason = ModuleCall_Detach; + g_CurrentlyCalledModule = this; (*detachFunc_New)(); + g_CurrentlyCalledModule = NULL; + g_ModuleCallReason = ModuleCall_NotCalled; + } } else { @@ -322,6 +336,20 @@ bool CModule::detachModule() 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 { switch(m_Status) diff --git a/amxmodx/CModule.h b/amxmodx/CModule.h index d237ebd8..9f9e4d96 100755 --- a/amxmodx/CModule.h +++ b/amxmodx/CModule.h @@ -99,6 +99,7 @@ public: inline bool isAmxx() const { return m_Amxx; } inline const char *getMissingFunc() const { return m_MissingFunc; } inline const char *getFilename() const { return m_Filename.str(); } + void CModule::CallPluginsLoaded(); CList m_Natives; }; diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 415c61fa..4245a957 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -38,9 +38,11 @@ CList g_modules; CList 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 // This is needed so we know which module called a function +ModuleCallReason g_ModuleCallReason; + #ifdef __cplusplus extern "C" { #endif @@ -614,26 +616,133 @@ int countModules(CountModulesMode mode) return 0; } +// Call all modules' AMXX_PluginsLoaded functions +void modules_callPluginsLoaded() +{ + for (CList::iterator iter = g_modules.begin(); iter; ++iter) + { + (*iter).CallPluginsLoaded(); + } +} + // new functions -// :TODO: Add functions int MNF_AddNatives(AMX_NATIVE_INFO* natives) { CList::iterator a = g_modules.begin(); - if (!g_CurrentlyAttachedModule) - return AMX_ERR_NATIVE; // not possible tho ;] + if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach) + return FALSE; // may only be called from attach // This is needed so that CList can free it ;] AMX_NATIVE_INFO** pPtr = new AMX_NATIVE_INFO*(natives); if (!pPtr) - return AMX_ERR_NONE; + return FALSE; - g_CurrentlyAttachedModule->m_Natives.put(pPtr); - return AMX_ERR_NONE; + g_CurrentlyCalledModule->m_Natives.put(pPtr); + 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::iterator iter = g_loadedscripts.begin(); + while (iter && id--) + ++iter; + + return (*iter).getAMX(); +} + +const char *MNF_GetAmxScriptName(int id) +{ + CList::iterator iter = g_loadedscripts.begin(); + while (iter && id--) + ++iter; + + return (*iter).getName(); +} + +int MNF_FindAmxScriptByName(const char *name) +{ + CList::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::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 const char *g_LastRequestedFunc = NULL; +#define REGISTER_FUNC(name, func) { name, (void*)func }, void *Module_ReqFnptr(const char *funcName) { // func table @@ -643,7 +752,35 @@ void *Module_ReqFnptr(const char *funcName) void *ptr; }; 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