feat(Debug): Added global debugging tab
This commit is contained in:
parent
96f04d762b
commit
0564af724e
@ -53,6 +53,7 @@
|
|||||||
#include "core/globals.hpp"
|
#include "core/globals.hpp"
|
||||||
#include "CPed.hpp"
|
#include "CPed.hpp"
|
||||||
|
|
||||||
|
#include "services/globals_service.hpp"
|
||||||
#include "services/vehicle_service.hpp"
|
#include "services/vehicle_service.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "debug_tabs.hpp"
|
#include "debug_tabs.hpp"
|
||||||
|
#include "services/globals_service.hpp"
|
||||||
|
#include "thread_pool.hpp"
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
@ -6,7 +8,55 @@ namespace big
|
|||||||
{
|
{
|
||||||
if (ImGui::BeginTabItem("Globals"))
|
if (ImGui::BeginTabItem("Globals"))
|
||||||
{
|
{
|
||||||
ImGui::Text("Coming soon...");
|
if (ImGui::Checkbox("Enable Freezing", &g_globals_service->m_running) && !g_globals_service->m_running)
|
||||||
|
g_thread_pool->push([&]() { g_globals_service->loop(); });
|
||||||
|
|
||||||
|
if (ImGui::Button("Load"))
|
||||||
|
g_globals_service->load();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
g_globals_service->save();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Add Global"))
|
||||||
|
{
|
||||||
|
ImGui::OpenPopup("New Global");
|
||||||
|
}
|
||||||
|
|
||||||
|
modal_debug::modal_new_global();
|
||||||
|
|
||||||
|
for (auto& global : g_globals_service->m_globals)
|
||||||
|
{
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
char label[64];
|
||||||
|
sprintf(label, "Freeze###freeze_%d", global.m_base_address);
|
||||||
|
ImGui::Checkbox(label, &global.m_freeze);
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::Text(global.m_name.c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
sprintf(label, "###input_%d", global.m_base_address);
|
||||||
|
ImGui::PushItemWidth(200.f);
|
||||||
|
ImGui::InputInt(label, global.get());
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
sprintf(label, "Write###btn_%d", global.m_base_address);
|
||||||
|
if (ImGui::Button(label))
|
||||||
|
global.write();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
sprintf(label, "Delete##delet_%d", global.m_base_address);
|
||||||
|
if (ImGui::Button(label))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_globals_service->m_globals.size(); i++)
|
||||||
|
if (const auto& it = g_globals_service->m_globals.at(i); it.m_base_address == global.m_base_address && it.m_name == global.m_name)
|
||||||
|
g_globals_service->m_globals.erase(g_globals_service->m_globals.begin() + i);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,13 @@
|
|||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
class tab_debug {
|
struct modal_debug
|
||||||
public:
|
{
|
||||||
|
static void modal_new_global();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tab_debug
|
||||||
|
{
|
||||||
static void tab_globals();
|
static void tab_globals();
|
||||||
static void tab_script_events();
|
static void tab_script_events();
|
||||||
static void _tab_debug();
|
static void _tab_debug();
|
||||||
|
97
BigBaseV2/src/gui/window/dbg/modals/new_globals.cpp
Normal file
97
BigBaseV2/src/gui/window/dbg/modals/new_globals.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "../debug_tabs.hpp"
|
||||||
|
#include "fiber_pool.hpp"
|
||||||
|
#include "thread_pool.hpp"
|
||||||
|
#include "natives.hpp"
|
||||||
|
#include "script.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
void modal_debug::modal_new_global()
|
||||||
|
{
|
||||||
|
ImGui::SetNextWindowSize({ 520, 325 }, ImGuiCond_FirstUseEver);
|
||||||
|
if (ImGui::BeginPopupModal("New Global"))
|
||||||
|
{
|
||||||
|
static int base_address = 0;
|
||||||
|
static bool freeze = false;
|
||||||
|
static char name[32] = "";
|
||||||
|
static int (*offsets)[2] = nullptr;
|
||||||
|
static int offset_count = 0;
|
||||||
|
static int previous_offset_count = 0;
|
||||||
|
|
||||||
|
QUEUE_JOB_BEGIN_CLAUSE()
|
||||||
|
{
|
||||||
|
PAD::DISABLE_ALL_CONTROL_ACTIONS(0);
|
||||||
|
}QUEUE_JOB_END_CLAUSE
|
||||||
|
|
||||||
|
ImGui::Text("Name:");
|
||||||
|
ImGui::InputText("##modal_global_name", name, sizeof(name));
|
||||||
|
ImGui::Text("Base Address:");
|
||||||
|
ImGui::InputInt("##modal_global_base_addr", &base_address);
|
||||||
|
ImGui::Text("Freeze:");
|
||||||
|
ImGui::Checkbox("##modal_global_freeze", &freeze);
|
||||||
|
ImGui::Text("Number of Offsets:");
|
||||||
|
ImGui::InputInt("##modal_offset_count", &offset_count);
|
||||||
|
|
||||||
|
if (offset_count < 0) offset_count;
|
||||||
|
else if (offset_count > 10) offset_count = 10;
|
||||||
|
|
||||||
|
if (offset_count != previous_offset_count)
|
||||||
|
{
|
||||||
|
int(*new_offsets)[2] = new int[offset_count][2]{ 0 };
|
||||||
|
memcpy(new_offsets, offsets, sizeof(int) * std::min(offset_count, previous_offset_count) * 2);
|
||||||
|
|
||||||
|
delete[] offsets;
|
||||||
|
offsets = new_offsets;
|
||||||
|
|
||||||
|
previous_offset_count = offset_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(320.f);
|
||||||
|
for (int i = 0; i < offset_count; i++)
|
||||||
|
{
|
||||||
|
char id[32];
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::Text("Offset: %d", i + 1);
|
||||||
|
|
||||||
|
sprintf(id, "##offset_%d", i);
|
||||||
|
ImGui::InputInt(id, &offsets[i][0]);
|
||||||
|
|
||||||
|
ImGui::Text("Size:");
|
||||||
|
ImGui::SameLine();
|
||||||
|
sprintf(id, "##size_%d", i);
|
||||||
|
ImGui::InputInt(id, &offsets[i][1]);
|
||||||
|
}
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
if (ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
strcpy(name, "");
|
||||||
|
freeze = false;
|
||||||
|
delete[] offsets;
|
||||||
|
offsets = nullptr;
|
||||||
|
offset_count = 0;
|
||||||
|
previous_offset_count = 0;
|
||||||
|
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
g_globals_service->m_globals.push_back(global(name, base_address, freeze, offsets, offset_count));
|
||||||
|
|
||||||
|
strcpy(name, "");
|
||||||
|
freeze = false;
|
||||||
|
delete[] offsets;
|
||||||
|
offsets = nullptr;
|
||||||
|
offset_count = 0;
|
||||||
|
previous_offset_count = 0;
|
||||||
|
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -51,6 +51,8 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
|||||||
g_hooking->enable();
|
g_hooking->enable();
|
||||||
LOG(INFO) << "Hooking enabled.";
|
LOG(INFO) << "Hooking enabled.";
|
||||||
|
|
||||||
|
LOG(INFO) << "Registering service instances...";
|
||||||
|
auto globals_service_instace = std::make_unique<globals_service>();
|
||||||
auto vehicle_service_instance = std::make_unique<vehicle_service>();
|
auto vehicle_service_instance = std::make_unique<vehicle_service>();
|
||||||
|
|
||||||
while (g_running)
|
while (g_running)
|
||||||
@ -58,6 +60,12 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
|||||||
std::this_thread::sleep_for(500ms);
|
std::this_thread::sleep_for(500ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Serviceses uninitialized.";
|
||||||
|
vehicle_service_instance.reset();
|
||||||
|
globals_service_instace.reset();
|
||||||
|
|
||||||
|
// Make sure that all threads created don't have any blocking loops
|
||||||
|
// otherwise make sure that they have stopped executing
|
||||||
g_thread_pool->destroy();
|
g_thread_pool->destroy();
|
||||||
LOG(INFO) << "Destroyed thread pool.";
|
LOG(INFO) << "Destroyed thread pool.";
|
||||||
|
|
||||||
@ -83,8 +91,6 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
|||||||
|
|
||||||
pointers_instance.reset();
|
pointers_instance.reset();
|
||||||
LOG(INFO) << "Pointers uninitialized.";
|
LOG(INFO) << "Pointers uninitialized.";
|
||||||
|
|
||||||
vehicle_service_instance.reset();
|
|
||||||
}
|
}
|
||||||
catch (std::exception const &ex)
|
catch (std::exception const &ex)
|
||||||
{
|
{
|
||||||
|
89
BigBaseV2/src/services/globals_service.cpp
Normal file
89
BigBaseV2/src/services/globals_service.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include "globals_service.hpp"
|
||||||
|
#include "thread_pool.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
globals_service::globals_service()
|
||||||
|
{
|
||||||
|
g_globals_service = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
globals_service::~globals_service()
|
||||||
|
{
|
||||||
|
g_globals_service = nullptr;
|
||||||
|
|
||||||
|
m_running = false;
|
||||||
|
|
||||||
|
this->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals_service::build(nlohmann::json& data)
|
||||||
|
{
|
||||||
|
m_globals.clear();
|
||||||
|
|
||||||
|
for (auto& offset : data)
|
||||||
|
m_globals.push_back(global(offset));
|
||||||
|
|
||||||
|
for (auto& global : m_globals)
|
||||||
|
global.build_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool globals_service::load()
|
||||||
|
{
|
||||||
|
std::string path = std::getenv("appdata");
|
||||||
|
path += this->file_location;
|
||||||
|
|
||||||
|
std::ifstream file(path);
|
||||||
|
|
||||||
|
if (!file.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
j << file;
|
||||||
|
|
||||||
|
this->build(j);
|
||||||
|
}
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Failure to parse globals.json, aborting...";
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals_service::loop()
|
||||||
|
{
|
||||||
|
// Don't start loop if it's already running...
|
||||||
|
if (m_running) return;
|
||||||
|
|
||||||
|
while (m_running)
|
||||||
|
for (auto& global : m_globals)
|
||||||
|
if (global.m_freeze) global.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals_service::save()
|
||||||
|
{
|
||||||
|
nlohmann::json j = nlohmann::json::array();
|
||||||
|
for (auto& global : m_globals)
|
||||||
|
j.push_back(global.to_json());
|
||||||
|
|
||||||
|
std::string path = std::getenv("appdata");
|
||||||
|
path += this->file_location;
|
||||||
|
std::ofstream file(path, std::ios::out | std::ios::trunc);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file << j.dump(4);
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
catch (const std::exception&)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Failed to write to globals.json";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
143
BigBaseV2/src/services/globals_service.hpp
Normal file
143
BigBaseV2/src/services/globals_service.hpp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "script_global.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
struct global_offset
|
||||||
|
{
|
||||||
|
global_offset(nlohmann::json data)
|
||||||
|
{
|
||||||
|
m_offset = data["offset"];
|
||||||
|
|
||||||
|
if (data.contains("size"))
|
||||||
|
m_size = data["size"];
|
||||||
|
}
|
||||||
|
|
||||||
|
global_offset(int offset, int size = 0)
|
||||||
|
{
|
||||||
|
m_offset = offset;
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
m_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
script_global apply(script_global internal_cache)
|
||||||
|
{
|
||||||
|
return m_size ? internal_cache.at(m_offset, m_size) : internal_cache.at(m_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json to_json()
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
|
||||||
|
j["offset"] = m_offset;
|
||||||
|
if (m_size)
|
||||||
|
j["size"] = m_size;
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_offset = 0;
|
||||||
|
int m_size = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct global
|
||||||
|
{
|
||||||
|
int m_base_address;
|
||||||
|
bool m_freeze = false;
|
||||||
|
std::string m_name;
|
||||||
|
std::vector<global_offset> m_offsets;
|
||||||
|
int m_value;
|
||||||
|
|
||||||
|
global(nlohmann::json data)
|
||||||
|
{
|
||||||
|
m_base_address = data["base_address"];
|
||||||
|
m_freeze = data["freeze"];
|
||||||
|
m_name = data["name"];
|
||||||
|
m_value = data["value"];
|
||||||
|
|
||||||
|
for (auto& offset : data["offsets"])
|
||||||
|
m_offsets.push_back(global_offset(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
global(const char* name, const int base_address, const bool freeze, const int(*offsets)[2], int offset_count)
|
||||||
|
{
|
||||||
|
m_base_address = base_address;
|
||||||
|
m_freeze = freeze;
|
||||||
|
m_name = std::string(name);
|
||||||
|
m_value = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < offset_count; i++)
|
||||||
|
m_offsets.push_back(global_offset(offsets[i][0], offsets[i][1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_cache()
|
||||||
|
{
|
||||||
|
script_global internal_cache(m_base_address);
|
||||||
|
|
||||||
|
for (auto& offset : m_offsets)
|
||||||
|
internal_cache = offset.apply(internal_cache);
|
||||||
|
|
||||||
|
m_internal_addr = internal_cache.as<int*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int* get()
|
||||||
|
{
|
||||||
|
if (m_freeze)
|
||||||
|
return &m_value;
|
||||||
|
return m_internal_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(int value)
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
if (!m_freeze)
|
||||||
|
this->write();
|
||||||
|
}
|
||||||
|
|
||||||
|
nlohmann::json to_json()
|
||||||
|
{
|
||||||
|
nlohmann::json j;
|
||||||
|
|
||||||
|
j["base_address"] = m_base_address;
|
||||||
|
j["freeze"] = m_freeze;
|
||||||
|
j["name"] = m_name;
|
||||||
|
j["value"] = m_value;
|
||||||
|
|
||||||
|
j["offsets"] = nlohmann::json::array();
|
||||||
|
for (auto& offset : m_offsets)
|
||||||
|
j["offsets"].push_back(offset.to_json());
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
void write()
|
||||||
|
{
|
||||||
|
*m_internal_addr = m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int* m_internal_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class globals_service
|
||||||
|
{
|
||||||
|
const char* file_location = "\\BigBaseV2\\globals.json";
|
||||||
|
|
||||||
|
public:
|
||||||
|
globals_service();
|
||||||
|
~globals_service();
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
void loop();
|
||||||
|
void save();
|
||||||
|
|
||||||
|
std::vector<global> m_globals;
|
||||||
|
bool m_running = false;;
|
||||||
|
private:
|
||||||
|
void build(nlohmann::json& data);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline globals_service* g_globals_service{};
|
||||||
|
}
|
Reference in New Issue
Block a user