mirror of
https://github.com/Mr-X-GTA/YimMenu.git
synced 2025-06-17 14:57:27 +08:00
feat(Pointers): add cache for pointers (#1203)
This commit is contained in:
parent
38ba68e0e5
commit
a2dbddc702
@ -12,21 +12,21 @@ namespace memory
|
||||
explicit handle(std::uintptr_t ptr);
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_pointer_v<T>, T> as();
|
||||
std::enable_if_t<std::is_pointer_v<T>, T> as() const;
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_lvalue_reference_v<T>, T> as();
|
||||
std::enable_if_t<std::is_lvalue_reference_v<T>, T> as() const;
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_same_v<T, std::uintptr_t>, T> as();
|
||||
std::enable_if_t<std::is_same_v<T, std::uintptr_t>, T> as() const;
|
||||
|
||||
template<typename T>
|
||||
handle add(T offset);
|
||||
handle add(T offset) const;
|
||||
|
||||
template<typename T>
|
||||
handle sub(T offset);
|
||||
handle sub(T offset) const;
|
||||
|
||||
handle rip();
|
||||
handle rip() const;
|
||||
|
||||
explicit operator bool();
|
||||
|
||||
@ -48,36 +48,36 @@ namespace memory
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<std::is_pointer_v<T>, T> handle::as()
|
||||
inline std::enable_if_t<std::is_pointer_v<T>, T> handle::as() const
|
||||
{
|
||||
return static_cast<T>(ptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<std::is_lvalue_reference_v<T>, T> handle::as()
|
||||
inline std::enable_if_t<std::is_lvalue_reference_v<T>, T> handle::as() const
|
||||
{
|
||||
return *static_cast<std::add_pointer_t<std::remove_reference_t<T>>>(ptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::enable_if_t<std::is_same_v<T, std::uintptr_t>, T> handle::as()
|
||||
inline std::enable_if_t<std::is_same_v<T, std::uintptr_t>, T> handle::as() const
|
||||
{
|
||||
return reinterpret_cast<std::uintptr_t>(ptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline handle handle::add(T offset)
|
||||
inline handle handle::add(T offset) const
|
||||
{
|
||||
return handle(as<std::uintptr_t>() + offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline handle handle::sub(T offset)
|
||||
inline handle handle::sub(T offset) const
|
||||
{
|
||||
return handle(as<std::uintptr_t>() - offset);
|
||||
}
|
||||
|
||||
inline handle handle::rip()
|
||||
inline handle handle::rip() const
|
||||
{
|
||||
return add(as<std::int32_t&>()).add(4);
|
||||
}
|
||||
|
@ -11,22 +11,22 @@ namespace memory
|
||||
{
|
||||
}
|
||||
|
||||
handle range::begin()
|
||||
handle range::begin() const
|
||||
{
|
||||
return m_base;
|
||||
}
|
||||
|
||||
handle range::end()
|
||||
handle range::end() const
|
||||
{
|
||||
return m_base.add(m_size);
|
||||
}
|
||||
|
||||
std::size_t range::size()
|
||||
std::size_t range::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
bool range::contains(handle h)
|
||||
bool range::contains(handle h) const
|
||||
{
|
||||
return h.as<std::uintptr_t>() >= begin().as<std::uintptr_t>() && h.as<std::uintptr_t>() <= end().as<std::uintptr_t>();
|
||||
}
|
||||
@ -83,7 +83,7 @@ namespace memory
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
handle range::scan(pattern const& sig)
|
||||
handle range::scan(pattern const& sig) const
|
||||
{
|
||||
auto data = sig.m_bytes.data();
|
||||
auto length = sig.m_bytes.size();
|
||||
@ -109,7 +109,7 @@ namespace memory
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<handle> range::scan_all(pattern const& sig)
|
||||
std::vector<handle> range::scan_all(pattern const& sig) const
|
||||
{
|
||||
std::vector<handle> result{};
|
||||
auto data = sig.m_bytes.data();
|
||||
|
@ -11,14 +11,14 @@ namespace memory
|
||||
public:
|
||||
range(handle base, std::size_t size);
|
||||
|
||||
handle begin();
|
||||
handle end();
|
||||
std::size_t size();
|
||||
handle begin() const;
|
||||
handle end() const;
|
||||
std::size_t size() const;
|
||||
|
||||
bool contains(handle h);
|
||||
bool contains(handle h) const;
|
||||
|
||||
handle scan(pattern const& sig);
|
||||
std::vector<handle> scan_all(pattern const& sig);
|
||||
handle scan(pattern const& sig) const;
|
||||
std::vector<handle> scan_all(pattern const& sig) const;
|
||||
|
||||
protected:
|
||||
handle m_base;
|
||||
|
279
src/pointers.cpp
279
src/pointers.cpp
@ -11,7 +11,95 @@ std::uint64_t g_sound_overload_ret_addr;
|
||||
|
||||
namespace big
|
||||
{
|
||||
pointers::pointers()
|
||||
bool pointers::is_pointers_cache_up_to_date(memory::batch& version_batch, const memory::module& mem_region)
|
||||
{
|
||||
if (version_batch.run(mem_region))
|
||||
{
|
||||
m_pointers_cache.load();
|
||||
|
||||
if (m_pointers_cache.up_to_date(m_game_version_uint32_t, m_online_version_float))
|
||||
{
|
||||
LOG(INFO) << "Pointers cache is up to date, using it.";
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "Failed to find version patterns. Can't utilize pointers cache.";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: ideally the `ptr` in the lambdas should be stored in separate fields than the memory::byte_patch (ideally you'd move those memory::byte_patch away from the pointers class...)
|
||||
// So that the ptrs could be cached
|
||||
void pointers::always_run_main_batch(const memory::module& mem_region)
|
||||
{
|
||||
memory::batch main_batch;
|
||||
|
||||
// Max Wanted Level
|
||||
main_batch.add("MWL", "8B 43 6C 89 05", [this](memory::handle ptr) {
|
||||
m_max_wanted_level = memory::byte_patch::make(ptr.add(5).rip().as<uint32_t*>(), 0).get();
|
||||
m_max_wanted_level_2 = memory::byte_patch::make(ptr.add(14).rip().as<uint32_t*>(), 0).get();
|
||||
});
|
||||
|
||||
// Blame Explode
|
||||
main_batch.add("BE", "0F 85 ? ? ? ? 48 8B 05 ? ? ? ? 48 8B 48 08 E8", [this](memory::handle ptr) {
|
||||
m_blame_explode = memory::byte_patch::make(ptr.as<std::uint16_t*>(), 0xE990).get();
|
||||
});
|
||||
|
||||
//Patch blocked explosions
|
||||
main_batch.add("EP", "E8 ? ? ? ? 48 8D 4C 24 20 E8 ? ? ? ? 4C 8D 9C 24 80 01 00 00", [this](memory::handle ptr) {
|
||||
m_explosion_patch = memory::byte_patch::make(ptr.sub(12).as<uint16_t*>(), 0x9090).get();
|
||||
});
|
||||
|
||||
// Is Matchmaking Session Valid
|
||||
main_batch.add("IMSV", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 20 45 0F", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.as<void*>(), std::to_array({0xB0, 0x01, 0xC3}))->apply(); // has no observable side effects
|
||||
});
|
||||
|
||||
// Broadcast Net Array Patch
|
||||
main_batch.add("BP", "74 73 FF 90 ? ? ? ? 8B D5 4C 8B 00 48 8B C8 41 FF 50 30", [this](memory::handle ptr) {
|
||||
m_broadcast_patch = memory::byte_patch::make(ptr.as<uint8_t*>(), 0xEB).get();
|
||||
});
|
||||
|
||||
// Creator Warp Cheat Triggered Patch
|
||||
main_batch.add("CW", "74 44 E8 ? ? ? ? 80 65 2B F8 48 8D 0D ? ? ? ? 48 89 4D 17 48 89 7D 1F 89 7D 27 C7 45", [](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.as<uint8_t*>(), 0xEB)->apply();
|
||||
});
|
||||
|
||||
// NTQVM Caller
|
||||
main_batch.add("NTQVMC", "66 0F 6F 0D ? ? ? ? 66 0F 6F 05 ? ? ? ? 66 0F 66 C4", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.add(4).rip().sub(32).as<uint64_t*>(), (uint64_t)&hooks::nt_query_virtual_memory)
|
||||
->apply();
|
||||
});
|
||||
|
||||
// Sound Overload Detour
|
||||
main_batch.add("SOD", "66 45 3B C1 74 38", [this](memory::handle ptr) {
|
||||
g_sound_overload_ret_addr = ptr.add(13 + 15).as<decltype(g_sound_overload_ret_addr)>();
|
||||
std::vector<byte> bytes = {0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90}; // far jump opcode + a nop opcode
|
||||
*(void**)(bytes.data() + 6) = sound_overload_detour;
|
||||
memory::byte_patch::make(ptr.add(13).as<void*>(), bytes)->apply();
|
||||
});
|
||||
|
||||
// Disable Collision
|
||||
main_batch.add("DC", "48 8B D1 49 8B CA ? ? ? ? ? 48 8B D1 49 8B CA", [this](memory::handle ptr) {
|
||||
m_disable_collision = memory::byte_patch::make(ptr.sub(2).as<uint8_t*>(), 0xEB).get();
|
||||
});
|
||||
|
||||
// Crash Trigger
|
||||
main_batch.add("CT", "48 3B F8 74 ? 8B 1D", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.add(4).as<uint8_t*>(), 0x00)->apply();
|
||||
});
|
||||
|
||||
if (!main_batch.run(mem_region))
|
||||
{
|
||||
throw std::runtime_error("Failed to find some patterns.");
|
||||
}
|
||||
}
|
||||
|
||||
void pointers::run_cacheable_main_batch(const memory::module& mem_region)
|
||||
{
|
||||
memory::batch main_batch;
|
||||
|
||||
@ -25,12 +113,6 @@ namespace big
|
||||
m_region_code = ptr.add(16).rip().add(1).as<uint32_t*>();
|
||||
});
|
||||
|
||||
// Max Wanted Level
|
||||
main_batch.add("MWL", "8B 43 6C 89 05", [this](memory::handle ptr) {
|
||||
m_max_wanted_level = memory::byte_patch::make(ptr.add(5).rip().as<uint32_t*>(), 0).get();
|
||||
m_max_wanted_level_2 = memory::byte_patch::make(ptr.add(14).rip().as<uint32_t*>(), 0).get();
|
||||
});
|
||||
|
||||
// Game State
|
||||
main_batch.add("GS", "83 3D ? ? ? ? ? 75 17 8B 43 20 25", [this](memory::handle ptr) {
|
||||
m_game_state = ptr.add(2).rip().add(1).as<eGameState*>();
|
||||
@ -198,16 +280,6 @@ namespace big
|
||||
m_handle_to_ptr = ptr.as<decltype(m_handle_to_ptr)>();
|
||||
});
|
||||
|
||||
// Blame Explode
|
||||
main_batch.add("BE", "0F 85 ? ? ? ? 48 8B 05 ? ? ? ? 48 8B 48 08 E8", [this](memory::handle ptr) {
|
||||
m_blame_explode = memory::byte_patch::make(ptr.as<std::uint16_t*>(), 0xE990).get();
|
||||
});
|
||||
|
||||
//Patch blocked explosions
|
||||
main_batch.add("EP", "E8 ? ? ? ? 48 8D 4C 24 20 E8 ? ? ? ? 4C 8D 9C 24 80 01 00 00", [this](memory::handle ptr) {
|
||||
m_explosion_patch = memory::byte_patch::make(ptr.sub(12).as<uint16_t*>(), 0x9090).get();
|
||||
});
|
||||
|
||||
// CNetworkObjectMgr
|
||||
main_batch.add("CNOM", "48 8B 0D ? ? ? ? 45 33 C0 E8 ? ? ? ? 33 FF 4C 8B F0", [this](memory::handle ptr) {
|
||||
m_network_object_mgr = ptr.add(3).rip().as<CNetworkObjectMgr**>();
|
||||
@ -348,12 +420,6 @@ namespace big
|
||||
m_fipackfile_unmount = ptr.add(1).rip().as<functions::fipackfile_unmount>();
|
||||
});
|
||||
|
||||
// game version + online version
|
||||
main_batch.add("GVOV", "8B C3 33 D2 C6 44 24 20", [this](memory::handle ptr) {
|
||||
m_game_version = ptr.add(0x24).rip().as<const char*>();
|
||||
m_online_version = ptr.add(0x24).rip().add(0x20).as<const char*>();
|
||||
});
|
||||
|
||||
// Invalid Mods Crash Detour
|
||||
main_batch.add("IMCD", "E8 ? ? ? ? 40 88 7C 24 ? 49 89 9C 24", [this](memory::handle ptr) {
|
||||
m_invalid_mods_crash_detour = ptr.add(1).rip().as<PVOID>();
|
||||
@ -474,11 +540,6 @@ namespace big
|
||||
m_serialize_join_request_message = ptr.add(1).rip().as<PVOID>();
|
||||
});
|
||||
|
||||
// Is Matchmaking Session Valid
|
||||
main_batch.add("IMSV", "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 57 41 54 41 55 41 56 41 57 48 83 EC 20 45 0F", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.as<void*>(), std::to_array({0xB0, 0x01, 0xC3}))->apply(); // has no observable side effects
|
||||
});
|
||||
|
||||
// Send Network Damage
|
||||
main_batch.add("SND", "E8 ? ? ? ? E9 E9 01 00 00 48 8B CB", [this](memory::handle ptr) {
|
||||
m_send_network_damage = ptr.add(1).rip().as<functions::send_network_damage>();
|
||||
@ -510,11 +571,6 @@ namespace big
|
||||
m_broadcast_net_array = ptr.as<PVOID>();
|
||||
});
|
||||
|
||||
// Broadcast Net Array Patch
|
||||
main_batch.add("BP", "74 73 FF 90 ? ? ? ? 8B D5 4C 8B 00 48 8B C8 41 FF 50 30", [this](memory::handle ptr) {
|
||||
m_broadcast_patch = memory::byte_patch::make(ptr.as<uint8_t*>(), 0xEB).get();
|
||||
});
|
||||
|
||||
// Rage Security
|
||||
main_batch.add("RS", "48 8B 1D ? ? ? ? 33 F6 BD C3 9E 26 00", [this](memory::handle ptr) {
|
||||
m_security = ptr.add(3).rip().as<rage::atSingleton<rage::RageSecurity>*>();
|
||||
@ -545,11 +601,6 @@ namespace big
|
||||
m_create_script_handler = *(ptr.add(3).rip().as<std::uint64_t**>() + 8);
|
||||
});
|
||||
|
||||
// Creator Warp Cheat Triggered Patch
|
||||
main_batch.add("CW", "74 44 E8 ? ? ? ? 80 65 2B F8 48 8D 0D ? ? ? ? 48 89 4D 17 48 89 7D 1F 89 7D 27 C7 45", [](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.as<uint8_t*>(), 0xEB)->apply();
|
||||
});
|
||||
|
||||
// Constraint Attachment Crash
|
||||
main_batch.add("CAC", "40 53 48 83 EC 20 48 8B D9 48 8B 49 38 48 8B 01", [this](memory::handle ptr) {
|
||||
m_constraint_attachment_crash = ptr.as<PVOID>();
|
||||
@ -581,12 +632,6 @@ namespace big
|
||||
m_decode_peer_info = ptr.as<functions::decode_peer_info>();
|
||||
});
|
||||
|
||||
// NTQVM Caller
|
||||
main_batch.add("NTQVMC", "66 0F 6F 0D ? ? ? ? 66 0F 6F 05 ? ? ? ? 66 0F 66 C4", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.add(4).rip().sub(32).as<uint64_t*>(), (uint64_t)&hooks::nt_query_virtual_memory)
|
||||
->apply();
|
||||
});
|
||||
|
||||
// Main File Object
|
||||
main_batch.add("MFO", "48 8D 05 ? ? ? ? 48 8D 1C D0 EB 03", [this](memory::handle ptr) {
|
||||
m_main_file_object = ptr.add(3).rip().as<datafile_commands::SveFileObject*>();
|
||||
@ -627,14 +672,6 @@ namespace big
|
||||
m_interval_check_func = ptr.add(3).rip().as<PVOID>();
|
||||
});
|
||||
|
||||
// Sound Overload Detour
|
||||
main_batch.add("SOD", "66 45 3B C1 74 38", [this](memory::handle ptr) {
|
||||
g_sound_overload_ret_addr = ptr.add(13 + 15).as<decltype(g_sound_overload_ret_addr)>();
|
||||
std::vector<byte> bytes = {0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90}; // far jump opcode + a nop opcode
|
||||
*(void**)(bytes.data() + 6) = sound_overload_detour;
|
||||
memory::byte_patch::make(ptr.add(13).as<void*>(), bytes)->apply();
|
||||
});
|
||||
|
||||
// Prepare Metric For Sending
|
||||
main_batch.add("PMFS", "48 8B C4 48 89 58 08 48 89 68 10 48 89 70 18 48 89 78 20 41 56 48 83 EC 30 49 8B E8 4C 8D 40 EC 49 8B F1 48 8B D9 40 32 FF E8", [this](memory::handle ptr) {
|
||||
m_prepare_metric_for_sending = ptr.as<PVOID>();
|
||||
@ -731,21 +768,11 @@ namespace big
|
||||
m_refresh_audio_input = ptr.add(3).rip().as<bool*>();
|
||||
});
|
||||
|
||||
// Disable Collision
|
||||
main_batch.add("DC", "48 8B D1 49 8B CA ? ? ? ? ? 48 8B D1 49 8B CA", [this](memory::handle ptr) {
|
||||
m_disable_collision = memory::byte_patch::make(ptr.sub(2).as<uint8_t*>(), 0xEB).get();
|
||||
});
|
||||
|
||||
// Allow Weapons In Vehicle
|
||||
main_batch.add("AWIV", "49 8B 40 08 39 10", [this](memory::handle ptr) {
|
||||
m_allow_weapons_in_vehicle = ptr.sub(23).as<PVOID>();
|
||||
});
|
||||
|
||||
// Crash Trigger
|
||||
main_batch.add("CT", "48 3B F8 74 ? 8B 1D", [this](memory::handle ptr) {
|
||||
memory::byte_patch::make(ptr.add(4).as<uint8_t*>(), 0x00)->apply();
|
||||
});
|
||||
|
||||
// Write Vehicle Proximity Migration Data Node
|
||||
main_batch.add("WVPMDN", "48 89 4C 24 08 55 53 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 68 4C 8B A9", [this](memory::handle ptr) {
|
||||
m_write_vehicle_proximity_migration_data_node = ptr.as<PVOID>();
|
||||
@ -756,17 +783,19 @@ namespace big
|
||||
m_migrate_object = ptr.as<functions::migrate_object>();
|
||||
});
|
||||
|
||||
//Task Jump Constructor
|
||||
// Task Jump Constructor
|
||||
main_batch.add("TJC", "48 89 5C 24 ? 89 54 24 10 57 48 83 EC 30 0F 29 74 24", [this](memory::handle ptr) {
|
||||
m_taskjump_constructor = ptr.as<PVOID>();
|
||||
});
|
||||
|
||||
auto mem_region = memory::module("GTA5.exe");
|
||||
if (!main_batch.run(mem_region))
|
||||
{
|
||||
throw std::runtime_error("Failed to find some patterns.");
|
||||
}
|
||||
}
|
||||
|
||||
void pointers::run_socialclub_batch()
|
||||
{
|
||||
memory::batch socialclub_batch;
|
||||
|
||||
// Presence Data
|
||||
@ -788,10 +817,10 @@ namespace big
|
||||
}
|
||||
else
|
||||
LOG(WARNING) << "socialclub.dll module was not loaded within the time limit.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Freemode thread restorer through VM patch
|
||||
*/
|
||||
void pointers::freemode_thread_restorer_through_vm_patch(const memory::module& mem_region)
|
||||
{
|
||||
if (auto pat1 = mem_region.scan("3b 0a 0f 83 ? ? ? ? 48 ff c7"))
|
||||
{
|
||||
memory::byte_patch::make(pat1.add(2).as<uint32_t*>(), 0xc9310272)->apply();
|
||||
@ -817,6 +846,122 @@ namespace big
|
||||
memory::byte_patch::make(handle.add(2).as<uint32_t*>(), 0xd2310272)->apply();
|
||||
memory::byte_patch::make(handle.add(6).as<uint16_t*>(), 0x9090)->apply();
|
||||
}
|
||||
}
|
||||
|
||||
// Any change to the sigs should have this number bumped, especially if the existing offsets are changing
|
||||
// Note: you don't need to bump that number when all the sigs stay the same and that the game updates,
|
||||
// because we also check against the game version and the online version.
|
||||
constexpr uint32_t pointers_version = 1;
|
||||
|
||||
pointers::pointers() :
|
||||
m_pointers_cache(g_file_manager->get_project_file("./cache/pointers.bin"), pointers_version)
|
||||
{
|
||||
memory::batch version_batch;
|
||||
|
||||
// game version + online version
|
||||
version_batch.add("GVOV", "8B C3 33 D2 C6 44 24 20", [this](memory::handle ptr) {
|
||||
m_game_version = ptr.add(0x24).rip().as<const char*>();
|
||||
m_online_version = ptr.add(0x24).rip().add(0x20).as<const char*>();
|
||||
|
||||
m_game_version_uint32_t = std::strtoul(m_game_version, nullptr, 10);
|
||||
m_online_version_float = std::strtof(m_online_version, nullptr);
|
||||
});
|
||||
|
||||
const auto mem_region = memory::module("GTA5.exe");
|
||||
|
||||
// save offsets of the fields to cache
|
||||
|
||||
// get the beginning and the end of what we need to save / load
|
||||
constexpr size_t offset_of_cache_begin_field = offsetof(big::pointers, m_offset_gta_module_cache_start) + sizeof(uintptr_t);
|
||||
constexpr size_t offset_of_cache_end_field = offsetof(big::pointers, m_offset_gta_module_cache_end);
|
||||
constexpr size_t field_count = (offset_of_cache_end_field - offset_of_cache_begin_field) / sizeof(void*);
|
||||
|
||||
// stupid check to see if we are aligned, don't really guarantee that the for loop below will succeed
|
||||
static_assert(((offset_of_cache_end_field - offset_of_cache_begin_field) % sizeof(void*)) == 0, "not aligned, prolly mean that there are rogue non cacheable fields between start and end");
|
||||
|
||||
const uintptr_t pointer_to_cacheable_data_start = reinterpret_cast<uintptr_t>(this) + offset_of_cache_begin_field;
|
||||
const uintptr_t pointer_to_cacheable_data_end = reinterpret_cast<uintptr_t>(this) + offset_of_cache_end_field;
|
||||
|
||||
if (!is_pointers_cache_up_to_date(version_batch, mem_region))
|
||||
{
|
||||
run_cacheable_main_batch(mem_region);
|
||||
|
||||
constexpr size_t data_size = offset_of_cache_end_field - offset_of_cache_begin_field;
|
||||
|
||||
big::cache_data cache_data_ptr = std::make_unique<std::uint8_t[]>(data_size);
|
||||
|
||||
// multiple things here:
|
||||
// - iterate each cacheable field of the pointers instance
|
||||
// - substract the base module address so that we only keep the offsets
|
||||
// - save that to the cache
|
||||
uintptr_t* cache_data = reinterpret_cast<uintptr_t*>(cache_data_ptr.get());
|
||||
|
||||
size_t i = 0;
|
||||
for (uintptr_t field_ptr = pointer_to_cacheable_data_start; field_ptr != pointer_to_cacheable_data_end; field_ptr += sizeof(uintptr_t))
|
||||
{
|
||||
const uintptr_t field_value = *reinterpret_cast<uintptr_t*>(field_ptr);
|
||||
|
||||
if (mem_region.contains(memory::handle(field_value)))
|
||||
{
|
||||
const uintptr_t offset = field_value - mem_region.begin().as<uintptr_t>();
|
||||
cache_data[i] = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(FATAL) << "Just tried to save to cache a pointer supposedly within the gta 5 module range but wasnt!!! Offset from start of pointers instance: " << (field_ptr - reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Pointers cache: saved " << (data_size / sizeof(uintptr_t)) << " fields to the cache";
|
||||
|
||||
m_pointers_cache.set_data(std::move(cache_data_ptr), data_size);
|
||||
|
||||
m_pointers_cache.set_header_version(m_game_version_uint32_t, m_online_version_float);
|
||||
m_pointers_cache.write();
|
||||
}
|
||||
else
|
||||
{
|
||||
// fill pointers instance fields by reading the file data into it
|
||||
|
||||
LOG(INFO) << "Loading pointers instance from cache";
|
||||
|
||||
// multiple things here:
|
||||
// - iterate each cacheable field of the pointers instance
|
||||
// - add the base module address to the current offset retrieved from the cache
|
||||
// - assign that ptr to the pointers field
|
||||
uintptr_t* cache_data = reinterpret_cast<uintptr_t*>(m_pointers_cache.data());
|
||||
|
||||
const size_t field_count_from_cache = m_pointers_cache.data_size() / sizeof(uintptr_t);
|
||||
LOG(INFO) << "Pointers cache: Loading " << field_count_from_cache << " fields from the cache";
|
||||
|
||||
uintptr_t* field_ptr = reinterpret_cast<uintptr_t*>(pointer_to_cacheable_data_start);
|
||||
for (size_t i = 0; i < field_count_from_cache; i++)
|
||||
{
|
||||
uintptr_t offset = cache_data[i];
|
||||
uintptr_t gta_module_ptr = offset + mem_region.begin().as<uintptr_t>();
|
||||
|
||||
if (mem_region.contains(memory::handle(gta_module_ptr)))
|
||||
{
|
||||
*field_ptr = gta_module_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(FATAL) << "Just tried to load from cache a pointer supposedly within the gta 5 module range but wasnt!!! Offset from start of pointers instance: " << (reinterpret_cast<uintptr_t>(field_ptr) - reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
field_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
m_pointers_cache.free();
|
||||
|
||||
always_run_main_batch(mem_region);
|
||||
|
||||
run_socialclub_batch();
|
||||
|
||||
freemode_thread_restorer_through_vm_patch(mem_region);
|
||||
|
||||
m_hwnd = FindWindowW(L"grcWindow", nullptr);
|
||||
|
||||
|
@ -4,7 +4,10 @@
|
||||
#include "function_types.hpp"
|
||||
#include "gta/fwddec.hpp"
|
||||
#include "gta/replay.hpp"
|
||||
#include "memory/batch.hpp"
|
||||
#include "memory/byte_patch.hpp"
|
||||
#include "memory/module.hpp"
|
||||
#include "services/gta_data/cache_file.hpp"
|
||||
#include "socialclub/ScInfo.hpp"
|
||||
|
||||
class CCommunications;
|
||||
@ -26,15 +29,56 @@ extern "C" std::uint64_t g_sound_overload_ret_addr;
|
||||
|
||||
namespace big
|
||||
{
|
||||
// needed for serialization of the pointers cache
|
||||
#pragma pack(push, 1)
|
||||
class pointers
|
||||
{
|
||||
private:
|
||||
bool is_pointers_cache_up_to_date(memory::batch& version_batch, const memory::module& mem_region);
|
||||
|
||||
// we can't cache things like pointers we allocate on the heap
|
||||
void always_run_main_batch(const memory::module& mem_region);
|
||||
|
||||
void run_cacheable_main_batch(const memory::module& mem_region);
|
||||
|
||||
void run_socialclub_batch();
|
||||
|
||||
void freemode_thread_restorer_through_vm_patch(const memory::module& mem_region);
|
||||
|
||||
public:
|
||||
explicit pointers();
|
||||
~pointers();
|
||||
|
||||
private:
|
||||
cache_file m_pointers_cache;
|
||||
|
||||
public:
|
||||
HWND m_hwnd{};
|
||||
|
||||
memory::byte_patch* m_max_wanted_level;
|
||||
memory::byte_patch* m_max_wanted_level_2;
|
||||
|
||||
memory::byte_patch* m_blame_explode;
|
||||
memory::byte_patch* m_explosion_patch;
|
||||
|
||||
memory::byte_patch* m_disable_collision{};
|
||||
|
||||
memory::byte_patch* m_broadcast_patch;
|
||||
|
||||
uint32_t m_game_version_uint32_t;
|
||||
float m_online_version_float;
|
||||
|
||||
// Pointers inside social club module START
|
||||
PVOID m_update_presence_attribute_int;
|
||||
PVOID m_update_presence_attribute_string;
|
||||
|
||||
functions::start_get_presence_attributes m_start_get_presence_attributes;
|
||||
// Pointers inside social club module END
|
||||
|
||||
// don't remove, used for signaling the start of the pointers gta module offset cache
|
||||
// Note: between the start and the end, only pointers coming from the gta 5 module should be in there
|
||||
void* m_offset_gta_module_cache_start;
|
||||
|
||||
eGameState* m_game_state{};
|
||||
bool* m_is_session_started{};
|
||||
|
||||
@ -63,11 +107,6 @@ namespace big
|
||||
|
||||
uint32_t* m_region_code;
|
||||
|
||||
memory::byte_patch* m_max_wanted_level;
|
||||
memory::byte_patch* m_max_wanted_level_2;
|
||||
|
||||
memory::byte_patch* m_blame_explode;
|
||||
memory::byte_patch* m_explosion_patch;
|
||||
PVOID m_world_model_spawn_bypass;
|
||||
PVOID m_native_return;
|
||||
PVOID m_get_label_text;
|
||||
@ -120,7 +159,6 @@ namespace big
|
||||
functions::get_sync_tree_for_type m_get_sync_tree_for_type{};
|
||||
functions::get_sync_type_info m_get_sync_type_info{};
|
||||
functions::get_net_object m_get_net_object{};
|
||||
functions::get_net_object_for_player m_get_net_object_for_player{};
|
||||
functions::read_bitbuffer_into_sync_tree m_read_bitbuffer_into_sync_tree{};
|
||||
//Sync Signatures END
|
||||
|
||||
@ -132,7 +170,6 @@ namespace big
|
||||
|
||||
functions::start_get_session_by_gamer_handle m_start_get_session_by_gamer_handle;
|
||||
functions::start_matchmaking_find_sessions m_start_matchmaking_find_sessions;
|
||||
functions::start_get_presence_attributes m_start_get_presence_attributes;
|
||||
functions::join_session_by_info m_join_session_by_info;
|
||||
|
||||
functions::reset_network_complaints m_reset_network_complaints{};
|
||||
@ -166,9 +203,6 @@ namespace big
|
||||
rage::rlGamerInfo* m_player_info_gamer_info{}; // the gamer info that is applied to CPlayerInfo
|
||||
CCommunications** m_communications{};
|
||||
|
||||
PVOID m_update_presence_attribute_int;
|
||||
PVOID m_update_presence_attribute_string;
|
||||
|
||||
PVOID m_serialize_ped_inventory_data_node;
|
||||
PVOID m_serialize_vehicle_gadget_data_node;
|
||||
functions::get_vehicle_gadget_array_size m_get_vehicle_gadget_array_size;
|
||||
@ -199,7 +233,6 @@ namespace big
|
||||
functions::handle_remove_gamer_cmd m_handle_remove_gamer_cmd{};
|
||||
|
||||
PVOID m_broadcast_net_array{};
|
||||
memory::byte_patch* m_broadcast_patch;
|
||||
|
||||
rage::atSingleton<rage::RageSecurity>* m_security;
|
||||
PVOID m_prepare_metric_for_sending;
|
||||
@ -254,14 +287,17 @@ namespace big
|
||||
PVOID m_direct_sound_capture_create{};
|
||||
bool* m_refresh_audio_input{};
|
||||
|
||||
memory::byte_patch* m_disable_collision{};
|
||||
PVOID m_allow_weapons_in_vehicle{};
|
||||
|
||||
PVOID m_taskjump_constructor{};
|
||||
|
||||
PVOID m_write_vehicle_proximity_migration_data_node{};
|
||||
functions::migrate_object m_migrate_object{};
|
||||
|
||||
// don't remove, used for signaling the end of the pointers gta module offset cache
|
||||
void* m_offset_gta_module_cache_end;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
inline pointers* g_pointers{};
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
#include "pugixml.hpp"
|
||||
#include "script.hpp"
|
||||
#include "thread_pool.hpp"
|
||||
#include "util/session.hpp"
|
||||
#include "yim_fipackfile.hpp"
|
||||
#include "util/vehicle.hpp"
|
||||
#include "util/misc.hpp"
|
||||
#include "util/model_info.hpp"
|
||||
#include "util/session.hpp"
|
||||
#include "util/vehicle.hpp"
|
||||
#include "yim_fipackfile.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -142,8 +142,8 @@ namespace big
|
||||
m_vehicles_cache.load();
|
||||
m_weapons_cache.load();
|
||||
|
||||
const auto game_version = std::strtoul(g_pointers->m_game_version, nullptr, 10);
|
||||
const auto online_version = std::strtof(g_pointers->m_online_version, nullptr);
|
||||
const auto game_version = g_pointers->m_game_version_uint32_t;
|
||||
const auto online_version = g_pointers->m_online_version_float;
|
||||
|
||||
return m_peds_cache.up_to_date(game_version, online_version) && m_vehicles_cache.up_to_date(game_version, online_version)
|
||||
&& m_weapons_cache.up_to_date(game_version, online_version);
|
||||
@ -484,8 +484,8 @@ namespace big
|
||||
|
||||
LOG(VERBOSE) << "Starting cache saving procedure...";
|
||||
g_thread_pool->push([this, peds = std::move(peds), vehicles = std::move(vehicles), weapons = std::move(weapons)] {
|
||||
const auto game_version = std::strtoul(g_pointers->m_game_version, nullptr, 10);
|
||||
const auto online_version = std::strtof(g_pointers->m_online_version, nullptr);
|
||||
const auto game_version = g_pointers->m_game_version_uint32_t;
|
||||
const auto online_version = g_pointers->m_online_version_float;
|
||||
|
||||
{
|
||||
const auto data_size = sizeof(ped_item) * peds.size();
|
||||
|
Loading…
x
Reference in New Issue
Block a user