Add custom text service (#370)
This commit is contained in:
parent
dbe3777b12
commit
400ba48fa6
@ -23,6 +23,9 @@ namespace big
|
|||||||
// Script Hook
|
// Script Hook
|
||||||
m_run_script_threads_hook("SH", g_pointers->m_run_script_threads, &hooks::run_script_threads),
|
m_run_script_threads_hook("SH", g_pointers->m_run_script_threads, &hooks::run_script_threads),
|
||||||
|
|
||||||
|
// Get Label Text
|
||||||
|
m_get_label_text("GLT", g_pointers->m_get_label_text, &hooks::get_label_text),
|
||||||
|
|
||||||
// GTA Thead Start
|
// GTA Thead Start
|
||||||
m_gta_thread_start_hook("GTS", g_pointers->m_gta_thread_start, &hooks::gta_thread_start),
|
m_gta_thread_start_hook("GTS", g_pointers->m_gta_thread_start, &hooks::gta_thread_start),
|
||||||
// GTA Thread Kill
|
// GTA Thread Kill
|
||||||
@ -77,6 +80,8 @@ namespace big
|
|||||||
|
|
||||||
m_run_script_threads_hook.enable();
|
m_run_script_threads_hook.enable();
|
||||||
|
|
||||||
|
m_get_label_text.enable();
|
||||||
|
|
||||||
m_gta_thread_start_hook.enable();
|
m_gta_thread_start_hook.enable();
|
||||||
m_gta_thread_kill_hook.enable();
|
m_gta_thread_kill_hook.enable();
|
||||||
|
|
||||||
@ -124,6 +129,8 @@ namespace big
|
|||||||
m_gta_thread_kill_hook.disable();
|
m_gta_thread_kill_hook.disable();
|
||||||
m_gta_thread_start_hook.disable();
|
m_gta_thread_start_hook.disable();
|
||||||
|
|
||||||
|
m_get_label_text.disable();
|
||||||
|
|
||||||
m_run_script_threads_hook.disable();
|
m_run_script_threads_hook.disable();
|
||||||
|
|
||||||
SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc));
|
SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc));
|
||||||
|
@ -21,6 +21,8 @@ namespace big
|
|||||||
|
|
||||||
static LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
static LRESULT wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||||
|
|
||||||
|
static const char* get_label_text(void* unk, const char* label);
|
||||||
|
|
||||||
static GtaThread* gta_thread_start(unsigned int** a1, unsigned int a2);
|
static GtaThread* gta_thread_start(unsigned int** a1, unsigned int a2);
|
||||||
static rage::eThreadState gta_thread_kill(GtaThread* thread);
|
static rage::eThreadState gta_thread_kill(GtaThread* thread);
|
||||||
|
|
||||||
@ -83,6 +85,8 @@ namespace big
|
|||||||
|
|
||||||
detour_hook m_run_script_threads_hook;
|
detour_hook m_run_script_threads_hook;
|
||||||
|
|
||||||
|
detour_hook m_get_label_text;
|
||||||
|
|
||||||
detour_hook m_gta_thread_start_hook;
|
detour_hook m_gta_thread_start_hook;
|
||||||
detour_hook m_gta_thread_kill_hook;
|
detour_hook m_gta_thread_kill_hook;
|
||||||
|
|
||||||
|
13
BigBaseV2/src/hooks/misc/get_label_text.cpp
Normal file
13
BigBaseV2/src/hooks/misc/get_label_text.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "hooking.hpp"
|
||||||
|
#include "services/custom_text/custom_text_service.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
const char* hooks::get_label_text(void* unk, const char* label)
|
||||||
|
{
|
||||||
|
if (const auto text = g_custom_text_service->get_text(label); text)
|
||||||
|
return text;
|
||||||
|
|
||||||
|
return g_hooking->m_get_label_text.get_original<decltype(&get_label_text)>()(unk, label);
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
#include "backend/backend.hpp"
|
#include "backend/backend.hpp"
|
||||||
#include "native_hooks/native_hooks.hpp"
|
#include "native_hooks/native_hooks.hpp"
|
||||||
#include "services/context_menu/context_menu_service.hpp"
|
#include "services/context_menu/context_menu_service.hpp"
|
||||||
|
#include "services/custom_text/custom_text_service.hpp"
|
||||||
#include "services/globals/globals_service.hpp"
|
#include "services/globals/globals_service.hpp"
|
||||||
#include "services/gui/gui_service.hpp"
|
#include "services/gui/gui_service.hpp"
|
||||||
#include "services/gta_data/gta_data_service.hpp"
|
#include "services/gta_data/gta_data_service.hpp"
|
||||||
@ -31,151 +32,154 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
|||||||
|
|
||||||
g_hmodule = hmod;
|
g_hmodule = hmod;
|
||||||
g_main_thread = CreateThread(nullptr, 0, [](PVOID) -> DWORD
|
g_main_thread = CreateThread(nullptr, 0, [](PVOID) -> DWORD
|
||||||
|
{
|
||||||
|
while (!FindWindow(L"grcWindow", L"Grand Theft Auto V"))
|
||||||
|
std::this_thread::sleep_for(1s);
|
||||||
|
|
||||||
|
std::filesystem::path base_dir = std::getenv("appdata");
|
||||||
|
base_dir /= "BigBaseV2";
|
||||||
|
auto file_manager_instance = std::make_unique<file_manager>(base_dir);
|
||||||
|
|
||||||
|
auto globals_instance = std::make_unique<menu_settings>(
|
||||||
|
file_manager_instance->get_project_file("./settings.json")
|
||||||
|
);
|
||||||
|
|
||||||
|
auto logger_instance = std::make_unique<logger>(
|
||||||
|
"YimMenu",
|
||||||
|
file_manager_instance->get_project_file("./cout.log")
|
||||||
|
);
|
||||||
|
|
||||||
|
EnableMenuItem(GetSystemMenu(FindWindowA(NULL, "YimMenu"), 0), SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
while (!FindWindow(L"grcWindow", L"Grand Theft Auto V"))
|
LOG(INFO) << "Yim's Menu Initializing";
|
||||||
std::this_thread::sleep_for(1s);
|
auto pointers_instance = std::make_unique<pointers>();
|
||||||
|
LOG(INFO) << "Pointers initialized.";
|
||||||
|
|
||||||
std::filesystem::path base_dir = std::getenv("appdata");
|
auto renderer_instance = std::make_unique<renderer>();
|
||||||
base_dir /= "BigBaseV2";
|
LOG(INFO) << "Renderer initialized.";
|
||||||
auto file_manager_instance = std::make_unique<file_manager>(base_dir);
|
|
||||||
|
|
||||||
auto globals_instance = std::make_unique<menu_settings>(
|
auto fiber_pool_instance = std::make_unique<fiber_pool>(11);
|
||||||
file_manager_instance->get_project_file("./settings.json")
|
LOG(INFO) << "Fiber pool initialized.";
|
||||||
);
|
|
||||||
|
|
||||||
auto logger_instance = std::make_unique<logger>(
|
auto hooking_instance = std::make_unique<hooking>();
|
||||||
"YimMenu",
|
LOG(INFO) << "Hooking initialized.";
|
||||||
file_manager_instance->get_project_file("./cout.log")
|
|
||||||
);
|
|
||||||
|
|
||||||
EnableMenuItem(GetSystemMenu(FindWindowA(NULL, "YimMenu"), 0), SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
|
g->load();
|
||||||
|
LOG(INFO) << "Settings Loaded.";
|
||||||
|
|
||||||
try
|
auto thread_pool_instance = std::make_unique<thread_pool>();
|
||||||
{
|
LOG(INFO) << "Thread pool initialized.";
|
||||||
LOG(INFO) << "Yim's Menu Initializing";
|
|
||||||
auto pointers_instance = std::make_unique<pointers>();
|
|
||||||
LOG(INFO) << "Pointers initialized.";
|
|
||||||
|
|
||||||
auto renderer_instance = std::make_unique<renderer>();
|
auto context_menu_service_instance = std::make_unique<context_menu_service>();
|
||||||
LOG(INFO) << "Renderer initialized.";
|
auto custom_text_service_instance = std::make_unique<custom_text_service>();
|
||||||
|
auto globals_service_instace = std::make_unique<globals_service>();
|
||||||
|
auto mobile_service_instance = std::make_unique<mobile_service>();
|
||||||
|
auto notification_service_instance = std::make_unique<notification_service>();
|
||||||
|
auto pickup_service_instance = std::make_unique<pickup_service>();
|
||||||
|
auto player_service_instance = std::make_unique<player_service>();
|
||||||
|
auto gta_data_service_instance = std::make_unique<gta_data_service>();
|
||||||
|
auto vehicle_preview_service_instance = std::make_unique<vehicle_preview_service>();
|
||||||
|
auto vehicle_service_instance = std::make_unique<vehicle_service>();
|
||||||
|
auto gui_service_instance = std::make_unique<gui_service>();
|
||||||
|
LOG(INFO) << "Registered service instances...";
|
||||||
|
|
||||||
auto fiber_pool_instance = std::make_unique<fiber_pool>(11);
|
g_script_mgr.add_script(std::make_unique<script>(&gui::script_func, "GUI", false));
|
||||||
LOG(INFO) << "Fiber pool initialized.";
|
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::loop, "Backend Loop", false));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::self_loop, "Self"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::weapons_loop, "Weapon"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::vehicles_loop, "Vehicle"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::misc_loop, "Miscellaneous"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::remote_loop, "Remote"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::noclip_loop, "No Clip"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::lscustoms_loop, "LS Customs"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::vehiclefly_loop, "Vehicle Fly"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::rgbrandomizer_loop, "RGB Randomizer"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::turnsignal_loop, "Turn Signals"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
|
||||||
|
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
|
||||||
|
LOG(INFO) << "Scripts registered.";
|
||||||
|
|
||||||
auto hooking_instance = std::make_unique<hooking>();
|
auto native_hooks_instance = std::make_unique<native_hooks>();
|
||||||
LOG(INFO) << "Hooking initialized.";
|
LOG(INFO) << "Dynamic native hooker initialized.";
|
||||||
|
|
||||||
g->load();
|
g_hooking->enable();
|
||||||
LOG(INFO) << "Settings Loaded.";
|
LOG(INFO) << "Hooking enabled.";
|
||||||
|
|
||||||
auto thread_pool_instance = std::make_unique<thread_pool>();
|
g_running = true;
|
||||||
LOG(INFO) << "Thread pool initialized.";
|
|
||||||
|
|
||||||
auto context_menu_service_instance = std::make_unique<context_menu_service>();
|
while (g_running)
|
||||||
auto globals_service_instace = std::make_unique<globals_service>();
|
std::this_thread::sleep_for(500ms);
|
||||||
auto mobile_service_instance = std::make_unique<mobile_service>();
|
|
||||||
auto notification_service_instance = std::make_unique<notification_service>();
|
|
||||||
auto pickup_service_instance = std::make_unique<pickup_service>();
|
|
||||||
auto player_service_instance = std::make_unique<player_service>();
|
|
||||||
auto gta_data_service_instance = std::make_unique<gta_data_service>();
|
|
||||||
auto vehicle_preview_service_instance = std::make_unique<vehicle_preview_service>();
|
|
||||||
auto vehicle_service_instance = std::make_unique<vehicle_service>();
|
|
||||||
auto gui_service_instance = std::make_unique<gui_service>();
|
|
||||||
LOG(INFO) << "Registered service instances...";
|
|
||||||
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&gui::script_func, "GUI", false));
|
g_hooking->disable();
|
||||||
|
LOG(INFO) << "Hooking disabled.";
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::loop, "Backend Loop", false));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::self_loop, "Self"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::weapons_loop, "Weapon"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::vehicles_loop, "Vehicle"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::misc_loop, "Miscellaneous"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::remote_loop, "Remote"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::noclip_loop, "No Clip"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::lscustoms_loop, "LS Customs"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::vehiclefly_loop, "Vehicle Fly"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::rgbrandomizer_loop, "RGB Randomizer"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::turnsignal_loop, "Turn Signals"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&backend::disable_control_action_loop, "Disable Controls"));
|
|
||||||
g_script_mgr.add_script(std::make_unique<script>(&context_menu_service::context_menu, "Context Menu"));
|
|
||||||
LOG(INFO) << "Scripts registered.";
|
|
||||||
|
|
||||||
auto native_hooks_instance = std::make_unique<native_hooks>();
|
native_hooks_instance.reset();
|
||||||
LOG(INFO) << "Dynamic native hooker initialized.";
|
LOG(INFO) << "Dynamic native hooker uninitialized.";
|
||||||
|
|
||||||
g_hooking->enable();
|
g_script_mgr.remove_all_scripts();
|
||||||
LOG(INFO) << "Hooking enabled.";
|
LOG(INFO) << "Scripts unregistered.";
|
||||||
|
|
||||||
g_running = true;
|
gui_service_instance.reset();
|
||||||
|
LOG(INFO) << "Gui Service reset.";
|
||||||
|
gta_data_service_instance.reset();
|
||||||
|
LOG(INFO) << "GTA Data Service reset.";
|
||||||
|
vehicle_service_instance.reset();
|
||||||
|
LOG(INFO) << "Vehicle Service reset.";
|
||||||
|
vehicle_preview_service_instance.reset();
|
||||||
|
LOG(INFO) << "Vehicle Preview Service reset.";
|
||||||
|
mobile_service_instance.reset();
|
||||||
|
LOG(INFO) << "Mobile Service reset.";
|
||||||
|
player_service_instance.reset();
|
||||||
|
LOG(INFO) << "Player Service reset.";
|
||||||
|
pickup_service_instance.reset();
|
||||||
|
LOG(INFO) << "Pickup Service reset.";
|
||||||
|
globals_service_instace.reset();
|
||||||
|
LOG(INFO) << "Globals Service reset.";
|
||||||
|
custom_text_service_instance.reset();
|
||||||
|
LOG(INFO) << "Custom Text Service reset.";
|
||||||
|
context_menu_service_instance.reset();
|
||||||
|
LOG(INFO) << "Context Service reset.";
|
||||||
|
LOG(INFO) << "Services uninitialized.";
|
||||||
|
|
||||||
while (g_running)
|
// Make sure that all threads created don't have any blocking loops
|
||||||
std::this_thread::sleep_for(500ms);
|
// otherwise make sure that they have stopped executing
|
||||||
|
thread_pool_instance->destroy();
|
||||||
|
LOG(INFO) << "Destroyed thread pool.";
|
||||||
|
|
||||||
g_hooking->disable();
|
thread_pool_instance.reset();
|
||||||
LOG(INFO) << "Hooking disabled.";
|
LOG(INFO) << "Thread pool uninitialized.";
|
||||||
|
|
||||||
native_hooks_instance.reset();
|
hooking_instance.reset();
|
||||||
LOG(INFO) << "Dynamic native hooker uninitialized.";
|
LOG(INFO) << "Hooking uninitialized.";
|
||||||
|
|
||||||
g_script_mgr.remove_all_scripts();
|
fiber_pool_instance.reset();
|
||||||
LOG(INFO) << "Scripts unregistered.";
|
LOG(INFO) << "Fiber pool uninitialized.";
|
||||||
|
|
||||||
gui_service_instance.reset();
|
renderer_instance.reset();
|
||||||
LOG(INFO) << "Gui Service reset.";
|
LOG(INFO) << "Renderer uninitialized.";
|
||||||
gta_data_service_instance.reset();
|
|
||||||
LOG(INFO) << "GTA Data Service reset.";
|
|
||||||
vehicle_service_instance.reset();
|
|
||||||
LOG(INFO) << "Vehicle Service reset.";
|
|
||||||
vehicle_preview_service_instance.reset();
|
|
||||||
LOG(INFO) << "Vehicle Preview Service reset.";
|
|
||||||
mobile_service_instance.reset();
|
|
||||||
LOG(INFO) << "Mobile Service reset.";
|
|
||||||
player_service_instance.reset();
|
|
||||||
LOG(INFO) << "Player Service reset.";
|
|
||||||
pickup_service_instance.reset();
|
|
||||||
LOG(INFO) << "Pickup Service reset.";
|
|
||||||
globals_service_instace.reset();
|
|
||||||
LOG(INFO) << "Globals Service reset.";
|
|
||||||
context_menu_service_instance.reset();
|
|
||||||
LOG(INFO) << "Context Service reset.";
|
|
||||||
LOG(INFO) << "Services uninitialized.";
|
|
||||||
|
|
||||||
// Make sure that all threads created don't have any blocking loops
|
pointers_instance.reset();
|
||||||
// otherwise make sure that they have stopped executing
|
LOG(INFO) << "Pointers uninitialized.";
|
||||||
thread_pool_instance->destroy();
|
}
|
||||||
LOG(INFO) << "Destroyed thread pool.";
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
|
LOG(WARNING) << ex.what();
|
||||||
|
}
|
||||||
|
|
||||||
thread_pool_instance.reset();
|
LOG(INFO) << "Farewell!";
|
||||||
LOG(INFO) << "Thread pool uninitialized.";
|
logger_instance->destroy();
|
||||||
|
logger_instance.reset();
|
||||||
|
|
||||||
hooking_instance.reset();
|
globals_instance.reset();
|
||||||
LOG(INFO) << "Hooking uninitialized.";
|
|
||||||
|
|
||||||
fiber_pool_instance.reset();
|
file_manager_instance.reset();
|
||||||
LOG(INFO) << "Fiber pool uninitialized.";
|
|
||||||
|
|
||||||
renderer_instance.reset();
|
CloseHandle(g_main_thread);
|
||||||
LOG(INFO) << "Renderer uninitialized.";
|
FreeLibraryAndExitThread(g_hmodule, 0);
|
||||||
|
}, nullptr, 0, &g_main_thread_id);
|
||||||
pointers_instance.reset();
|
|
||||||
LOG(INFO) << "Pointers uninitialized.";
|
|
||||||
}
|
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
|
||||||
LOG(WARNING) << ex.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(INFO) << "Farewell!";
|
|
||||||
logger_instance->destroy();
|
|
||||||
logger_instance.reset();
|
|
||||||
|
|
||||||
globals_instance.reset();
|
|
||||||
|
|
||||||
file_manager_instance.reset();
|
|
||||||
|
|
||||||
CloseHandle(g_main_thread);
|
|
||||||
FreeLibraryAndExitThread(g_hmodule, 0);
|
|
||||||
}, nullptr, 0, &g_main_thread_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -361,6 +361,12 @@ namespace big
|
|||||||
}*/
|
}*/
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Get Label Text
|
||||||
|
main_batch.add("GLT", "75 ? E8 ? ? ? ? 8B 0D ? ? ? ? 65 48 8B 04 25 ? ? ? ? BA ? ? ? ? 48 8B 04 C8 8B 0C 02 D1 E9", [this](memory::handle ptr)
|
||||||
|
{
|
||||||
|
m_get_label_text = ptr.sub(19).as<PVOID>();
|
||||||
|
});
|
||||||
|
|
||||||
auto mem_region = memory::module(nullptr);
|
auto mem_region = memory::module(nullptr);
|
||||||
main_batch.run(mem_region);
|
main_batch.run(mem_region);
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ namespace big
|
|||||||
PVOID m_is_dlc_present;
|
PVOID m_is_dlc_present;
|
||||||
PVOID m_network_group_override;
|
PVOID m_network_group_override;
|
||||||
PUSHORT m_spectator_check;
|
PUSHORT m_spectator_check;
|
||||||
|
PVOID m_get_label_text;
|
||||||
|
|
||||||
FriendRegistry* m_friend_registry{};
|
FriendRegistry* m_friend_registry{};
|
||||||
|
|
||||||
|
12
BigBaseV2/src/services/custom_text/custom_text_callbacks.cpp
Normal file
12
BigBaseV2/src/services/custom_text/custom_text_callbacks.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "custom_text_callbacks.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
const char* respawn_label_callback(const char* label)
|
||||||
|
{
|
||||||
|
if (g->self.god_mode)
|
||||||
|
return "~r~Dying with god mode, how?";
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
namespace big
|
||||||
|
{
|
||||||
|
extern const char* respawn_label_callback(const char* label);
|
||||||
|
}
|
51
BigBaseV2/src/services/custom_text/custom_text_service.cpp
Normal file
51
BigBaseV2/src/services/custom_text/custom_text_service.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "custom_text_service.hpp"
|
||||||
|
#include "custom_text_callbacks.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
custom_text_service::custom_text_service()
|
||||||
|
{
|
||||||
|
add_callback_for_labels({ RAGE_JOAAT("RESPAWN_W"), RAGE_JOAAT("RESPAWN_W_MP") }, respawn_label_callback);
|
||||||
|
add_label_overwrite(RAGE_JOAAT("GC_OTR_TMR"), "HIDING FROM CLOWNS");
|
||||||
|
add_label_overwrite(RAGE_JOAAT("TICK_LEFTCHEAT"), "~a~~HUD_COLOUR_WHITE~ has been swatted by Rockstar.");
|
||||||
|
|
||||||
|
g_custom_text_service = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_text_service::~custom_text_service()
|
||||||
|
{
|
||||||
|
g_custom_text_service = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool custom_text_service::add_callback_for_label(rage::joaat_t hash, custom_label_callback&& cb)
|
||||||
|
{
|
||||||
|
return m_callbacks.insert({ hash, cb }).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool custom_text_service::add_callback_for_labels(std::list<rage::joaat_t> hashes, custom_label_callback&& cb)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
for (const auto& hash : hashes)
|
||||||
|
result = m_callbacks.insert({ hash, cb }).second;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool custom_text_service::add_label_overwrite(rage::joaat_t hash, const std::string_view overwrite)
|
||||||
|
{
|
||||||
|
const auto size = std::strlen(overwrite.data()) + 1;
|
||||||
|
auto buffer = std::make_unique<char[]>(size);
|
||||||
|
memcpy(buffer.get(), overwrite.data(), size);
|
||||||
|
|
||||||
|
return m_label_overwrites.insert({ hash, std::move(buffer) }).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* custom_text_service::get_text(const char* label) const
|
||||||
|
{
|
||||||
|
const auto hash = rage::joaat(label);
|
||||||
|
if (const auto& it = m_callbacks.find(hash); it != m_callbacks.end())
|
||||||
|
return it->second(label);
|
||||||
|
if (const auto& it = m_label_overwrites.find(hash); it != m_label_overwrites.end())
|
||||||
|
return it->second.get();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
33
BigBaseV2/src/services/custom_text/custom_text_service.hpp
Normal file
33
BigBaseV2/src/services/custom_text/custom_text_service.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "gta/joaat.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
using custom_label_callback = std::function<const char* (const char*)>;
|
||||||
|
class custom_text_service final
|
||||||
|
{
|
||||||
|
std::map<rage::joaat_t, custom_label_callback> m_callbacks;
|
||||||
|
std::map<rage::joaat_t, std::unique_ptr<char[]>> m_label_overwrites;
|
||||||
|
|
||||||
|
public:
|
||||||
|
custom_text_service();
|
||||||
|
~custom_text_service();
|
||||||
|
|
||||||
|
custom_text_service(const custom_text_service&) = delete;
|
||||||
|
custom_text_service(custom_text_service&&) noexcept = delete;
|
||||||
|
custom_text_service& operator=(const custom_text_service&) = delete;
|
||||||
|
custom_text_service& operator=(custom_text_service&&) noexcept = delete;
|
||||||
|
|
||||||
|
bool add_callback_for_label(rage::joaat_t hash, custom_label_callback&& cb);
|
||||||
|
bool add_callback_for_labels(std::list<rage::joaat_t> hashes, custom_label_callback&& cb);
|
||||||
|
bool add_label_overwrite(rage::joaat_t hash, std::string_view overwrite);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the custom text for a label.
|
||||||
|
* \return nullptr if no custom text exists
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const char* get_text(const char* label) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline custom_text_service* g_custom_text_service;
|
||||||
|
}
|
Reference in New Issue
Block a user