added ability to override natives (someone shoot me)

This commit is contained in:
David Anderson 2006-05-10 11:23:08 +00:00
parent de1f1eef8d
commit b12025093b
5 changed files with 85 additions and 12 deletions

View File

@ -82,6 +82,12 @@ void CModule::clear(bool clearFilename)
m_InfoNew.reload = 0; m_InfoNew.reload = 0;
m_MissingFunc = NULL; m_MissingFunc = NULL;
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
{
delete [] m_Natives[m_DestroyableIndexes[i]];
}
m_DestroyableIndexes.clear();
m_Natives.clear(); m_Natives.clear();
} }
@ -105,6 +111,53 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
return true; return true;
} }
//this ugly function is ultimately something like O(n^4).
//sigh. it shouldn't be needed.
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
{
AMX_NATIVE_INFO *curlist;
for (size_t i=0; i<m_Natives.size(); i++)
{
curlist = m_Natives[i];
bool changed = false;
bool found = false;
CVector<size_t> newlist;
for (size_t j=0; curlist[j].func != NULL; j++)
{
found = false;
for (size_t k=0; list[k].func != NULL; k++)
{
if (strcmp(curlist[j].name, list[k].name) == 0)
{
found = true;
break;
}
}
if (found)
{
changed = true;
//don't break, we have to search it all
} else {
newlist.push_back(j);
}
}
if (changed)
{
//now build the new list
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
for (size_t j=0; j<newlist.size(); j++)
{
rlist[j].func = curlist[newlist[j]].func;
rlist[j].name = curlist[newlist[j]].name;
}
rlist[newlist.size()].func = NULL;
rlist[newlist.size()].name = NULL;
m_Natives[i] = rlist;
m_DestroyableIndexes.push_back(i);
}
}
}
bool CModule::attachModule() bool CModule::attachModule()
{ {
// old & new // old & new

View File

@ -92,6 +92,7 @@ public:
bool attachModule(); bool attachModule();
bool queryModule(); bool queryModule();
bool detachModule(); bool detachModule();
void rewriteNativeLists(AMX_NATIVE_INFO *list);
#ifndef FAKEMETA #ifndef FAKEMETA
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now); bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
@ -115,7 +116,8 @@ public:
void CallPluginsUnloaded(); void CallPluginsUnloaded();
void CallPluginsUnloading(); void CallPluginsUnloading();
CList<AMX_NATIVE_INFO*> m_Natives; CVector<AMX_NATIVE_INFO*> m_Natives;
CVector<size_t> m_DestroyableIndexes;
}; };
#endif //CMODULE_H #endif //CMODULE_H

View File

