Moved shared stuff to a submodule

This commit is contained in:
Silent 2019-06-28 23:14:32 +02:00
parent 19f078bb04
commit 4d02505521
No known key found for this signature in database
GPG Key ID: AE53149BB0C45AF1
28 changed files with 121 additions and 1681 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "SilentPatch/Utils"]
path = SilentPatch/Utils
url = https://github.com/CookiePLMonster/ModUtils.git

View File

@ -168,7 +168,7 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\SilentPatch\Common_ddraw.cpp" />
<ClCompile Include="..\SilentPatch\Patterns.cpp" />
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp" />
<ClCompile Include="dllmain.cpp" />
</ItemGroup>
<ItemGroup>
@ -176,8 +176,8 @@ copy /y "$(TargetPath)" "D:\Steam\steamapps\common\Grand Theft Auto Vice City\dd
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\Common_ddraw.h" />
<ClInclude Include="..\SilentPatch\MemoryMgr.h" />
<ClInclude Include="..\SilentPatch\Patterns.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -13,28 +13,34 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Utils">
<UniqueIdentifier>{e6db2444-bfd1-4eb2-a878-7de676789c09}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Utils">
<UniqueIdentifier>{53c8e8e5-df13-4831-aa9b-a14b0d0fec04}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Common_ddraw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<Filter>Source Files\Utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Patterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Common_ddraw.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">

View File

@ -6,8 +6,8 @@
#include <stdio.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#include "MemoryMgr.h"
#include "Patterns.h"
#include "Utils/MemoryMgr.h"
#include "Utils/Patterns.h"
#include "Common_ddraw.h"

View File

@ -1,7 +1,7 @@
#include "Common.h"
#include "MemoryMgr.h"
#include "Patterns.h"
#include "Utils/MemoryMgr.h"
#include "Utils/Patterns.h"
#include "StoredCar.h"

View File

@ -2,8 +2,8 @@
#include <Shlwapi.h>
#include <ShlObj.h>
#include "MemoryMgr.h"
#include "Patterns.h"
#include "Utils/MemoryMgr.h"
#include "Utils/Patterns.h"
#pragma comment(lib, "shlwapi.lib")

View File

@ -1,56 +0,0 @@
#pragma once
template<typename T>
class BasicDelimStringReader
{
public:
BasicDelimStringReader( size_t size )
: m_buffer( new T[size] ), m_size( size )
{
Reset();
}
~BasicDelimStringReader()
{
delete[] m_buffer;
}
inline T* GetBuffer() const
{
return m_buffer;
}
inline size_t GetSize() const
{
return m_size;
}
const T* GetString( size_t* size = nullptr )
{
if ( *m_cursor == '\0' )
{
if ( size != nullptr ) *size = 0;
return nullptr;
}
const T* curString = m_cursor;
size_t len = 0;
while ( *m_cursor++ != '\0' ) len++;
if ( size != nullptr ) *size = len;
return curString;
}
inline void Reset()
{
m_cursor = m_buffer;
}
private:
T* const m_buffer;
const T* m_cursor;
const size_t m_size;
};
typedef BasicDelimStringReader<char> DelimStringReader;
typedef BasicDelimStringReader<wchar_t> WideDelimStringReader;

View File

@ -1,432 +0,0 @@
#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 ( auto pao = std::get_if<PatternAndOffset>(&address11) ) return HandlePattern( *pao );
else
{
const uintptr_t addr = *std::get_if<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 ( auto pao = std::get_if<PatternAndOffset>(&addressSteam) ) return HandlePattern( *pao );
else
{
const uintptr_t addr = *std::get_if<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 ( auto pao = std::get_if<PatternAndOffset>(&addressNewsteamR2) ) return HandlePattern( *pao );
else
{
const uintptr_t addr = *std::get_if<uintptr_t>(&addressNewsteamR2);
#ifdef assert
assert(addr);
#endif
if ( addr == 0 )
return GetDummy();
return DynBaseAddress(addr);
}
case 5:
if ( auto pao = std::get_if<PatternAndOffset>(&addressNewsteamR2) ) return HandlePattern( *pao );
else
{
const uintptr_t addr = *std::get_if<uintptr_t>(&addressNewsteamR2_LV);
#ifdef assert
assert(addr);
#endif
if ( addr == 0 )
return GetDummy();
return DynBaseAddress(addr);
}
default:
if ( auto pao = std::get_if<PatternAndOffset>(&address10) ) return HandlePattern( *pao );
else
{
const uintptr_t addr = *std::get_if<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() };
}
};

View File

