mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
Factorized MemoryMgr to be game agnostic
This commit is contained in:
parent
b11644ae5a
commit
33c1ab4ace
10 changed files with 453 additions and 444 deletions
432
SilentPatch/MemoryMgr.GTA.h
Normal file
432
SilentPatch/MemoryMgr.GTA.h
Normal file
|
@ -0,0 +1,432 @@
|
|||
#pragma once
|
||||
|
||||
#include "MemoryMgr.h"
|
||||
|
||||
#include <variant>
|
||||
#include "Patterns.h"
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
struct PatternAndOffset
|
||||
{
|
||||
PatternAndOffset( std::string_view pattern, ptrdiff_t offset = 0 )
|
||||
: pattern(std::move(pattern)), offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
std::string_view pattern;
|
||||
ptrdiff_t offset;
|
||||
};
|
||||
|
||||
using AddrVariant = std::variant<uintptr_t, PatternAndOffset>;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
inline signed char* GetVer()
|
||||
{
|
||||
static signed char bVer = -1;
|
||||
return &bVer;
|
||||
}
|
||||
|
||||
inline bool* GetEuropean()
|
||||
{
|
||||
static bool bEuropean;
|
||||
return &bEuropean;
|
||||
}
|
||||
|
||||
inline uintptr_t GetDummy()
|
||||
{
|
||||
static uintptr_t dwDummy;
|
||||
return reinterpret_cast<uintptr_t>(&dwDummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
inline uintptr_t HandlePattern( const PatternAndOffset& pattern )
|
||||
{
|
||||
void* addr = hook::get_pattern( pattern.pattern, pattern.offset );
|
||||
return reinterpret_cast<uintptr_t>(addr);
|
||||
}
|
||||
|
||||
#if defined _GTA_III
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if (*(uint32_t*)0x5C1E75 == 0xB85548EC) *bVer = 0;
|
||||
else if (*(uint32_t*)0x5C2135 == 0xB85548EC) *bVer = 1;
|
||||
else if (*(uint32_t*)0x5C6FD5 == 0xB85548EC) *bVer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined _GTA_VC
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if (*(uint32_t*)0x667BF5 == 0xB85548EC) *bVer = 0;
|
||||
else if (*(uint32_t*)0x667C45 == 0xB85548EC) *bVer = 1;
|
||||
else if (*(uint32_t*)0x666BA5 == 0xB85548EC) *bVer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined _GTA_SA
|
||||
|
||||
inline bool TryMatch_10()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x82457C) == 0x94BF )
|
||||
{
|
||||
// 1.0 US
|
||||
*GetVer() = 0;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
if ( *(uint32_t*)DynBaseAddress(0x8245BC) == 0x94BF )
|
||||
{
|
||||
// 1.0 EU
|
||||
*GetVer() = 0;
|
||||
*GetEuropean() = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_11()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x8252FC) == 0x94BF )
|
||||
{
|
||||
// 1.01 US
|
||||
*GetVer() = 1;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
if ( *(uint32_t*)DynBaseAddress(0x82533C) == 0x94BF )
|
||||
{
|
||||
// 1.01 EU
|
||||
*GetVer() = 1;
|
||||
*GetEuropean() = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_30()
|
||||
{
|
||||
if (*(uint32_t*)DynBaseAddress(0x85EC4A) == 0x94BF )
|
||||
{
|
||||
// 3.0
|
||||
*GetVer() = 2;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r1()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858D21) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r1
|
||||
*GetVer() = 3;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r2()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858D51) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r2
|
||||
*GetVer() = 4;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r2_lv()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858C61) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r2 lv
|
||||
*GetVer() = 5;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
if ( *GetVer() == -1 )
|
||||
{
|
||||
if ( TryMatch_10() ) return;
|
||||
if ( TryMatch_11() ) return;
|
||||
if ( TryMatch_30() ) return;
|
||||
if ( TryMatch_newsteam_r1() ) return;
|
||||
if ( TryMatch_newsteam_r2() ) return;
|
||||
if ( TryMatch_newsteam_r2_lv() ) return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void InitializeRegion_10()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if ( !TryMatch_10() )
|
||||
{
|
||||
#ifdef assert
|
||||
assert(!"AddressByRegion_10 on non-1.0 EXE!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void InitializeRegion_11()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if ( !TryMatch_11() )
|
||||
{
|
||||
#ifdef assert
|
||||
assert(!"AddressByRegion_11 on non-1.01 EXE!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uintptr_t AdjustAddress_10(uintptr_t address10)
|
||||
{
|
||||
if ( *GetEuropean() )
|
||||
{
|
||||
if ( address10 >= 0x746720 && address10 < 0x857000 )
|
||||
{
|
||||
if ( address10 >= 0x7BA940 )
|
||||
address10 += 0x40;
|
||||
else
|
||||
address10 += 0x50;
|
||||
}
|
||||
}
|
||||
return address10;
|
||||
}
|
||||
|
||||
inline uintptr_t AdjustAddress_11(uintptr_t address11)
|
||||
{
|
||||
if ( !(*GetEuropean()) && address11 > 0x746FA0 )
|
||||
{
|
||||
if ( address11 < 0x7BB240 )
|
||||
address11 -= 0x50;
|
||||
else
|
||||
address11 -= 0x40;
|
||||
}
|
||||
return address11;
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByVersion(AddrVariant address10, AddrVariant address11, AddrVariant addressSteam, AddrVariant addressNewsteamR2, AddrVariant addressNewsteamR2_LV)
|
||||
{
|
||||
InitializeVersions();
|
||||
|
||||
signed char bVer = *GetVer();
|
||||
|
||||
switch ( bVer )
|
||||
{
|
||||
case 1:
|
||||
if ( std::holds_alternative<PatternAndOffset>(address11) ) return HandlePattern( std::get<PatternAndOffset>(address11) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(address11);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
|
||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
// Adjust to US if needed
|
||||
return AdjustAddress_11(addr);
|
||||
}
|
||||
case 2:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressSteam) ) return HandlePattern( std::get<PatternAndOffset>(addressSteam) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressSteam);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return addr;
|
||||
}
|
||||
case 3:
|
||||
return GetDummy();
|
||||
case 4:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressNewsteamR2) ) return HandlePattern( std::get<PatternAndOffset>(addressNewsteamR2) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressNewsteamR2);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return DynBaseAddress(addr);
|
||||
}
|
||||
case 5:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressNewsteamR2_LV) ) return HandlePattern( std::get<PatternAndOffset>(addressNewsteamR2_LV) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressNewsteamR2_LV);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return DynBaseAddress(addr);
|
||||
}
|
||||
default:
|
||||
if ( std::holds_alternative<PatternAndOffset>(address10) ) return HandlePattern( std::get<PatternAndOffset>(address10) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(address10);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
// Adjust to EU if needed
|
||||
return AdjustAddress_10(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByRegion_10(uintptr_t address10)
|
||||
{
|
||||
InitializeRegion_10();
|
||||
|
||||
// Adjust to EU if needed
|
||||
return AdjustAddress_10(address10);
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByRegion_11(uintptr_t address11)
|
||||
{
|
||||
InitializeRegion_11();
|
||||
|
||||
// Adjust to US if needed
|
||||
return AdjustAddress_11(address11);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined _GTA_III || defined _GTA_VC
|
||||
|
||||
inline uintptr_t AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam)
|
||||
{
|
||||
InitializeVersions();
|
||||
|
||||
signed char bVer = *GetVer();
|
||||
|
||||
switch ( bVer )
|
||||
{
|
||||
case 1:
|
||||
#ifdef assert
|
||||
assert(address11);
|
||||
#endif
|
||||
return address11;
|
||||
case 2:
|
||||
#ifdef assert
|
||||
assert(addressSteam);
|
||||
#endif
|
||||
return addressSteam;
|
||||
default:
|
||||
#ifdef assert
|
||||
assert(address10);
|
||||
#endif
|
||||
return address10;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if defined _GTA_III || defined _GTA_VC
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( address10, address11, addressSteam ));
|
||||
}
|
||||
|
||||
#elif defined _GTA_SA
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant address11, Memory::AddrVariant addressSteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), std::move(address11), std::move(addressSteam), 0, 0 ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant address11, Memory::AddrVariant addressSteam, Memory::AddrVariant addressNewsteamR2, Memory::AddrVariant addressNewsteamR2_LV)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), std::move(address11), std::move(addressSteam), std::move(addressNewsteamR2), std::move(addressNewsteamR2_LV) ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant addressNewsteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), 0, 0, addressNewsteam, addressNewsteam ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByRegion_10(uintptr_t address10)
|
||||
{
|
||||
return T(Memory::internal::AddressByRegion_10(address10));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByRegion_11(uintptr_t address11)
|
||||
{
|
||||
return T(Memory::internal::AddressByRegion_11(address11));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
struct VersionInfo
|
||||
{
|
||||
int8_t version;
|
||||
bool european;
|
||||
};
|
||||
|
||||
inline VersionInfo GetVersion()
|
||||
{
|
||||
Memory::internal::InitializeVersions();
|
||||
return { *Memory::internal::GetVer(), *Memory::internal::GetEuropean() };
|
||||
}
|
||||
};
|
|
@ -25,9 +25,6 @@
|
|||
#ifndef _MEMORY_NO_CRT
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <variant>
|
||||
|
||||
#include "Patterns.h"
|
||||
#endif
|
||||
|
||||
enum
|
||||
|
@ -36,438 +33,12 @@ enum
|
|||
PATCH_JUMP
|
||||
};
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
struct PatternAndOffset
|
||||
{
|
||||
PatternAndOffset( std::string_view pattern, ptrdiff_t offset = 0 )
|
||||
: pattern(std::move(pattern)), offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
std::string_view pattern;
|
||||
ptrdiff_t offset;
|
||||
};
|
||||
|
||||
using AddrVariant = std::variant<uintptr_t, PatternAndOffset>;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
inline signed char* GetVer()
|
||||
{
|
||||
static signed char bVer = -1;
|
||||
return &bVer;
|
||||
}
|
||||
|
||||
inline bool* GetEuropean()
|
||||
{
|
||||
static bool bEuropean;
|
||||
return &bEuropean;
|
||||
}
|
||||
|
||||
inline uintptr_t GetDummy()
|
||||
{
|
||||
static uintptr_t dwDummy;
|
||||
return reinterpret_cast<uintptr_t>(&dwDummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename AT>
|
||||
inline AT DynBaseAddress(AT address)
|
||||
{
|
||||
return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address;
|
||||
}
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
inline uintptr_t HandlePattern( const PatternAndOffset& pattern )
|
||||
{
|
||||
void* addr = hook::get_pattern( pattern.pattern, pattern.offset );
|
||||
return reinterpret_cast<uintptr_t>(addr);
|
||||
}
|
||||
|
||||
#if defined _GTA_III
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if (*(uint32_t*)0x5C1E75 == 0xB85548EC) *bVer = 0;
|
||||
else if (*(uint32_t*)0x5C2135 == 0xB85548EC) *bVer = 1;
|
||||
else if (*(uint32_t*)0x5C6FD5 == 0xB85548EC) *bVer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined _GTA_VC
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if (*(uint32_t*)0x667BF5 == 0xB85548EC) *bVer = 0;
|
||||
else if (*(uint32_t*)0x667C45 == 0xB85548EC) *bVer = 1;
|
||||
else if (*(uint32_t*)0x666BA5 == 0xB85548EC) *bVer = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined _GTA_SA
|
||||
|
||||
inline bool TryMatch_10()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x82457C) == 0x94BF )
|
||||
{
|
||||
// 1.0 US
|
||||
*GetVer() = 0;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
if ( *(uint32_t*)DynBaseAddress(0x8245BC) == 0x94BF )
|
||||
{
|
||||
// 1.0 EU
|
||||
*GetVer() = 0;
|
||||
*GetEuropean() = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_11()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x8252FC) == 0x94BF )
|
||||
{
|
||||
// 1.01 US
|
||||
*GetVer() = 1;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
if ( *(uint32_t*)DynBaseAddress(0x82533C) == 0x94BF )
|
||||
{
|
||||
// 1.01 EU
|
||||
*GetVer() = 1;
|
||||
*GetEuropean() = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_30()
|
||||
{
|
||||
if (*(uint32_t*)DynBaseAddress(0x85EC4A) == 0x94BF )
|
||||
{
|
||||
// 3.0
|
||||
*GetVer() = 2;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r1()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858D21) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r1
|
||||
*GetVer() = 3;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r2()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858D51) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r2
|
||||
*GetVer() = 4;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool TryMatch_newsteam_r2_lv()
|
||||
{
|
||||
if ( *(uint32_t*)DynBaseAddress(0x858C61) == 0x3539F633 )
|
||||
{
|
||||
// newsteam r2 lv
|
||||
*GetVer() = 5;
|
||||
*GetEuropean() = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
if ( *GetVer() == -1 )
|
||||
{
|
||||
if ( TryMatch_10() ) return;
|
||||
if ( TryMatch_11() ) return;
|
||||
if ( TryMatch_30() ) return;
|
||||
if ( TryMatch_newsteam_r1() ) return;
|
||||
if ( TryMatch_newsteam_r2() ) return;
|
||||
if ( TryMatch_newsteam_r2_lv() ) return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void InitializeRegion_10()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if ( !TryMatch_10() )
|
||||
{
|
||||
#ifdef assert
|
||||
assert(!"AddressByRegion_10 on non-1.0 EXE!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void InitializeRegion_11()
|
||||
{
|
||||
signed char* bVer = GetVer();
|
||||
|
||||
if ( *bVer == -1 )
|
||||
{
|
||||
if ( !TryMatch_11() )
|
||||
{
|
||||
#ifdef assert
|
||||
assert(!"AddressByRegion_11 on non-1.01 EXE!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uintptr_t AdjustAddress_10(uintptr_t address10)
|
||||
{
|
||||
if ( *GetEuropean() )
|
||||
{
|
||||
if ( address10 >= 0x746720 && address10 < 0x857000 )
|
||||
{
|
||||
if ( address10 >= 0x7BA940 )
|
||||
address10 += 0x40;
|
||||
else
|
||||
address10 += 0x50;
|
||||
}
|
||||
}
|
||||
return address10;
|
||||
}
|
||||
|
||||
inline uintptr_t AdjustAddress_11(uintptr_t address11)
|
||||
{
|
||||
if ( !(*GetEuropean()) && address11 > 0x746FA0 )
|
||||
{
|
||||
if ( address11 < 0x7BB240 )
|
||||
address11 -= 0x50;
|
||||
else
|
||||
address11 -= 0x40;
|
||||
}
|
||||
return address11;
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByVersion(AddrVariant address10, AddrVariant address11, AddrVariant addressSteam, AddrVariant addressNewsteamR2, AddrVariant addressNewsteamR2_LV)
|
||||
{
|
||||
InitializeVersions();
|
||||
|
||||
signed char bVer = *GetVer();
|
||||
|
||||
switch ( bVer )
|
||||
{
|
||||
case 1:
|
||||
if ( std::holds_alternative<PatternAndOffset>(address11) ) return HandlePattern( std::get<PatternAndOffset>(address11) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(address11);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
|
||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
// Adjust to US if needed
|
||||
return AdjustAddress_11(addr);
|
||||
}
|
||||
case 2:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressSteam) ) return HandlePattern( std::get<PatternAndOffset>(addressSteam) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressSteam);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
// Safety measures - if null, return dummy var pointer to prevent a crash
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return addr;
|
||||
}
|
||||
case 3:
|
||||
return GetDummy();
|
||||
case 4:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressNewsteamR2) ) return HandlePattern( std::get<PatternAndOffset>(addressNewsteamR2) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressNewsteamR2);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return DynBaseAddress(addr);
|
||||
}
|
||||
case 5:
|
||||
if ( std::holds_alternative<PatternAndOffset>(addressNewsteamR2_LV) ) return HandlePattern( std::get<PatternAndOffset>(addressNewsteamR2_LV) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(addressNewsteamR2_LV);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
if ( addr == 0 )
|
||||
return GetDummy();
|
||||
|
||||
return DynBaseAddress(addr);
|
||||
}
|
||||
default:
|
||||
if ( std::holds_alternative<PatternAndOffset>(address10) ) return HandlePattern( std::get<PatternAndOffset>(address10) );
|
||||
else
|
||||
{
|
||||
const uintptr_t addr = std::get<uintptr_t>(address10);
|
||||
#ifdef assert
|
||||
assert(addr);
|
||||
#endif
|
||||
// Adjust to EU if needed
|
||||
return AdjustAddress_10(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByRegion_10(uintptr_t address10)
|
||||
{
|
||||
InitializeRegion_10();
|
||||
|
||||
// Adjust to EU if needed
|
||||
return AdjustAddress_10(address10);
|
||||
}
|
||||
|
||||
inline uintptr_t AddressByRegion_11(uintptr_t address11)
|
||||
{
|
||||
InitializeRegion_11();
|
||||
|
||||
// Adjust to US if needed
|
||||
return AdjustAddress_11(address11);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline void InitializeVersions()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined _GTA_III || defined _GTA_VC
|
||||
|
||||
inline uintptr_t AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam)
|
||||
{
|
||||
InitializeVersions();
|
||||
|
||||
signed char bVer = *GetVer();
|
||||
|
||||
switch ( bVer )
|
||||
{
|
||||
case 1:
|
||||
#ifdef assert
|
||||
assert(address11);
|
||||
#endif
|
||||
return address11;
|
||||
case 2:
|
||||
#ifdef assert
|
||||
assert(addressSteam);
|
||||
#endif
|
||||
return addressSteam;
|
||||
default:
|
||||
#ifdef assert
|
||||
assert(address10);
|
||||
#endif
|
||||
return address10;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if defined _GTA_III || defined _GTA_VC
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(uintptr_t address10, uintptr_t address11, uintptr_t addressSteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( address10, address11, addressSteam ));
|
||||
}
|
||||
|
||||
#elif defined _GTA_SA
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant address11, Memory::AddrVariant addressSteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), std::move(address11), std::move(addressSteam), 0, 0 ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant address11, Memory::AddrVariant addressSteam, Memory::AddrVariant addressNewsteamR2, Memory::AddrVariant addressNewsteamR2_LV)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), std::move(address11), std::move(addressSteam), std::move(addressNewsteamR2), std::move(addressNewsteamR2_LV) ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByVersion(Memory::AddrVariant address10, Memory::AddrVariant addressNewsteam)
|
||||
{
|
||||
return T(Memory::internal::AddressByVersion( std::move(address10), 0, 0, addressNewsteam, addressNewsteam ));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByRegion_10(uintptr_t address10)
|
||||
{
|
||||
return T(Memory::internal::AddressByRegion_10(address10));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T AddressByRegion_11(uintptr_t address11)
|
||||
{
|
||||
return T(Memory::internal::AddressByRegion_11(address11));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
struct VersionInfo
|
||||
{
|
||||
int8_t version;
|
||||
bool european;
|
||||
};
|
||||
|
||||
inline VersionInfo GetVersion()
|
||||
{
|
||||
Memory::internal::InitializeVersions();
|
||||
return { *Memory::internal::GetVer(), *Memory::internal::GetEuropean() };
|
||||
}
|
||||
};
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
template<typename T, typename AT>
|
||||
|
@ -478,7 +49,7 @@ namespace Memory
|
|||
template<typename AT>
|
||||
inline void Patch(AT address, std::initializer_list<uint8_t> list )
|
||||
{
|
||||
uint8_t* const addr = (uint8_t*)address;
|
||||
uint8_t* addr = reinterpret_cast<uint8_t*>(address);
|
||||
std::copy( list.begin(), list.end(), stdext::make_checked_array_iterator(addr, list.size()) );
|
||||
}
|
||||
#endif
|
||||
|
@ -502,24 +73,16 @@ namespace Memory
|
|||
Func funcPtr;
|
||||
} cast;
|
||||
static_assert( sizeof(cast.addr) == sizeof(cast.funcPtr), "member_cast failure!" );
|
||||
|
||||
cast.funcPtr = hook;
|
||||
*(ptrdiff_t*)((intptr_t)address + 1) = cast.addr - (intptr_t)address - 5;
|
||||
|
||||
*(int32_t*)((intptr_t)address + 1) = static_cast<int32_t>(cast.addr - (intptr_t)address - 5);
|
||||
}
|
||||
|
||||
template<typename AT, typename HT>
|
||||
inline void InjectHook(AT address, HT hook, unsigned int nType)
|
||||
template<typename AT, typename Func>
|
||||
inline void InjectHook(AT address, Func hook, unsigned int nType)
|
||||
{
|
||||
intptr_t dwHook;
|
||||
_asm
|
||||
{
|
||||
mov eax, hook
|
||||
mov dwHook, eax
|
||||
}
|
||||
|
||||
*(uint8_t*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8;
|
||||
|
||||
*(ptrdiff_t*)((intptr_t)address + 1) = dwHook - (intptr_t)address - 5;
|
||||
InjectHook(address, hook);
|
||||
}
|
||||
|
||||
template<typename Func, typename AT>
|
||||
|
@ -532,7 +95,7 @@ namespace Memory
|
|||
} cast;
|
||||
static_assert( sizeof(cast.addr) == sizeof(cast.funcPtr), "member_cast failure!" );
|
||||
|
||||
cast.addr = *(ptrdiff_t*)((intptr_t)address+1) + (intptr_t)address + 5;
|
||||
cast.addr = (intptr_t)address + 5 + *(int32_t*)((intptr_t)address+1);
|
||||
func = cast.funcPtr;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,5 +9,6 @@
|
|||
#include <cstdio>
|
||||
|
||||
#include "MemoryMgr.h"
|
||||
#include "MemoryMgr.GTA.h"
|
||||
|
||||
#define DISABLE_FLA_DONATION_WINDOW 0
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<ClInclude Include="..\SilentPatch\Common.h" />
|
||||
<ClInclude Include="..\SilentPatch\Common_ddraw.h" />
|
||||
<ClInclude Include="..\SilentPatch\General.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
|
||||
<ClInclude Include="..\SilentPatch\Patterns.h" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
<ClInclude Include="..\SilentPatch\StoredCar.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
|
@ -228,6 +228,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
|||
<ClInclude Include="..\SilentPatch\FLAC\metadata.h" />
|
||||
<ClInclude Include="..\SilentPatch\FLAC\ordinals.h" />
|
||||
<ClInclude Include="..\SilentPatch\FLAC\stream_decoder.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
|
||||
<ClInclude Include="..\SilentPatch\ModuleList.hpp" />
|
||||
<ClInclude Include="..\SilentPatch\Patterns.h" />
|
||||
|
|
|
@ -167,6 +167,9 @@
|
|||
<ClInclude Include="FireManagerSA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <rtpng.h>
|
||||
|
||||
#include "MemoryMgr.h"
|
||||
#include "MemoryMgr.GTA.h"
|
||||
#include "Maths.h"
|
||||
#include "rwpred.hpp"
|
||||
|
||||
|
|
|
@ -176,6 +176,7 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="..\SilentPatch\Common_ddraw.h" />
|
||||
<ClInclude Include="..\SilentPatch\General.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h" />
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
|
||||
<ClInclude Include="..\SilentPatch\Patterns.h" />
|
||||
<ClInclude Include="..\SilentPatch\StdAfx.h" />
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
<ClInclude Include="ModelInfoVC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\SilentPatch\Timer.cpp">
|
||||
|
|
Loading…
Reference in a new issue