mirror of
https://github.com/Jous99/F4MP.git
synced 2026-01-13 00:20:54 +01:00
215 lines
9.6 KiB
C++
215 lines
9.6 KiB
C++
#ifndef COMMON_UTILITIES_H
|
|
#define COMMON_UTILITIES_H
|
|
|
|
#include <Windows.h>
|
|
#include <iostream>
|
|
#include "Types.h"
|
|
#include "GamePtr.h"
|
|
|
|
namespace Utilities {
|
|
|
|
#pragma warning (push)
|
|
#pragma warning (disable : 4200)
|
|
struct RTTIType
|
|
{
|
|
void * typeInfo;
|
|
Types::UInt64 data;
|
|
char name[0];
|
|
};
|
|
|
|
struct RTTILocator
|
|
{
|
|
Types::UInt32 sig, offset, cdOffset;
|
|
Types::UInt32 typeDesc;
|
|
Types::UInt32 classDesc;
|
|
};
|
|
#pragma warning (pop)
|
|
|
|
const char * GetObjClassName(void * objBase);
|
|
void DumpClass(void * theClassPtr, Types::UInt64 nIntsToDump);
|
|
|
|
template <typename T>
|
|
uintptr_t GetFnAddr(T src)
|
|
{
|
|
union
|
|
{
|
|
uintptr_t u;
|
|
T t;
|
|
} data;
|
|
|
|
data.t = src;
|
|
|
|
return data.u;
|
|
}
|
|
|
|
class IAT {
|
|
public:
|
|
IAT(void * module,const char * DllName,const char * ImportName) : module(module), DllName(DllName), ImportName(ImportName) {
|
|
base = (Types::UInt8 *)module;
|
|
dosHeader = (IMAGE_DOS_HEADER *)base;
|
|
ntHeader = (IMAGE_NT_HEADERS *)(base + dosHeader->e_lfanew);
|
|
importTable = (IMAGE_IMPORT_DESCRIPTOR *)(base + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
|
};
|
|
|
|
void * Get();
|
|
private:
|
|
void * module;
|
|
const char * DllName;
|
|
const char * ImportName;
|
|
|
|
Types::UInt8 * base;
|
|
IMAGE_DOS_HEADER * dosHeader;
|
|
IMAGE_NT_HEADERS * ntHeader;
|
|
IMAGE_IMPORT_DESCRIPTOR * importTable;
|
|
};
|
|
|
|
//+++THANKS TO F4SE TEAM
|
|
#define MEMBER_FN_PREFIX(className) \
|
|
typedef className _MEMBER_FN_BASE_TYPE
|
|
|
|
#define DEFINE_MEMBER_FN_LONG(className, functionName, retnType, address, ...) \
|
|
typedef retnType (className::* _##functionName##_type)(__VA_ARGS__); \
|
|
\
|
|
inline _##functionName##_type * _##functionName##_GetPtr(void) \
|
|
{ \
|
|
static uintptr_t _address; \
|
|
_address = address + Memory::GamePtr_Manager::s_baseAddress; \
|
|
return (_##functionName##_type *)&_address; \
|
|
}
|
|
|
|
#define DEFINE_MEMBER_FN(functionName, retnType, address, ...) \
|
|
DEFINE_MEMBER_FN_LONG(_MEMBER_FN_BASE_TYPE, functionName, retnType, address, __VA_ARGS__)
|
|
|
|
#define DEFINE_STATIC_HEAP(staticAllocate, staticFree) \
|
|
static void * operator new(std::size_t size) \
|
|
{ \
|
|
return staticAllocate(size); \
|
|
} \
|
|
static void * operator new(std::size_t size, const std::nothrow_t &) \
|
|
{ \
|
|
return staticAllocate(size); \
|
|
} \
|
|
static void * operator new(std::size_t size, void * ptr) \
|
|
{ \
|
|
return ptr; \
|
|
} \
|
|
static void operator delete(void * ptr) \
|
|
{ \
|
|
staticFree(ptr); \
|
|
} \
|
|
static void operator delete(void * ptr, const std::nothrow_t &) \
|
|
{ \
|
|
staticFree(ptr); \
|
|
} \
|
|
static void operator delete(void *, void *) \
|
|
{ \
|
|
}
|
|
|
|
#define CALL_MEMBER_FN(obj, fn) \
|
|
((*(obj)).*(*((obj)->_##fn##_GetPtr())))
|
|
|
|
|
|
// Using the original implementation does very broken things in a Release build
|
|
// For classes like BSGFxShaderFXTarget and GameMenuBase
|
|
#define FORCE_INLINE __forceinline
|
|
#define DEFINE_MEMBER_FN_0(fnName, retnType, addr) \
|
|
FORCE_INLINE retnType fnName() { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_1(fnName, retnType, addr, ...) \
|
|
template<typename T1> \
|
|
FORCE_INLINE retnType fnName(T1 && t1) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_2(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_3(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_4(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_5(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_6(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5, T6 && t6) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5, t6); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_7(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5, T6 && t6, T7 && t7) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5, t6, t7); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_8(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5, T6 && t6, T7 && t7, T8 && t8) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5, t6, t7, t8); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_9(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5, T6 && t6, T7 && t7, T8 && t8, T9 && t9) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5, t6, t7, t8, t9); \
|
|
}
|
|
#define DEFINE_MEMBER_FN_10(fnName, retnType, addr, ...) \
|
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> \
|
|
FORCE_INLINE retnType fnName(T1 && t1, T2 && t2, T3 && t3, T4 && t4, T5 && t5, T6 && t6, T7 && t7, T8 && t8, T9 && t9, T10 && t10) { \
|
|
struct empty_struct {}; \
|
|
typedef retnType(empty_struct::*_##fnName##_type)(__VA_ARGS__); \
|
|
const static uintptr_t address = addr + Memory::GamePtr_Manager::s_baseAddress; \
|
|
_##fnName##_type fn = *(_##fnName##_type*)&address; \
|
|
return (reinterpret_cast<empty_struct*>(this)->*fn)(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \
|
|
}
|
|
}
|
|
|
|
#endif
|