@ -1,429 +0,0 @@
#ifndef __MEMORYMGR
#define __MEMORYMGR
// Switches:
// _MEMORY_NO_CRT - don't include anything "complex" like ScopedUnprotect or memset
// _MEMORY_DECLS_ONLY - don't include anything but macroes
#define WRAPPER __declspec(naked)
#define DEPRECATED __declspec(deprecated)
#define EAXJMP(a) { _asm mov eax, a _asm jmp eax }
#define VARJMP(a) { _asm jmp a }
#define WRAPARG(a) ((int)a)
#define NOVMT __declspec(novtable)
#define SETVMT(a) *((uintptr_t*)this) = (uintptr_t)a
#ifndef _MEMORY_DECLS_ONLY
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <cstdint>
#include <cassert>
#ifndef _MEMORY_NO_CRT
#include <initializer_list>
#include <iterator>
#endif
enum
{
PATCH_CALL,
PATCH_JUMP
};
template<typename AT>
inline AT DynBaseAddress(AT address)
{
return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address;
}
namespace Memory
{
template<typename T, typename AT>
inline void Patch(AT address, T value)
{*(T*)address = value; }
#ifndef _MEMORY_NO_CRT
template<typename AT>
inline void Patch(AT address, std::initializer_list<uint8_t> list )
{
uint8_t* addr = reinterpret_cast<uint8_t*>(address);
std::copy( list.begin(), list.end(), stdext::make_checked_array_iterator(addr, list.size()) );
}
#endif
template<typename AT>
inline void Nop(AT address, size_t count)
#ifndef _MEMORY_NO_CRT
{ memset((void*)address, 0x90, count); }
#else
{ do {
*(uint8_t*)address++ = 0x90;
} while ( --count != 0 ); }
#endif
template<typename AT, typename Func>
inline void InjectHook(AT address, Func hook)
{
union member_cast
{
intptr_t addr;
Func funcPtr;
} cast;
static_assert( sizeof(cast.addr) == sizeof(cast.funcPtr), "member_cast failure!" );
cast.funcPtr = hook;
*(int32_t*)((intptr_t)address + 1) = static_cast<int32_t>(cast.addr - (intptr_t)address - 5);
}
template<typename AT, typename Func>
inline void InjectHook(AT address, Func hook, unsigned int nType)
{
*(uint8_t*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8;
InjectHook(address, hook);
}
template<typename Func, typename AT>
inline void ReadCall(AT address, Func& func)
{
union member_cast
{
intptr_t addr;
Func funcPtr;
} cast;
static_assert( sizeof(cast.addr) == sizeof(cast.funcPtr), "member_cast failure!" );
cast.addr = (intptr_t)address + 5 + *(int32_t*)((intptr_t)address+1);
func = cast.funcPtr;
}
template<typename AT>
inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0)
{
uintptr_t addr;
ReadCall( address, addr );
return reinterpret_cast<void*>( addr + offset );
}
#ifndef _MEMORY_NO_CRT
inline bool MemEquals(uintptr_t address, std::initializer_list<uint8_t> val)
{
const uint8_t* mem = reinterpret_cast<const uint8_t*>(address);
return std::equal( val.begin(), val.end(), stdext::make_checked_array_iterator(mem, val.size()) );
}
#endif
template<typename AT>
inline AT Verify(AT address, uintptr_t expected)
{
assert( uintptr_t(address) == expected );
return address;
}
namespace DynBase
{
template<typename T, typename AT>
inline void Patch(AT address, T value)
{
Memory::Patch(DynBaseAddress(address), value);
}
#ifndef _MEMORY_NO_CRT
template<typename AT>
inline void Patch(AT address, std::initializer_list<uint8_t> list )
{
Memory::Patch(DynBaseAddress(address), std::move(list));
}
#endif
template<typename AT>
inline void Nop(AT address, size_t count)
{
Memory::Nop(DynBaseAddress(address), count);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook)
{
Memory::InjectHook(DynBaseAddress(address), hook);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook, unsigned int nType)
{
Memory::InjectHook(DynBaseAddress(address), hook, nType);
}
template<typename Func, typename AT>
inline void ReadCall(AT address, Func& func)
{
Memory::ReadCall(DynBaseAddress(address), func);
}
template<typename AT>
inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0)
{
return Memory::ReadCallFrom(DynBaseAddress(address), offset);
}
#ifndef _MEMORY_NO_CRT
inline bool MemEquals(uintptr_t address, std::initializer_list<uint8_t> val)
{
return Memory::MemEquals(DynBaseAddress(address), std::move(val));
}
template<typename AT>
inline AT Verify(AT address, uintptr_t expected)
{
return Memory::Verify(address, DynBaseAddress(expected));
}
#endif
};
namespace VP
{
template<typename T, typename AT>
inline void Patch(AT address, T value)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, sizeof(T), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Memory::Patch( address, value );
VirtualProtect((void*)address, sizeof(T), dwProtect[0], &dwProtect[1]);
}
#ifndef _MEMORY_NO_CRT
template<typename AT>
inline void Patch(AT address, std::initializer_list<uint8_t> list )
{
DWORD dwProtect[2];
VirtualProtect((void*)address, list.size(), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Memory::Patch(address, std::move(list));
VirtualProtect((void*)address, list.size(), dwProtect[0], &dwProtect[1]);
}
#endif
template<typename AT>
inline void Nop(AT address, size_t count)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, count, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Memory::Nop( address, count );
VirtualProtect((void*)address, count, dwProtect[0], &dwProtect[1]);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook)
{
DWORD dwProtect[2];
VirtualProtect((void*)((DWORD_PTR)address + 1), 4, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Memory::InjectHook( address, hook );
VirtualProtect((void*)((DWORD_PTR)address + 1), 4, dwProtect[0], &dwProtect[1]);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook, unsigned int nType)
{
DWORD dwProtect[2];
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect[0]);
Memory::InjectHook( address, hook, nType );
VirtualProtect((void*)address, 5, dwProtect[0], &dwProtect[1]);
}
template<typename Func, typename AT>
inline void ReadCall(AT address, Func& func)
{
Memory::ReadCall(address, func);
}
template<typename AT>
inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0)
{
return Memory::ReadCallFrom(address, offset);
}
#ifndef _MEMORY_NO_CRT
inline bool MemEquals(uintptr_t address, std::initializer_list<uint8_t> val)
{
return Memory::MemEquals(address, std::move(val));
}
#endif
template<typename AT>
inline AT Verify(AT address, uintptr_t expected)
{
return Memory::Verify(address, expected);
}
namespace DynBase
{
template<typename T, typename AT>
inline void Patch(AT address, T value)
{
VP::Patch(DynBaseAddress(address), value);
}
#ifndef _MEMORY_NO_CRT
template<typename AT>
inline void Patch(AT address, std::initializer_list<uint8_t> list )
{
VP::Patch(DynBaseAddress(address), std::move(list));
}
#endif
template<typename AT>
inline void Nop(AT address, size_t count)
{
VP::Nop(DynBaseAddress(address), count);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook)
{
VP::InjectHook(DynBaseAddress(address), hook);
}
template<typename AT, typename HT>
inline void InjectHook(AT address, HT hook, unsigned int nType)
{
VP::InjectHook(DynBaseAddress(address), hook, nType);
}
template<typename Func, typename AT>
inline void ReadCall(AT address, Func& func)
{
Memory::ReadCall(DynBaseAddress(address), func);
}
template<typename AT>
inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0)
{
Memory::ReadCallFrom(DynBaseAddress(address), offset);
}
#ifndef _MEMORY_NO_CRT
inline bool MemEquals(uintptr_t address, std::initializer_list<uint8_t> val)
{
return Memory::MemEquals(DynBaseAddress(address), std::move(val));
}
#endif
template<typename AT>
inline AT Verify(AT address, uintptr_t expected)
{
return Memory::Verify(address, DynBaseAddress(expected));
}
};
};
};
#ifndef _MEMORY_NO_CRT
#include <forward_list>
#include <tuple>
#include <memory>
namespace ScopedUnprotect
{
class Unprotect
{
public:
~Unprotect()
{
for ( auto& it : m_queriedProtects )
{
DWORD dwOldProtect;
VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect );
}
}
protected:
Unprotect() = default;
void UnprotectRange( DWORD_PTR BaseAddress, SIZE_T Size )
{
SIZE_T QueriedSize = 0;
while ( QueriedSize < Size )
{
MEMORY_BASIC_INFORMATION MemoryInf;
DWORD dwOldProtect;
VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 &&
(MemoryInf.Protect & (PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 )
{
const bool wasExecutable = (MemoryInf.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ)) != 0;
VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, wasExecutable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &dwOldProtect );
m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
}
QueriedSize += MemoryInf.RegionSize;
}
}
private:
std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects;
};
class Section : public Unprotect
{
public:
Section( HINSTANCE hInstance, const char* name )
{
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader);
DWORD_PTR VirtualAddress = DWORD_PTR(-1);
SIZE_T VirtualSize = SIZE_T(-1);
for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
{
if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
{
VirtualAddress = (DWORD_PTR)hInstance + pSection->VirtualAddress;
VirtualSize = pSection->Misc.VirtualSize;
m_locatedSection = true;
break;
}
}
if ( VirtualAddress == DWORD_PTR(-1) )
return;
UnprotectRange( VirtualAddress, VirtualSize );
};
bool SectionLocated() const { return m_locatedSection; }
private:
bool m_locatedSection = false;
};
class FullModule : public Unprotect
{
public:
FullModule( HINSTANCE hInstance )
{
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
UnprotectRange( (DWORD_PTR)hInstance, ntHeader->OptionalHeader.SizeOfImage );
}
};
inline std::unique_ptr<Unprotect> UnprotectSectionOrFullModule( HINSTANCE hInstance, const char* name )
{
std::unique_ptr<Section> section = std::make_unique<Section>( hInstance, name );
if ( !section->SectionLocated() )
{
return std::make_unique<FullModule>( hInstance );
}
return section;
}
};
#endif
#endif
#endif

