mirror of
https://github.com/Mr-X-GTA/YimMenu.git
synced 2025-01-04 00:23:27 +08:00
133 lines
4.3 KiB
C++
133 lines
4.3 KiB
C++
#pragma once
|
|
#include "base/HashTable.hpp"
|
|
#include "function_types.hpp"
|
|
#include "gta/fwddec.hpp"
|
|
#include "gta_pointers.hpp"
|
|
#include "memory/batch.hpp"
|
|
#include "memory/byte_patch.hpp"
|
|
#include "memory/module.hpp"
|
|
#include "sc_pointers.hpp"
|
|
#include "services/gta_data/cache_file.hpp"
|
|
#include "socialclub/ScInfo.hpp"
|
|
#include "util/compile_time_helpers.hpp"
|
|
|
|
namespace big
|
|
{
|
|
class pointers
|
|
{
|
|
private:
|
|
template<cstxpr_str batch_name, auto batch_hash, size_t offset_of_cache_begin_field, size_t offset_of_cache_end_field, memory::batch batch>
|
|
void write_to_cache_or_read_from_cache(cache_file& cache_file, const memory::module& mem_region)
|
|
{
|
|
static_assert(batch_hash > 0);
|
|
|
|
constexpr size_t field_count = (offset_of_cache_end_field - offset_of_cache_begin_field) / sizeof(void*);
|
|
constexpr auto cache_version = batch_hash + field_count;
|
|
|
|
cache_file.set_cache_version(cache_version);
|
|
|
|
const uintptr_t pointer_to_cacheable_data_start = reinterpret_cast<uintptr_t>(this) + offset_of_cache_begin_field;
|
|
|
|
if (!is_pointers_cache_up_to_date<batch_name>(cache_file, mem_region))
|
|
{
|
|
run_batch<batch_name>(batch, mem_region);
|
|
|
|
const uintptr_t pointer_to_cacheable_data_end = reinterpret_cast<uintptr_t>(this) + offset_of_cache_end_field;
|
|
write_pointers_to_cache<batch_name, offset_of_cache_begin_field, offset_of_cache_end_field>(cache_file, pointer_to_cacheable_data_start, pointer_to_cacheable_data_end, mem_region);
|
|
}
|
|
else
|
|
{
|
|
load_pointers_from_cache(cache_file, pointer_to_cacheable_data_start, mem_region);
|
|
}
|
|
|
|
cache_file.free();
|
|
}
|
|
|
|
void load_pointers_from_cache(const cache_file& cache_file, const uintptr_t pointer_to_cacheable_data_start, const memory::module& mem_region);
|
|
|
|
template<cstxpr_str batch_name, size_t offset_of_cache_begin_field, size_t offset_of_cache_end_field>
|
|
void write_pointers_to_cache(cache_file& cache_file, const uintptr_t pointer_to_cacheable_data_start, const uintptr_t pointer_to_cacheable_data_end, const memory::module& mem_region)
|
|
{
|
|
constexpr size_t data_size = offset_of_cache_end_field - offset_of_cache_begin_field;
|
|
|
|
cache_data cache_data_ptr = std::make_unique<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 " << batch_name.str << " module range but isn't! 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";
|
|
|
|
cache_file.set_data(std::move(cache_data_ptr), data_size);
|
|
|
|
cache_file.set_header_version(mem_region.timestamp());
|
|
cache_file.write();
|
|
}
|
|
|
|
template<cstxpr_str batch_name>
|
|
bool is_pointers_cache_up_to_date(cache_file& cache_file, const memory::module& mem_region)
|
|
{
|
|
cache_file.load();
|
|
|
|
if (cache_file.up_to_date(mem_region.timestamp()))
|
|
{
|
|
LOG(INFO) << batch_name.str << " pointers cache is up to date, using it.";
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static constexpr auto get_gta_batch();
|
|
static constexpr auto get_sc_batch();
|
|
|
|
template<cstxpr_str batch_name, size_t N>
|
|
void run_batch(const memory::batch<N>& batch, const memory::module& mem_region)
|
|
{
|
|
if (!memory::batch_runner::run(batch, mem_region))
|
|
{
|
|
const std::string error_message =
|
|
std::string("Failed to find some patterns for ") + std::string(batch_name.str);
|
|
throw std::runtime_error(error_message);
|
|
}
|
|
}
|
|
|
|
public:
|
|
explicit pointers();
|
|
~pointers();
|
|
|
|
private:
|
|
cache_file m_gta_pointers_cache;
|
|
cache_file m_sc_pointers_cache;
|
|
|
|
public:
|
|
HWND m_hwnd{};
|
|
|
|
gta_pointers m_gta;
|
|
socialclub_pointers m_sc;
|
|
};
|
|
|
|
inline pointers* g_pointers{};
|
|
}
|