Locals editor (#1211)

This commit is contained in:
DayibBaba
2023-04-11 21:36:43 +02:00
committed by GitHub
parent 83ad7d65ae
commit 31d2db48df
3 changed files with 402 additions and 0 deletions

View File

@ -0,0 +1,126 @@
#include "locals_service.hpp"
#include "core/data/all_script_names.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "fiber_pool.hpp"
namespace big
{
bool locals_service::is_script_thread_running(GtaThread* thread)
{
if (thread)
{
return thread->m_context.m_state == rage::eThreadState::running || thread->m_context.m_state == rage::eThreadState::idle;
}
return false;
}
bool locals_service::does_script_exist(std::string script_name)
{
for (auto s : all_script_names)
if (script_name == s)
return true;
bool script_exists = false;
g_fiber_pool->queue_job([&] {script_exists = SCRIPT::DOES_SCRIPT_EXIST(script_name.data());});
return script_exists;
}
std::filesystem::path locals_service::get_path()
{
return g_file_manager->get_project_file("locals.json").get_path();
}
bool locals_service::load()
{
std::ifstream file(locals_service::get_path());
if (!file.is_open())
return false;
try
{
nlohmann::json j;
file >> j;
m_locals.clear();
for (const auto& l : j.items())
{
if (!l.key().empty())
{
local new_local{"", "", 0, 0, 0, 0};
new_local.m_base_address = j[l.key()]["base_address"];
std::string script_name = j[l.key()]["script_thread_name"];
strcpy(new_local.m_script_thread_name, script_name.data());
new_local.m_freeze = j[l.key()]["freeze"];
std::string name = j[l.key()]["name"];
strcpy(new_local.m_name, name.data());
new_local.m_value = j[l.key()]["value"];
if (!j[l.key()]["offsets"].is_null())
{
for (const auto& offset : j[l.key()]["offsets"].items())
{
if (!offset.key().empty())
{
local_offset new_offset{0, 0};
new_offset.m_offset = j[l.key()]["offsets"][offset.key()]["offset"];
if (!j[l.key()]["offsets"][offset.key()]["size"].is_null())
new_offset.m_size = j[l.key()]["offsets"][offset.key()]["size"];
new_local.m_offsets.push_back(new_offset);
}
}
}
new_local.fetch_local_pointer();
m_locals.push_back(new_local);
}
}
}
catch (const std::exception&)
{
LOG(WARNING) << "Failure to parse locals.json, aborting...";
return false;
}
return true;
}
void locals_service::save()
{
std::map<std::string, local> locals_with_names;
for (auto& l : m_locals)
{
locals_with_names.insert(std::pair<std::string, local>(std::string(l.m_name).empty() ? std::string(l.m_script_thread_name + std::string("_") + std::to_string(l.m_base_address)) : l.m_name, l));
}
nlohmann::json j;
for (auto& l : locals_with_names)
{
j[l.first]["script_thread_name"] = l.second.m_script_thread_name;
j[l.first]["base_address"] = l.second.m_base_address;
j[l.first]["freeze"] = l.second.m_freeze;
j[l.first]["name"] = l.second.m_name;
j[l.first]["value"] = l.second.m_value;
for (int i = 0; i < l.second.m_offsets.size(); i++)
{
j[l.first]["offsets"][std::to_string(i)]["offset"] = l.second.m_offsets[i].m_offset;
if (l.second.m_offsets[i].m_size > 0)
j[l.first]["offsets"][std::to_string(i)]["size"] = l.second.m_offsets[i].m_size;
};
}
std::ofstream file(locals_service::get_path(), std::ios::out | std::ios::trunc);
try
{
file << j.dump(4);
file.close();
}
catch (const std::exception&)
{
LOG(WARNING) << "Failed to write to locals.json";
}
}
};

View File

@ -0,0 +1,104 @@
#pragma once
#include "file_manager.hpp"
#include "file_manager/file.hpp"
#include "gta/script_thread.hpp"
#include "gta_util.hpp"
#include "script_local.hpp"
namespace big
{
struct local_offset
{
local_offset(int offset, int size = 0)
{
m_offset = offset;
if (size)
m_size = size;
}
int m_offset = 0;
int m_size = 0;
};
struct local
{
GtaThread* m_script_thread;
char m_script_thread_name[200];
int m_base_address;
bool m_freeze = false;
char m_name[200];
std::vector<local_offset> m_offsets;
int m_value;
int m_freeze_value;
int* m_internal_address;
local(const char* script_thread_name, const char* name, const int base_address, const bool freeze, const int (*offsets)[2], int offset_count)
{
m_internal_id = ++m_instance_count;
strcpy(m_script_thread_name, script_thread_name);
m_base_address = base_address;
m_freeze = freeze;
strcpy(m_name, name);
m_value = 0;
for (int i = 0; i < offset_count; i++)
m_offsets.push_back(local_offset(offsets[i][0], offsets[i][1]));
fetch_local_pointer();
}
int get_id() const
{
return m_internal_id;
}
int* fetch_local_pointer()
{
m_script_thread = gta_util::find_script_thread(rage::joaat(m_script_thread_name));
if (m_script_thread)
{
script_local actual_local = script_local(m_script_thread, m_base_address);
for (auto offset : m_offsets)
{
if (offset.m_size > 0)
actual_local = actual_local.at(offset.m_offset, offset.m_size);
else
actual_local = actual_local.at(offset.m_offset);
}
m_internal_address = actual_local.as<int*>();
return m_internal_address;
}
return nullptr;
}
private:
inline static int m_instance_count;
int m_internal_id;
};
class locals_service
{
public:
std::filesystem::path get_path();
bool load();
void save();
static bool does_script_exist(std::string script);
static bool is_script_thread_running(GtaThread* thread);
std::vector<local> m_locals;
bool m_running = false;
};
inline locals_service g_locals_service{};
}