View File

@ -1,212 +0,0 @@
#pragma once
#include <vector>
#include <algorithm>
#include <cassert>
// Stores a list of loaded modules with their names, WITHOUT extension
class ModuleList
{
public:
struct LazyEnumerateTag {};
ModuleList()
{
Enumerate();
}
explicit ModuleList( LazyEnumerateTag )
{
}
// Initializes module list
// Needs to be called before any calls to Get or GetAll
void Enumerate()
{
// Cannot enumerate twice without cleaing
assert( m_moduleList.size() == 0 );
constexpr size_t INITIAL_SIZE = sizeof(HMODULE) * 256;
HMODULE* modules = static_cast<HMODULE*>(malloc( INITIAL_SIZE ));
if ( modules != nullptr )
{
typedef BOOL (WINAPI * Func)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);
HMODULE hLib = LoadLibrary( TEXT("kernel32") );
assert( hLib != nullptr ); // If this fails then everything is probably broken anyway
Func pEnumProcessModules = reinterpret_cast<Func>(GetProcAddress( hLib, "K32EnumProcessModules" ));
if ( pEnumProcessModules == nullptr )
{
// Try psapi
FreeLibrary( hLib );
hLib = LoadLibrary( TEXT("psapi") );
if ( hLib != nullptr )
{
pEnumProcessModules = reinterpret_cast<Func>(GetProcAddress( hLib, "EnumProcessModules" ));
}
}
if ( pEnumProcessModules != nullptr )
{
const HANDLE currentProcess = GetCurrentProcess();
DWORD cbNeeded = 0;
if ( pEnumProcessModules( currentProcess, modules, INITIAL_SIZE, &cbNeeded ) != 0 )
{
if ( cbNeeded > INITIAL_SIZE )
{
HMODULE* newModules = static_cast<HMODULE*>(realloc( modules, cbNeeded ));
if ( newModules != nullptr )
{
modules = newModules;
if ( pEnumProcessModules( currentProcess, modules, cbNeeded, &cbNeeded ) != 0 )
{
EnumerateInternal( modules, cbNeeded / sizeof(HMODULE) );
}
}
else
{
EnumerateInternal( modules, INITIAL_SIZE / sizeof(HMODULE) );
}
}
else
{
EnumerateInternal( modules, cbNeeded / sizeof(HMODULE) );
}
}
}
if ( hLib != nullptr )
{
FreeLibrary( hLib );
}
free( modules );
}
}
// Recreates module list
void ReEnumerate()
{
Clear();
Enumerate();
}
// Clears module list
void Clear()
{
m_moduleList.clear();
}
// Gets handle of a loaded module with given name, NULL otherwise
HMODULE Get( const wchar_t* moduleName ) const
{
// If vector is empty then we're trying to call it without calling Enumerate first
assert( m_moduleList.size() != 0 );
auto it = std::find_if( m_moduleList.begin(), m_moduleList.end(), [&]( const auto& e ) {
return _wcsicmp( moduleName, e.second.c_str() ) == 0;
} );
return it != m_moduleList.end() ? it->first : nullptr;
}
// Gets handles to all loaded modules with given name
std::vector<HMODULE> GetAll( const wchar_t* moduleName ) const
{
// If vector is empty then we're trying to call it without calling Enumerate first
assert( m_moduleList.size() != 0 );
std::vector<HMODULE> results;
for ( auto& e : m_moduleList )
{
if ( _wcsicmp( moduleName, e.second.c_str() ) == 0 )
{
results.push_back( e.first );
}
}
return results;
}
// Gets handle of a loaded module with given prefix, NULL otherwise
HMODULE GetByPrefix( const wchar_t* modulePrefix ) const
{
// If vector is empty then we're trying to call it without calling Enumerate first
assert( m_moduleList.size() != 0 );
const size_t len = wcslen( modulePrefix );
auto it = std::find_if( m_moduleList.begin(), m_moduleList.end(), [&]( const auto& e ) {
return _wcsnicmp( modulePrefix, e.second.c_str(), len ) == 0;
} );
return it != m_moduleList.end() ? it->first : nullptr;
}
// Gets handles to all loaded modules with given prefix
std::vector<HMODULE> GetAllByPrefix( const wchar_t* modulePrefix ) const
{
// If vector is empty then we're trying to call it without calling Enumerate first
assert( m_moduleList.size() != 0 );
const size_t len = wcslen( modulePrefix );
std::vector<HMODULE> results;
for ( auto& e : m_moduleList )
{
if ( _wcsnicmp( modulePrefix, e.second.c_str(), len ) == 0 )
{
results.push_back( e.first );
}
}
return results;
}
private:
void EnumerateInternal( HMODULE* modules, size_t numModules )
{
size_t moduleNameLength = MAX_PATH;
wchar_t* moduleName = static_cast<wchar_t*>( malloc( moduleNameLength * sizeof(moduleName[0]) ) );
if ( moduleName != nullptr )
{
m_moduleList.reserve( numModules );
for ( size_t i = 0; i < numModules; i++ )
{
// Obtain module name, with resizing if necessary
DWORD size;
while ( size = GetModuleFileNameW( *modules, moduleName, moduleNameLength ), size == moduleNameLength )
{
wchar_t* newName = static_cast<wchar_t*>( realloc( moduleName, 2 * moduleNameLength * sizeof(moduleName[0]) ) );
if ( newName != nullptr )
{
moduleName = newName;
moduleNameLength *= 2;
}
else
{
size = 0;
break;
}
}
if ( size != 0 )
{
const wchar_t* nameBegin = wcsrchr( moduleName, '\\' ) + 1;
const wchar_t* dotPos = wcsrchr( nameBegin, '.' );
if ( dotPos != nullptr )
{
m_moduleList.emplace_back( *modules, std::wstring( nameBegin, dotPos ) );
}
else
{
m_moduleList.emplace_back( *modules, nameBegin );
}
}
modules++;
}
free( moduleName );
}
}
std::vector< std::pair<HMODULE, std::wstring> > m_moduleList;
};

