feat(Pointers): add cache for pointers (#1203)

This commit is contained in:
Quentin E. / iDeath 2023-04-06 20:01:23 +02:00 committed by GitHub
parent 38ba68e0e5
commit a2dbddc702
6 changed files with 294 additions and 113 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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