Merge pull request #271 from Arkshine/fix/ns_remove_upgrade
Fix ns_remove_upgrade() native (bug 3394)
This commit is contained in:
		| @@ -30,7 +30,8 @@ extern BOOL iscombat; | |||||||
| TitleManager TitleMan; | TitleManager TitleMan; | ||||||
| ParticleManager ParticleMan; | ParticleManager ParticleMan; | ||||||
|  |  | ||||||
| void MFuncs_Initialize(void); | void MFuncs_Initialize(char *base); | ||||||
|  | void MPlayerFuncs_Initialize(char *base); | ||||||
|  |  | ||||||
| // Native register calls here | // Native register calls here | ||||||
| void AddNatives_MemberFunc(); | void AddNatives_MemberFunc(); | ||||||
| @@ -86,6 +87,20 @@ void OnAmxxAttach() | |||||||
| 	AddNatives_Structure(); | 	AddNatives_Structure(); | ||||||
| 	AddNatives_General(); | 	AddNatives_General(); | ||||||
|  |  | ||||||
| 	MFuncs_Initialize(); | 	char *FuncBase; | ||||||
|  | 	char FileName[256]; | ||||||
|  | 	DLHANDLE DLLBase; | ||||||
|  | #ifdef __linux__ | ||||||
|  | 	UTIL_Format(FileName, sizeof(FileName), "%s/dlls/ns_i386.so", MF_GetModname()); | ||||||
|  | #else | ||||||
|  | 	UTIL_Format(FileName, sizeof(FileName), "%s\\dlls\\ns.dll", MF_GetModname()); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	DLLBase = DLOPEN(FileName); | ||||||
|  | 	FuncBase = (char *)DLSYM(DLLBase, MAKE_OFFSET(BASE)); | ||||||
|  | 	DLCLOSE(DLLBase); | ||||||
|  |  | ||||||
|  | 	MFuncs_Initialize(FuncBase); | ||||||
|  | 	MPlayerFuncs_Initialize(FuncBase); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -42,63 +42,10 @@ static void (GenericClass::*MFP_WeldFinished)(float); | |||||||
| // AvHGameRules *GetGameRules(void) | // AvHGameRules *GetGameRules(void) | ||||||
| static void *(*FP_GetGameRules)(); | static void *(*FP_GetGameRules)(); | ||||||
|  |  | ||||||
|  | void MFuncs_Initialize(char *base) | ||||||
| char *FuncBase; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * sizeof(void (detail::GenericClass::*fptr)()) |  | ||||||
|  * is 8 in GCC.  Add an empty void * pointer at |  | ||||||
|  * the end to compensate. |  | ||||||
|  * Layout in GCC: |  | ||||||
|  * union {  |  | ||||||
|  *   void *address;      // When this is an address it will always be positive |  | ||||||
|  *   int   vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1 |  | ||||||
|  * }; |  | ||||||
|  * int delta; |  | ||||||
|  * - |  | ||||||
|  * Delta is the adjustment to the this pointer |  | ||||||
|  * For my implementations I will only need it to 0 |  | ||||||
|  */ |  | ||||||
| #ifdef __GNUC__ |  | ||||||
| template <typename OutType> |  | ||||||
| inline void set_mfp(OutType &out, void *in) |  | ||||||
| { | { | ||||||
| 	union |  | ||||||
| 	{ |  | ||||||
| 		void    *in[2]; |  | ||||||
| 		OutType out; |  | ||||||
| 	} mfpu; |  | ||||||
|  |  | ||||||
| 	mfpu.in[0]=in; |  | ||||||
| 	mfpu.in[1]=NULL; |  | ||||||
| 	out=mfpu.out; |  | ||||||
| }; |  | ||||||
| #else |  | ||||||
| template <typename OutType> |  | ||||||
| inline void set_mfp(OutType &out, void *in) |  | ||||||
| { |  | ||||||
| 	out=horrible_cast<OutType>(in); |  | ||||||
| }; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| void MFuncs_Initialize(void) |  | ||||||
| { |  | ||||||
| 	char FileName[256]; |  | ||||||
| 	DLHANDLE DLLBase; |  | ||||||
| #ifdef __linux__ |  | ||||||
| 	UTIL_Format(FileName,sizeof(FileName)-1,"%s/dlls/ns_i386.so",MF_GetModname()); |  | ||||||
| #else |  | ||||||
| 	UTIL_Format(FileName, sizeof(FileName)-1, "%s\\dlls\\ns.dll", MF_GetModname()); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	DLLBase=DLOPEN(FileName); |  | ||||||
| 	FuncBase=(char *)DLSYM(DLLBase, MAKE_OFFSET(BASE)); |  | ||||||
| 	DLCLOSE(DLLBase); |  | ||||||
|  |  | ||||||
| #define MFP(Offs) (((void *)(((char *)FuncBase)+MAKE_OFFSET(Offs)))) |  | ||||||
|  |  | ||||||
| 	set_mfp(MFP_Recycle,MFP(MEMBER_RECYCLE)); | 	set_mfp(MFP_Recycle,MFP(MEMBER_RECYCLE)); | ||||||
| 	 |  | ||||||
| 	set_mfp(MFP_WeldFinished,MFP(MEMBER_TRIGGER_WELDABLE)); | 	set_mfp(MFP_WeldFinished,MFP(MEMBER_TRIGGER_WELDABLE)); | ||||||
|  |  | ||||||
| 	// This is not a member function pointer, but use MFP since it | 	// This is not a member function pointer, but use MFP since it | ||||||
|   | |||||||
| @@ -20,6 +20,16 @@ | |||||||
|  |  | ||||||
| #include "GameManager.h" | #include "GameManager.h" | ||||||
| #include "CPlayer.h" | #include "CPlayer.h" | ||||||
|  | #include "FastDelegate.h" | ||||||
|  |  | ||||||
|  | using namespace fastdelegate::detail; | ||||||
|  |  | ||||||
|  | static bool (GenericClass::*MFP_SetResearchDone)(int inMessageID, bool inState); | ||||||
|  |  | ||||||
|  | void MPlayerFuncs_Initialize(char *base) | ||||||
|  | { | ||||||
|  | 	set_mfp(MFP_SetResearchDone, MFP(MEMBER_SET_RESEARCH_DONE)); | ||||||
|  | }; | ||||||
|  |  | ||||||
| // Float:ns_get_res(Player) | // Float:ns_get_res(Player) | ||||||
| static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params) | static cell AMX_NATIVE_CALL ns_get_res(AMX *amx, cell *params) | ||||||
| @@ -378,6 +388,9 @@ static cell AMX_NATIVE_CALL ns_remove_upgrade(AMX *amx, cell *params) | |||||||
|  |  | ||||||
| 	if (bfound) | 	if (bfound) | ||||||
| 	{ | 	{ | ||||||
|  | 		void *pTechTree = reinterpret_cast<char*>(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(COMBAT_TECHTREE); | ||||||
|  | 		(reinterpret_cast<GenericClass *>(pTechTree)->*(MFP_SetResearchDone))(params[2], false); | ||||||
|  |  | ||||||
| 		if (afound) | 		if (afound) | ||||||
| 		{ | 		{ | ||||||
| 			return 2; | 			return 2; | ||||||
|   | |||||||
| @@ -122,6 +122,10 @@ | |||||||
| #define OFFSET_WIN_UPGRADES_ACTIVE	0x198C | #define OFFSET_WIN_UPGRADES_ACTIVE	0x198C | ||||||
| #define OFFSET_LIN_UPGRADES_ACTIVE	0x19A0 | #define OFFSET_LIN_UPGRADES_ACTIVE	0x19A0 | ||||||
|  |  | ||||||
|  | #define OFFSET_WIN_COMBAT_TECHTREE	0x1998 | ||||||
|  | #define OFFSET_LIN_COMBAT_TECHTREE	0x19AC | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // TODO: Symbols / signatures instead | // TODO: Symbols / signatures instead | ||||||
| // Not actually offsets, but easier to use MAKE_OFFSET stuff for this :o | // Not actually offsets, but easier to use MAKE_OFFSET stuff for this :o | ||||||
| @@ -147,7 +151,9 @@ | |||||||
| #define OFFSET_WIN_MEMBER_TRIGGER_WELDABLE		MAKE_MEMBER_OFFSET(0x000A0E20) | #define OFFSET_WIN_MEMBER_TRIGGER_WELDABLE		MAKE_MEMBER_OFFSET(0x000A0E20) | ||||||
| #define OFFSET_LIN_MEMBER_TRIGGER_WELDABLE		MAKE_MEMBER_OFFSET(0x00232840) | #define OFFSET_LIN_MEMBER_TRIGGER_WELDABLE		MAKE_MEMBER_OFFSET(0x00232840) | ||||||
|  |  | ||||||
|  | // Research:  bool AvHTechTree::SetResearchDone(AvHMessageID inMessageID, bool inState) | ||||||
|  | #define OFFSET_WIN_MEMBER_SET_RESEARCH_DONE		MAKE_MEMBER_OFFSET(0x0009EC40) | ||||||
|  | #define OFFSET_LIN_MEMBER_SET_RESEARCH_DONE		MAKE_MEMBER_OFFSET(0x0022E740) | ||||||
|  |  | ||||||
| // Game Rules: AvHGameRules *GetGameRules(void) | // Game Rules: AvHGameRules *GetGameRules(void) | ||||||
| #define OFFSET_WIN_GETGAMERULES					MAKE_MEMBER_OFFSET(0x00068000) | #define OFFSET_WIN_GETGAMERULES					MAKE_MEMBER_OFFSET(0x00068000) | ||||||
|   | |||||||
| @@ -233,6 +233,43 @@ inline unsigned char set_private_b(edict_t *pEntity, int offset, unsigned char v | |||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  | * sizeof(void (detail::GenericClass::*fptr)()) | ||||||
|  | * is 8 in GCC.  Add an empty void * pointer at | ||||||
|  | * the end to compensate. | ||||||
|  | * Layout in GCC: | ||||||
|  | * union { | ||||||
|  | *   void *address;      // When this is an address it will always be positive | ||||||
|  | *   int   vtable_index; // When it is a vtable index it will always be odd = (vindex*2)+1 | ||||||
|  | * }; | ||||||
|  | * int delta; | ||||||
|  | * - | ||||||
|  | * Delta is the adjustment to the this pointer | ||||||
|  | * For my implementations I will only need it to 0 | ||||||
|  | */ | ||||||
|  | #ifdef __GNUC__ | ||||||
|  | template <typename OutType> | ||||||
|  | inline void set_mfp(OutType &out, void *in) | ||||||
|  | { | ||||||
|  | 	union | ||||||
|  | 	{ | ||||||
|  | 		void    *in[2]; | ||||||
|  | 		OutType out; | ||||||
|  | 	} mfpu; | ||||||
|  |  | ||||||
|  | 	mfpu.in[0] = in; | ||||||
|  | 	mfpu.in[1] = NULL; | ||||||
|  | 	out = mfpu.out; | ||||||
|  | }; | ||||||
|  | #else | ||||||
|  | template <typename OutType> | ||||||
|  | inline void set_mfp(OutType &out, void *in) | ||||||
|  | { | ||||||
|  | 	out = horrible_cast<OutType>(in); | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define MFP(Offs) (((void *)(((char *)base)+MAKE_OFFSET(Offs)))) | ||||||
|  |  | ||||||
| #endif // UTILFUNCTIONS_H | #endif // UTILFUNCTIONS_H | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user