View File

@ -1,274 +0,0 @@
/*
* This file is part of the CitizenFX project - http://citizen.re/
*
* See LICENSE and MENTIONS in the root of the source tree for information
* regarding licensing.
*/
#include "Patterns.h"
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <algorithm>
#if PATTERNS_USE_HINTS
#include <map>
#endif
#if PATTERNS_USE_HINTS
// from boost someplace
template <std::uint64_t FnvPrime, std::uint64_t OffsetBasis>
struct basic_fnv_1
{
std::uint64_t operator()(std::string_view text) const
{
std::uint64_t hash = OffsetBasis;
for (auto it : text)
{
hash *= FnvPrime;
hash ^= it;
}
return hash;
}
};
static constexpr std::uint64_t fnv_prime = 1099511628211u;
static constexpr std::uint64_t fnv_offset_basis = 14695981039346656037u;
typedef basic_fnv_1<fnv_prime, fnv_offset_basis> fnv_1;
#endif
namespace hook
{
ptrdiff_t pattern::get_process_base()
{
return ptrdiff_t(GetModuleHandle(nullptr));
}
#if PATTERNS_USE_HINTS
static auto& getHints()
{
static std::multimap<uint64_t, uintptr_t> hints;
return hints;
}
#endif
static void TransformPattern(std::string_view pattern, std::basic_string<uint8_t>& data, std::basic_string<uint8_t>& mask)
{
uint8_t tempDigit = 0;
bool tempFlag = false;
auto tol = [] (char ch) -> uint8_t
{
if (ch >= 'A' && ch <= 'F') return uint8_t(ch - 'A' + 10);
if (ch >= 'a' && ch <= 'f') return uint8_t(ch - 'a' + 10);
return uint8_t(ch - '0');
};
for (auto ch : pattern)
{
if (ch == ' ')
{
continue;
}
else if (ch == '?')
{
data.push_back(0);
mask.push_back(0);
}
else if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
{
uint8_t thisDigit = tol(ch);
if (!tempFlag)
{
tempDigit = thisDigit << 4;
tempFlag = true;
}
else
{
tempDigit |= thisDigit;
tempFlag = false;
data.push_back(tempDigit);
mask.push_back(0xFF);
}
}
}
}
class executable_meta
{
private:
uintptr_t m_begin;
uintptr_t m_end;
template<typename TReturn, typename TOffset>
TReturn* getRVA(TOffset rva)
{
return (TReturn*)(m_begin + rva);
}
public:
explicit executable_meta(uintptr_t module)
: m_begin(module)
{
PIMAGE_DOS_HEADER dosHeader = getRVA<IMAGE_DOS_HEADER>(0);
PIMAGE_NT_HEADERS ntHeader = getRVA<IMAGE_NT_HEADERS>(dosHeader->e_lfanew);
m_end = m_begin + ntHeader->OptionalHeader.SizeOfImage;
}
executable_meta(uintptr_t begin, uintptr_t end)
: m_begin(begin), m_end(end)
{
}
inline uintptr_t begin() const { return m_begin; }
inline uintptr_t end() const { return m_end; }
};
void pattern::Initialize(std::string_view pattern)
{
// get the hash for the base pattern
#if PATTERNS_USE_HINTS
m_hash = fnv_1()(pattern);
#endif
// transform the base pattern from IDA format to canonical format
TransformPattern(pattern, m_bytes, m_mask);
#if PATTERNS_USE_HINTS
// if there's hints, try those first
#if PATTERNS_CAN_SERIALIZE_HINTS
if (m_rangeStart == reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr)))
#endif
{
auto range = getHints().equal_range(m_hash);
if (range.first != range.second)
{
std::for_each(range.first, range.second, [&] (const auto& hint)
{
ConsiderHint(hint.second);
});
// if the hints succeeded, we don't need to do anything more
if (!m_matches.empty())
{
m_matched = true;
return;
}
}
}
#endif
}
void pattern::EnsureMatches(uint32_t maxCount)
{
if (m_matched)
{
return;
}
// scan the executable for code
executable_meta executable = m_rangeStart != 0 && m_rangeEnd != 0 ? executable_meta(m_rangeStart, m_rangeEnd) : executable_meta(m_rangeStart);
auto matchSuccess = [&] (uintptr_t address)
{
#if PATTERNS_USE_HINTS
getHints().emplace(m_hash, address);
#else
(void)address;
#endif
return (m_matches.size() == maxCount);
};
const uint8_t* pattern = m_bytes.data();
const uint8_t* mask = m_mask.data();
const size_t maskSize = m_mask.size();
const size_t lastWild = m_mask.find_last_not_of(uint8_t(0xFF));
ptrdiff_t Last[256];
std::fill(std::begin(Last), std::end(Last), lastWild == std::string::npos ? -1 : static_cast<ptrdiff_t>(lastWild) );
for ( ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(maskSize); ++i )
{
if ( Last[ pattern[i] ] < i )
{
Last[ pattern[i] ] = i;
}
}
for (uintptr_t i = executable.begin(), end = executable.end() - maskSize; i <= end;)
{
uint8_t* ptr = reinterpret_cast<uint8_t*>(i);
ptrdiff_t j = maskSize - 1;
while((j >= 0) && pattern[j] == (ptr[j] & mask[j])) j--;
if(j < 0)
{
m_matches.emplace_back(ptr);
if (matchSuccess(i))
{
break;
}
i++;
}
else i += std::max(ptrdiff_t(1), j - Last[ ptr[j] ]);
}
m_matched = true;
}
bool pattern::ConsiderHint(uintptr_t offset)
{
uint8_t* ptr = reinterpret_cast<uint8_t*>(offset);
#if PATTERNS_CAN_SERIALIZE_HINTS
const uint8_t* pattern = m_bytes.data();
const uint8_t* mask = m_mask.data();
for (size_t i = 0, j = m_mask.size(); i < j; i++)
{
if (pattern[i] != (ptr[i] & mask[i]))
{
return false;
}
}
#endif
m_matches.emplace_back(ptr);
return true;
}
#if PATTERNS_USE_HINTS && PATTERNS_CAN_SERIALIZE_HINTS
void pattern::hint(uint64_t hash, uintptr_t address)
{
auto& hints = getHints();
auto range = hints.equal_range(hash);
for (auto it = range.first; it != range.second; ++it)
{
if (it->second == address)
{
return;
}
}
hints.emplace(hash, address);
}
#endif
}

