added ability to override natives (someone shoot me)
This commit is contained in:
		| @@ -82,6 +82,12 @@ void CModule::clear(bool clearFilename) | ||||
| 	m_InfoNew.reload = 0; | ||||
| 	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(); | ||||
| } | ||||
|  | ||||
| @@ -105,6 +111,53 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now) | ||||
| 	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() | ||||
| { | ||||
| 	// old & new | ||||
|   | ||||
| @@ -92,6 +92,7 @@ public: | ||||
| 	bool attachModule(); | ||||
| 	bool queryModule(); | ||||
| 	bool detachModule(); | ||||
| 	void rewriteNativeLists(AMX_NATIVE_INFO *list); | ||||
|  | ||||
| #ifndef FAKEMETA | ||||
| 	bool attachMetamod(const char *mmfile, PLUG_LOADTIME now); | ||||
| @@ -115,7 +116,8 @@ public: | ||||
| 	void CallPluginsUnloaded(); | ||||
| 	void CallPluginsUnloading(); | ||||
|  | ||||
| 	CList<AMX_NATIVE_INFO*> m_Natives; | ||||
| 	CVector<AMX_NATIVE_INFO*> m_Natives; | ||||
| 	CVector<size_t> m_DestroyableIndexes; | ||||
| }; | ||||
|  | ||||
| #endif //CMODULE_H | ||||
|   | ||||
| @@ -502,10 +502,14 @@ int CheckModules(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<AMX_NATIVE_INFO*>::iterator cc = (*a).m_Natives.begin(); cc; ++cc) | ||||
| 			amx_Register(amx, *cc, -1); | ||||
| 		cm = &(*a); | ||||
| 		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); | ||||
| @@ -1113,12 +1117,7 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives) | ||||
| 	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 FALSE; | ||||
|  | ||||
| 	g_CurrentlyCalledModule->m_Natives.put(pPtr); | ||||
| 	g_CurrentlyCalledModule->m_Natives.push_back(natives); | ||||
| 	 | ||||
| 	return TRUE; | ||||
| } | ||||
| @@ -1284,6 +1283,17 @@ const char * MNF_GetPlayerName(int id) | ||||
| 	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) | ||||
| { | ||||
| 	if (id < 1 || id > gpGlobals->maxClients) | ||||
| @@ -1775,6 +1785,7 @@ void Module_CacheFunctions() | ||||
| 	REGISTER_FUNC("FindLibrary", MNF_FindLibrary); | ||||
| 	REGISTER_FUNC("AddLibraries", MFN_AddLibraries); | ||||
| 	REGISTER_FUNC("RemoveLibraries", MNF_RemoveLibraries); | ||||
| 	REGISTER_FUNC("OverrideNatives", MNF_OverrideNatives); | ||||
|  | ||||
| #ifdef MEMORY_TEST | ||||
| 	REGISTER_FUNC("Allocator", m_allocator) | ||||
|   | ||||
| @@ -2511,6 +2511,7 @@ PFN_UNREG_AUTH_FUNC			g_fn_UnregAuthFunc; | ||||
| PFN_FINDLIBRARY				g_fn_FindLibrary; | ||||
| PFN_ADDLIBRARIES			g_fn_AddLibraries; | ||||
| PFN_REMOVELIBRARIES			g_fn_RemoveLibraries; | ||||
| PFN_OVERRIDENATIVES			g_fn_OverrideNatives; | ||||
|  | ||||
| // *** Exports *** | ||||
| 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("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES); | ||||
| 	REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES); | ||||
| 	REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES); | ||||
|  | ||||
| #ifdef MEMORY_TEST | ||||
| 	// Memory | ||||
| @@ -2769,6 +2771,7 @@ void ValidateMacros_DontCallThis_Smiley() | ||||
| 	MF_FindLibrary(NULL, LibType_Class); | ||||
| 	MF_AddLibraries(NULL, LibType_Class, NULL); | ||||
| 	MF_RemoveLibraries(NULL); | ||||
| 	MF_OverrideNatives(NULL); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -2179,6 +2179,7 @@ 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*/); | ||||
| typedef void			(*PFN_OVERRIDENATIVES)			(AMX_NATIVE_INFO * /*natives*/); | ||||
|  | ||||
| extern PFN_ADD_NATIVES				g_fn_AddNatives; | ||||
| 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_ADDLIBRARIES				g_fn_AddLibraries; | ||||
| extern PFN_REMOVELIBRARIES			g_fn_RemoveLibraries; | ||||
| extern PFN_OVERRIDENATIVES			g_fn_OverrideNatives; | ||||
|  | ||||
| #ifdef MAY_NEVER_BE_DEFINED | ||||
| // Function prototypes for intellisense and similar systems | ||||
| @@ -2316,6 +2318,7 @@ 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) { } | ||||
| void			MF_OverrideNatives			(AMX_NATIVE_INFO *natives) { } | ||||
| #endif	// MAY_NEVER_BE_DEFINED | ||||
|  | ||||
| #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_RegAuthFunc g_fn_RegAuthFunc | ||||
| #define MF_UnregAuthFunc g_fn_UnregAuthFunc | ||||
| #define MF_FindLibrary g_fn_FindLibrary; | ||||
| #define MF_AddLibraries g_fn_AddLibraries; | ||||
| #define MF_RemoveLibraries g_fn_RemoveLibraries; | ||||
| #define MF_FindLibrary g_fn_FindLibrary | ||||
| #define MF_AddLibraries g_fn_AddLibraries | ||||
| #define MF_RemoveLibraries g_fn_RemoveLibraries | ||||
| #define MF_OverrideNatives g_fn_OverrideNatives | ||||
|  | ||||
| #ifdef MEMORY_TEST | ||||
| /*** Memory ***/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user