Merge pull request #271 from Arkshine/fix/ns_remove_upgrade

Fix ns_remove_upgrade() native (bug 3394)
This commit is contained in:
Vincent Herbet 2015-08-10 15:28:44 +02:00
commit 20201290e3
5 changed files with 76 additions and 58 deletions

View File

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

View File

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

View File

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

View File

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

View File

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