View File

@ -1,181 +0,0 @@
/*
* This file is part of the CitizenFX project - http://citizen.re/
*
* See LICENSE and MENTIONS in the root of the source tree for information
* regarding licensing.
*/
#pragma once
#include <cassert>
#include <vector>
#include <string_view>
#pragma warning(push)
#pragma warning(disable:4201)
namespace hook
{
class pattern_match
{
private:
void* m_pointer;
public:
inline pattern_match(void* pointer)
: m_pointer(pointer)
{
}
template<typename T>
T* get(ptrdiff_t offset = 0) const
{
char* ptr = reinterpret_cast<char*>(m_pointer);
return reinterpret_cast<T*>(ptr + offset);
}
};
class pattern
{
private:
std::basic_string<uint8_t> m_bytes;
std::basic_string<uint8_t> m_mask;
#if PATTERNS_USE_HINTS
uint64_t m_hash;
#endif
std::vector<pattern_match> m_matches;
bool m_matched = false;
uintptr_t m_rangeStart;
uintptr_t m_rangeEnd;
private:
static ptrdiff_t get_process_base();
void Initialize(std::string_view pattern);
bool ConsiderHint(uintptr_t offset);
void EnsureMatches(uint32_t maxCount);
inline pattern_match _get_internal(size_t index) const
{
return m_matches[index];
}
inline pattern(uintptr_t module)
: pattern( module, 0 )
{
}
inline pattern(uintptr_t begin, uintptr_t end)
: m_rangeStart(begin), m_rangeEnd(end)
{
}
public:
pattern(std::string_view pattern)
: pattern(get_process_base())
{
Initialize(std::move(pattern));
}
inline pattern(void* module, std::string_view pattern)
: pattern(reinterpret_cast<uintptr_t>(module))
{
Initialize(std::move(pattern));
}
inline pattern(uintptr_t begin, uintptr_t end, std::string_view pattern)
: m_rangeStart(begin), m_rangeEnd(end)
{
Initialize(std::move(pattern));
}
inline pattern&& count(uint32_t expected)
{
EnsureMatches(expected);
assert(m_matches.size() == expected);
return std::forward<pattern>(*this);
}
inline pattern&& count_hint(uint32_t expected)
{
EnsureMatches(expected);
return std::forward<pattern>(*this);
}
inline pattern&& clear()
{
m_matches.clear();
m_matched = false;
return std::forward<pattern>(*this);
}
inline size_t size()
{
EnsureMatches(UINT32_MAX);
return m_matches.size();
}
inline bool empty()
{
return size() == 0;
}
inline pattern_match get(size_t index)
{
EnsureMatches(UINT32_MAX);
return _get_internal(index);
}
inline pattern_match get_one()
{
return std::forward<pattern>(*this).count(1)._get_internal(0);
}
template<typename T = void>
inline auto get_first(ptrdiff_t offset = 0)
{
return get_one().get<T>(offset);
}
template <typename Pred>
inline Pred for_each_result(Pred&& pred)
{
EnsureMatches(UINT32_MAX);
for ( auto it : m_matches )
{
std::forward<Pred>(pred)(it);
}
return std::forward<Pred>(pred);
}
public:
#if PATTERNS_USE_HINTS && PATTERNS_CAN_SERIALIZE_HINTS
// define a hint
static void hint(uint64_t hash, uintptr_t address);
#endif
};
inline pattern make_module_pattern(void* module, std::string_view bytes)
{
return pattern(module, std::move(bytes));
}
inline pattern make_range_pattern(uintptr_t begin, uintptr_t end, std::string_view bytes)
{
return pattern(begin, end, std::move(bytes));
}
template<typename T = void>
inline auto get_pattern(std::string_view pattern_string, ptrdiff_t offset = 0)
{
return pattern(std::move(pattern_string)).get_first<T>(offset);
}
}
#pragma warning(pop)

