added some support for the new module interface

This commit is contained in:
Pavol Marko 2004-04-03 19:15:06 +00:00
parent 79e214a6ea
commit b9c9e9d100
3 changed files with 177 additions and 11 deletions

View File

@ -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)

View File

@ -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<AMX_NATIVE_INFO*> m_Natives;
};

View File

@ -38,9 +38,11 @@
CList<CModule> g_modules;
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
// 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<CModule>::iterator iter = g_modules.begin(); iter; ++iter)
{
(*iter).CallPluginsLoaded();
}
}
// new functions
// :TODO: Add functions
int MNF_AddNatives(AMX_NATIVE_INFO* natives)
{
CList<CModule>::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<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
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