Files
TmpMenu/src/services/tunables/tunables_service.cpp
Andreas Maerten 88036b91da refactor: switch RAGE_JOAAT with string literal functions (#2806)
Why? Shorter to write and removes the macro usage

I used the following regex to find all occurrences:
```r
RAGE_JOAAT\("(.*?)"\)
```
then the following to replace it all:
```r
"$1"_J
```
2024-03-12 09:42:11 +01:00

133 lines
3.6 KiB
C++

#include "tunables_service.hpp"
#include "memory/module.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "script.hpp"
#include "services/script_connection/script_connection_service.hpp" // for the stack size
#include "services/script_patcher/script_patcher_service.hpp"
#include "thread_pool.hpp"
#include "util/scripts.hpp"
namespace big
{
tunables_service::tunables_service() :
m_cache_file(g_file_manager.get_project_file("./cache/tunables.bin"), 1)
{
g_tunables_service = this;
}
tunables_service::~tunables_service()
{
m_loading = false;
g_tunables_service = nullptr;
}
void tunables_service::run_script()
{
while (true)
{
script::get_current()->yield();
m_cache_file.load();
if (m_cache_file.up_to_date(memory::module("GTA5.exe").size()))
{
LOG(INFO) << "Loading tunables from cache";
m_loading = true;
load();
}
if (m_initialized || m_loading)
return;
if (!m_script_started && SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("tuneables_processing"_J) > 0)
continue;
if (!m_script_started)
{
SCRIPT::REQUEST_SCRIPT_WITH_NAME_HASH("tuneables_processing"_J);
if (SCRIPT::HAS_SCRIPT_WITH_NAME_HASH_LOADED("tuneables_processing"_J))
{
uint64_t args[] = {6, 27}; // TODO: check args
int id = SYSTEM::START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS("tuneables_processing"_J, (Any*)args, sizeof(args) / 8, DEFAULT_STACK_SIZE);
if (!id)
{
LOG(FATAL) << "Failed to start tuneables_processing. Cannot cache tunables";
return;
}
SCRIPT::SET_SCRIPT_WITH_NAME_HASH_AS_NO_LONGER_NEEDED("tuneables_processing"_J);
m_script_started = true;
g_script_patcher_service->add_patch({"tuneables_processing"_J, "tuneables_processing1", "2E ? ? 55 ? ? 38 06", 0, std::vector<uint8_t>(17, 0x0), &m_script_started}); // bool tunables registration hack
if (auto program = gta_util::find_script_program("tuneables_processing"_J))
g_script_patcher_service->on_script_load(program);
}
}
else
{
if (SCRIPT::GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH("tuneables_processing"_J) == 0)
{
if (m_tunables.size() == 0)
{
LOG(FATAL) << "Failed to cache tunables";
g_script_patcher_service->update();
return;
}
m_script_started = false;
m_initialized = true;
LOG(INFO) << "Saving " << m_tunables.size() << " tunables to cache";
g_script_patcher_service->update();
save();
}
}
}
}
void tunables_service::save()
{
auto data_size = sizeof(uint32_t) + sizeof(tunable_save_struct) * m_tunables.size();
auto data = std::make_unique<uint8_t[]>(data_size);
auto data_ptr = data.get();
*(uint32_t*)data_ptr = m_tunables.size();
data_ptr += sizeof(uint32_t);
for (auto& [hash, ptr] : m_tunables)
{
auto save_struct = (tunable_save_struct*)data_ptr;
save_struct->hash = hash;
save_struct->offset = ((std::int64_t*)ptr) - g_pointers->m_gta.m_script_globals[1];
data_ptr += sizeof(tunable_save_struct);
}
m_cache_file.set_header_version(memory::module("GTA5.exe").size());
m_cache_file.set_data(std::move(data), data_size);
m_cache_file.write();
}
void tunables_service::load()
{
auto data = m_cache_file.data();
auto num_tunables = *(uint32_t*)data;
data += sizeof(uint32_t);
for (int i = 0; i < num_tunables; i++)
{
auto save_struct = (tunable_save_struct*)data;
m_tunables.emplace(save_struct->hash, (void*)(g_pointers->m_gta.m_script_globals[1] + save_struct->offset));
data += sizeof(tunable_save_struct);
}
m_initialized = true;
m_loading = false;
}
}