View File

@ -8,7 +8,7 @@
#include <cassert>
#include <cstdio>
#include "MemoryMgr.h"
#include "MemoryMgr.GTA.h"
#include "Utils/MemoryMgr.h"
#include "Utils/MemoryMgr.GTA.h"
#define DISABLE_FLA_DONATION_WINDOW 0

View File

@ -1,7 +1,7 @@
#include "StdAfx.h"
#include "StoredCar.h"
#include "Patterns.h"
#include "Utils/Patterns.h"
#if _GTA_III
static auto FindPlayerPed = hook::get_pattern<class CEntity*()>( "6B C0 4F 8B 04 85 ? ? ? ? C3", -7 );

View File

@ -3,7 +3,7 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "ModuleList.hpp"
#include "Utils/ModuleList.hpp"
int32_t (*FLAUtils::GetExtendedID8Func)(const uint8_t* ptr) = FLAUtils::GetExtendedID8_Stock;
int32_t (*FLAUtils::GetExtendedID16Func)(const uint16_t* ptr) = FLAUtils::GetExtendedID16_Stock;

View File

@ -1,7 +1,7 @@
#include "StdAfx.h"
#include "Timer.h"
#include "Patterns.h"
#include "Utils/Patterns.h"
int& CTimer::m_snTimeInMilliseconds = **hook::get_pattern<int*>( "83 E4 F8 89 44 24 08 C7 44 24 0C 00 00 00 00 DF 6C 24 08", -20 + 1 );