@ -502,10 +502,14 @@ int CheckModules(AMX *amx, char error[128])
int set_amxnatives(AMX* amx, char error[128]) int set_amxnatives(AMX* amx, char error[128])
{ {
CModule *cm;
for (CList<CModule, const char *>::iterator a = g_modules.begin(); a ; ++a) for (CList<CModule, const char *>::iterator a = g_modules.begin(); a ; ++a)
{ {
for (CList<AMX_NATIVE_INFO*>::iterator cc = (*a).m_Natives.begin(); cc; ++cc) cm = &(*a);
amx_Register(amx, *cc, -1); for (size_t i=0; i<cm->m_Natives.size(); i++)
{
amx_Register(amx, cm->m_Natives[i], -1);
}
} }
amx_Register(amx, string_Natives, -1); amx_Register(amx, string_Natives, -1);
@ -1113,12 +1117,7 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach) if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
return FALSE; // may only be called from attach return FALSE; // may only be called from attach
// This is needed so that CList can free it ;] g_CurrentlyCalledModule->m_Natives.push_back(natives);
AMX_NATIVE_INFO** pPtr = new AMX_NATIVE_INFO*(natives);
if (!pPtr)
return FALSE;
g_CurrentlyCalledModule->m_Natives.put(pPtr);
return TRUE; return TRUE;
} }
@ -1284,6 +1283,17 @@ const char * MNF_GetPlayerName(int id)
return GET_PLAYER_POINTER_I(id)->name.c_str(); return GET_PLAYER_POINTER_I(id)->name.c_str();
} }
void MNF_OverrideNatives(AMX_NATIVE_INFO *natives)
{
//HACKHACK - we should never have had to do this
//find a better solution for SourceMod!!!
for (CList<CModule, const char *>::iterator a = g_modules.begin(); a ; ++a)
{
CModule &cm = (*a);
cm.rewriteNativeLists(natives);
}
}
const char * MNF_GetPlayerIP(int id) const char * MNF_GetPlayerIP(int id)
{ {
if (id < 1 || id > gpGlobals->maxClients) if (id < 1 || id > gpGlobals->maxClients)
@ -1775,6 +1785,7 @@ void Module_CacheFunctions()
REGISTER_FUNC("FindLibrary", MNF_FindLibrary); REGISTER_FUNC("FindLibrary", MNF_FindLibrary);
REGISTER_FUNC("AddLibraries", MFN_AddLibraries); REGISTER_FUNC("AddLibraries", MFN_AddLibraries);
REGISTER_FUNC("RemoveLibraries", MNF_RemoveLibraries); REGISTER_FUNC("RemoveLibraries", MNF_RemoveLibraries);
REGISTER_FUNC("OverrideNatives", MNF_OverrideNatives);
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
REGISTER_FUNC("Allocator", m_allocator) REGISTER_FUNC("Allocator", m_allocator)

View File

@ -2511,6 +2511,7 @@ PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
PFN_FINDLIBRARY g_fn_FindLibrary; PFN_FINDLIBRARY g_fn_FindLibrary;
PFN_ADDLIBRARIES g_fn_AddLibraries; PFN_ADDLIBRARIES g_fn_AddLibraries;
PFN_REMOVELIBRARIES g_fn_RemoveLibraries; PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
// *** 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)
@ -2628,6 +2629,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY); REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES); REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES); REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
// Memory // Memory
@ -2769,6 +2771,7 @@ void ValidateMacros_DontCallThis_Smiley()
MF_FindLibrary(NULL, LibType_Class); MF_FindLibrary(NULL, LibType_Class);
MF_AddLibraries(NULL, LibType_Class, NULL); MF_AddLibraries(NULL, LibType_Class, NULL);
MF_RemoveLibraries(NULL); MF_RemoveLibraries(NULL);
MF_OverrideNatives(NULL);
} }
#endif #endif

View File

@ -2179,6 +2179,7 @@ typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/); 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_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/); typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/);
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;
@ -2249,6 +2250,7 @@ extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
extern PFN_FINDLIBRARY g_fn_FindLibrary; extern PFN_FINDLIBRARY g_fn_FindLibrary;
extern PFN_ADDLIBRARIES g_fn_AddLibraries; extern PFN_ADDLIBRARIES g_fn_AddLibraries;
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries; extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
#ifdef MAY_NEVER_BE_DEFINED #ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems // Function prototypes for intellisense and similar systems
@ -2316,6 +2318,7 @@ void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
int MF_FindLibrary (const char *name, LibType type) { } int MF_FindLibrary (const char *name, LibType type) { }
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { } size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
size_t MF_RemoveLibraries (void *parent) { } size_t MF_RemoveLibraries (void *parent) { }
void MF_OverrideNatives (AMX_NATIVE_INFO *natives) { }
#endif // MAY_NEVER_BE_DEFINED #endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives #define MF_AddNatives g_fn_AddNatives
@ -2385,9 +2388,10 @@ 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_FindLibrary g_fn_FindLibrary
#define MF_AddLibraries g_fn_AddLibraries; #define MF_AddLibraries g_fn_AddLibraries
#define MF_RemoveLibraries g_fn_RemoveLibraries; #define MF_RemoveLibraries g_fn_RemoveLibraries
#define MF_OverrideNatives g_fn_OverrideNatives
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
/*** Memory ***/ /*** Memory ***/