1
SilentPatch/Utils Submodule

@ -0,0 +1 @@
Subproject commit 43e545d9fe2caa609579dd3936702a4566b71258

View File

@ -2,7 +2,7 @@
#include "General.h"
#include "Timer.h"
#include "Patterns.h"
#include "Utils/Patterns.h"
#include "Common.h"
#include "Common_ddraw.h"

View File

@ -25,13 +25,13 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\StoredCar.cpp" />
<ClCompile Include="..\SilentPatch\Timer.cpp" />
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="SilentPatchIII.cpp" />
<ClCompile Include="StdAfxIII.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
@ -43,12 +43,12 @@
<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" />
<ClInclude Include="..\SilentPatch\StoredCar.h" />
<ClInclude Include="..\SilentPatch\Timer.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
<ClInclude Include="VehicleIII.h" />
</ItemGroup>
<ItemGroup>

View File

@ -13,6 +13,12 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Utils">
<UniqueIdentifier>{6f7b5bc0-8528-4f8e-a767-183d8c1abb17}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Utils">
<UniqueIdentifier>{66df9142-3ab6-4f22-aca5-69b4c3d9b475}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\SilentPatch\Timer.cpp">
@ -24,9 +30,6 @@
<ClCompile Include="StdAfxIII.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Common.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -36,11 +39,11 @@
<ClCompile Include="..\SilentPatch\StoredCar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<Filter>Source Files\Utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -50,9 +53,6 @@
<ClInclude Include="..\SilentPatch\StdAfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Patterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="VehicleIII.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -65,8 +65,14 @@
<ClInclude Include="..\SilentPatch\StoredCar.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
<Filter>Header Files</Filter>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

View File

@ -21,9 +21,9 @@
#include "WaveDecoderSA.h"
#include "FLACDecoderSA.h"
#include "Patterns.h"
#include "DelimStringReader.h"
#include "ModuleList.hpp"
#include "Utils/Patterns.h"
#include "Utils/DelimStringReader.h"
#include "Utils/ModuleList.hpp"
#include "debugmenu_public.h"
#include "resource.h"

View File

@ -186,16 +186,16 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="AudioHardwareSA.cpp" />
<ClCompile Include="FireManagerSA.cpp" />
<ClCompile Include="FLACDecoderSA.cpp" />
@ -218,19 +218,18 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\debugmenu_public.h" />
<ClInclude Include="..\SilentPatch\DelimStringReader.h" />
<ClInclude Include="..\SilentPatch\FLAC\callback.h" />
<ClInclude Include="..\SilentPatch\FLAC\export.h" />
<ClInclude Include="..\SilentPatch\FLAC\format.h" />
<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" />
<ClInclude Include="..\SilentPatch\resource1.h" />
<ClInclude Include="..\SilentPatch\TheFLAUtils.h" />
<ClInclude Include="..\SilentPatch\Utils\DelimStringReader.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
<ClInclude Include="AudioHardwareSA.h" />
<ClInclude Include="FireManagerSA.h" />
<ClInclude Include="FLACDecoderSA.h" />

View File

@ -19,6 +19,12 @@
<Filter Include="Source Files\decoders">
<UniqueIdentifier>{f4ecbe23-228b-461b-b37f-d718e7ca92ae}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Utils">
<UniqueIdentifier>{d46aa122-7a45-44f2-a031-ad8e9b946ed2}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Utils">
<UniqueIdentifier>{09c5ceab-2ac8-4111-b2d1-d2c7379cb5c1}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SilentPatchSA.cpp">
@ -57,9 +63,6 @@
<ClCompile Include="FLACDecoderSA.cpp">
<Filter>Source Files\decoders</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\TheFLAUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -72,11 +75,11 @@
<ClCompile Include="FireManagerSA.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<Filter>Source Files\Utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\FLAC\callback.h">
<Filter>Header Files\FLAC</Filter>
</ClInclude>
@ -137,15 +140,9 @@
<ClInclude Include="FLACDecoderSA.h">
<Filter>Source Files\decoders</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Patterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\resource1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\DelimStringReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\TheFLAUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -155,21 +152,27 @@
<ClInclude Include="..\SilentPatch\debugmenu_public.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\ModuleList.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PlayerInfoSA.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FireManagerSA.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RWUtils.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\DelimStringReader.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">

View File

@ -17,8 +17,8 @@
#include <rphanim.h>
#include <rtpng.h>
#include "MemoryMgr.h"
#include "MemoryMgr.GTA.h"
#include "Utils/MemoryMgr.h"
#include "Utils/MemoryMgr.GTA.h"
#include "Maths.h"
#include "rwutils.hpp"

View File

@ -6,7 +6,7 @@
#include "VehicleSA.h"
#include "TimerSA.h"
#include "PedSA.h"
#include "DelimStringReader.h"
#include "Utils/DelimStringReader.h"
#include "PlayerInfoSA.h"
static constexpr float PHOENIX_FLUTTER_PERIOD = 70.0f;

View File

@ -1,7 +1,7 @@
#include "StdAfx.h"
#include "Timer.h"
#include "Patterns.h"
#include "Utils/Patterns.h"
#include "Common.h"
#include "Common_ddraw.h"
#include "General.h"

View File

@ -173,12 +173,12 @@
<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" />
<ClInclude Include="..\SilentPatch\StoredCar.h" />
<ClInclude Include="..\SilentPatch\Timer.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h" />
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h" />
<ClInclude Include="..\SilentPatch\Utils\Patterns.h" />
<ClInclude Include="ModelInfoVC.h" />
<ClInclude Include="VehicleVC.h" />
</ItemGroup>
@ -193,13 +193,13 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\SilentPatch\StoredCar.cpp" />
<ClCompile Include="..\SilentPatch\Timer.cpp" />
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Master|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ModelInfoVC.cpp" />
<ClCompile Include="SilentPatchVC.cpp" />
<ClCompile Include="StdAfxVC.cpp">

View File

@ -13,11 +13,14 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Header Files\Utils">
<UniqueIdentifier>{e3c269eb-37ad-4a59-a26c-cb1547484475}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Utils">
<UniqueIdentifier>{42382fee-b609-4a36-9bef-fa812755d623}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\SilentPatch\MemoryMgr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Timer.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -27,9 +30,6 @@
<ClInclude Include="..\SilentPatch\StdAfx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Patterns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\StoredCar.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -42,8 +42,14 @@
<ClInclude Include="ModelInfoVC.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\MemoryMgr.GTA.h">
<Filter>Header Files</Filter>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.GTA.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\MemoryMgr.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
<ClInclude Include="..\SilentPatch\Utils\Patterns.h">
<Filter>Header Files\Utils</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -56,9 +62,6 @@
<ClCompile Include="SilentPatchVC.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Patterns.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Common.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -71,6 +74,9 @@
<ClCompile Include="ModelInfoVC.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\SilentPatch\Utils\Patterns.cpp">
<Filter>Source Files\Utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\SilentPatch\SilentPatch.rc">