diff --git a/BigBaseV2/src/core/globals.hpp b/BigBaseV2/src/core/globals.hpp index 05fbd556..26ad8534 100644 --- a/BigBaseV2/src/core/globals.hpp +++ b/BigBaseV2/src/core/globals.hpp @@ -168,6 +168,7 @@ namespace big int teleport_waypoint = 0; }; + bool dev_dlc = false; hotkeys hotkeys{}; }; @@ -530,6 +531,7 @@ namespace big this->self.off_radar = j["self"]["off_radar"]; this->self.super_run = j["self"]["super_run"]; + this->settings.dev_dlc = j["settings"]["dev_dlc"]; this->settings.hotkeys.menu_toggle = j["settings"]["hotkeys"]["menu_toggle"]; this->spawn_vehicle.preview_vehicle = j["spawn_vehicle"]["preview_vehicle"]; @@ -787,6 +789,7 @@ namespace big }, { "settings", { + { "dev_dlc", this->settings.dev_dlc }, { "hotkeys", { { "menu_toggle", this->settings.hotkeys.menu_toggle } } diff --git a/BigBaseV2/src/hooking.cpp b/BigBaseV2/src/hooking.cpp index d1bf0ce1..982c27d9 100644 --- a/BigBaseV2/src/hooking.cpp +++ b/BigBaseV2/src/hooking.cpp @@ -38,9 +38,6 @@ namespace big // Network Group Override m_network_group_override("NGO", g_pointers->m_network_group_override, &hooks::network_group_override), - - // Is DLC Present - m_is_dlc_present_hook("IDP", g_pointers->m_is_dlc_present, &hooks::is_dlc_present), // Received Event m_received_event_hook("RE", g_pointers->m_received_event, &hooks::received_event), @@ -85,7 +82,6 @@ namespace big m_network_player_mgr_shutdown_hook.enable(); m_assign_physical_index_hook.enable(); m_received_event_hook.enable(); - m_is_dlc_present_hook.enable(); m_send_net_info_to_lobby.enable(); m_receive_net_message_hook.enable(); m_get_network_event_data_hook.enable(); @@ -105,7 +101,6 @@ namespace big m_receive_net_message_hook.disable(); m_send_net_info_to_lobby.disable(); m_received_event_hook.disable(); - m_is_dlc_present_hook.disable(); m_assign_physical_index_hook.disable(); m_network_player_mgr_init_hook.disable(); m_network_player_mgr_shutdown_hook.disable(); diff --git a/BigBaseV2/src/hooking.hpp b/BigBaseV2/src/hooking.hpp index ccb7eb9f..60712308 100644 --- a/BigBaseV2/src/hooking.hpp +++ b/BigBaseV2/src/hooking.hpp @@ -33,8 +33,6 @@ namespace big static void network_group_override(std::int64_t a1, std::int64_t a2, std::int64_t a3); - static bool is_dlc_present(Hash dlc_hash); - static void received_event( rage::netEventMgr* event_manager, CNetGamePlayer* source_player, @@ -104,8 +102,6 @@ namespace big detour_hook m_network_group_override; detour_hook m_assign_physical_index_hook; - - detour_hook m_is_dlc_present_hook; detour_hook m_received_event_hook; detour_hook m_received_clone_sync_hook; diff --git a/BigBaseV2/src/hooks/is_dlc_present.cpp b/BigBaseV2/src/hooks/is_dlc_present.cpp deleted file mode 100644 index 3c7e88dc..00000000 --- a/BigBaseV2/src/hooks/is_dlc_present.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "gta/joaat.hpp" -#include "hooking.hpp" -#include "natives.hpp" - -namespace big -{ - bool hooks::is_dlc_present(Hash dlc_hash) - { - switch (dlc_hash) - { - case 0x96F02EE6: - return true; - } - - return g_hooking->m_is_dlc_present_hook.get_original()(dlc_hash); - } -} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/all_scripts.hpp b/BigBaseV2/src/native_hooks/all_scripts.hpp new file mode 100644 index 00000000..31387a78 --- /dev/null +++ b/BigBaseV2/src/native_hooks/all_scripts.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "native_hooks.hpp" +#include "natives.hpp" + +namespace big +{ + namespace all_scripts + { + void IS_DLC_PRESENT(rage::scrNativeCallContext* src) + { + const auto hash = src->get_arg(0); + + bool return_value = DLC::IS_DLC_PRESENT(hash); + if (hash == 0x96F02EE6) + return_value = return_value || g->settings.dev_dlc; + + src->set_return_value(return_value); + } + } +} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/native_hooks.cpp b/BigBaseV2/src/native_hooks/native_hooks.cpp new file mode 100644 index 00000000..5903059b --- /dev/null +++ b/BigBaseV2/src/native_hooks/native_hooks.cpp @@ -0,0 +1,93 @@ +#include "native_hooks.hpp" +#include "all_scripts.hpp" +#include "carmod_shop.hpp" +#include "freemode.hpp" +#include "gta_util.hpp" +#include "shop_controller.hpp" + +namespace big +{ + constexpr auto ALL_SCRIPT_HASH = RAGE_JOAAT("ALL_SCRIPTS"); + + native_hooks::native_hooks() + { + add_native_detour(0x812595A0644CE1DE, all_scripts::IS_DLC_PRESENT); + add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS); + add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING); + add_native_detour(RAGE_JOAAT("carmod_shop"), 0x34E710FF01247C5A, carmod_shop::SET_VEHICLE_LIGHTS); + add_native_detour(RAGE_JOAAT("carmod_shop"), 0x767FBC2AC802EF3D, carmod_shop::STAT_GET_INT); + add_native_detour(RAGE_JOAAT("freemode"), 0x95914459A87EBA28, freemode::NETWORK_BAIL); + add_native_detour(RAGE_JOAAT("shop_controller"), 0xDC38CC1E35B6A5D7, shop_controller::SET_WARNING_MESSAGE_WITH_HEADER); + + for (const auto& native_detours_for_script : m_native_registrations) + if (const auto thread = gta_util::find_script_thread(native_detours_for_script.first); thread != nullptr && thread->m_context.m_state == rage::eThreadState::running) + this->check_for_thread(thread); + + g_native_hooks = this; + } + + native_hooks::~native_hooks() + { + g_native_hooks = nullptr; + } + + void native_hooks::add_native_detour(rage::scrNativeHash hash, rage::scrNativeHandler detour) + { + add_native_detour(ALL_SCRIPT_HASH, hash, detour); + } + + void native_hooks::add_native_detour(rage::joaat_t script_hash, rage::scrNativeHash hash, rage::scrNativeHandler detour) + { + if (const auto& it = m_native_registrations.find(script_hash); it != m_native_registrations.end()) + { + it->second.emplace_back(hash, detour); + + return; + } + + m_native_registrations.emplace(script_hash, std::vector({ { hash, detour } })); + } + + bool native_hooks::check_for_thread(const GtaThread* gta_thread) + { + std::unordered_map native_replacements; + const auto script_hash = gta_thread->m_script_hash; + + // Functions that need to be detoured for all scripts + if (const auto& pair = m_native_registrations.find(ALL_SCRIPT_HASH); pair != m_native_registrations.end()) + for (const auto& native_hook_reg : pair->second) + native_replacements.insert(native_hook_reg); + + // Functions that only need to be detoured for a specific script + if (const auto& pair = m_native_registrations.find(script_hash); pair != m_native_registrations.end()) + for (const auto& native_hook_reg : pair->second) + native_replacements.insert(native_hook_reg); + + if (!native_replacements.empty()) + { + if (m_script_hooks.find(gta_thread->m_script_hash) != m_script_hooks.end()) + { + // this should never happen but if it does we catch it + LOG(INFO) << "Dynamic native script hook still active for script, cleaning up..."; + + m_script_hooks.erase(gta_thread->m_script_hash); + } + + m_script_hooks.emplace( + gta_thread->m_script_hash, + std::make_unique(gta_thread->m_script_hash, native_replacements) + ); + + return true; + } + return false; + } + + void native_hooks::do_cleanup_for_thread(const GtaThread* gta_thread) + { + if (m_script_hooks.erase(gta_thread->m_script_hash)) + { + LOG(INFO) << gta_thread->m_name << " script terminated, cleaning up native hooks"; + } + } +} \ No newline at end of file diff --git a/BigBaseV2/src/native_hooks/native_hooks.hpp b/BigBaseV2/src/native_hooks/native_hooks.hpp index 3ff0d57a..44b91a7c 100644 --- a/BigBaseV2/src/native_hooks/native_hooks.hpp +++ b/BigBaseV2/src/native_hooks/native_hooks.hpp @@ -1,102 +1,57 @@ #pragma once -#include "gta_util.hpp" #include "gta/joaat.hpp" #include "gta/script_thread.hpp" -#include "native_hooks/carmod_shop.hpp" -#include "native_hooks/freemode.hpp" -#include "native_hooks/shop_controller.hpp" #include "script_hook.hpp" namespace big { - class native_hooks; - inline native_hooks* g_native_hooks{}; - class native_hooks final { - typedef std::pair native_detour; + using native_detour = std::pair; std::map> m_native_registrations; - std::map> m_script_hooks; public: - native_hooks() - { - add_native_detour(RAGE_JOAAT("carmod_shop"), 0x06843DA7060A026B, carmod_shop::SET_ENTITY_COORDS); - add_native_detour(RAGE_JOAAT("carmod_shop"), 0x8E2530AA8ADA980E, carmod_shop::SET_ENTITY_HEADING); - add_native_detour(RAGE_JOAAT("carmod_shop"), 0x34E710FF01247C5A, carmod_shop::SET_VEHICLE_LIGHTS); - add_native_detour(RAGE_JOAAT("carmod_shop"), 0x767FBC2AC802EF3D, carmod_shop::STAT_GET_INT); - add_native_detour(RAGE_JOAAT("freemode"), 0x95914459A87EBA28, freemode::NETWORK_BAIL); - add_native_detour(RAGE_JOAAT("shop_controller"), 0xDC38CC1E35B6A5D7, shop_controller::SET_WARNING_MESSAGE_WITH_HEADER); - - for (const auto& native_detours_for_script : m_native_registrations) - if (const GtaThread* thread = gta_util::find_script_thread(native_detours_for_script.first); thread != nullptr && thread->m_context.m_state == rage::eThreadState::running) - this->check_for_thread(thread); - - g_native_hooks = this; - } - ~native_hooks() - { - g_native_hooks = nullptr; - } + native_hooks(); + ~native_hooks(); native_hooks(const native_hooks&) = delete; native_hooks(native_hooks&&) noexcept = delete; native_hooks& operator=(const native_hooks&) = delete; native_hooks& operator=(native_hooks&&) noexcept = delete; - void add_native_detour(rage::joaat_t script_hash, rage::scrNativeHash hash, rage::scrNativeHandler detour) - { - if (const auto& it = m_native_registrations.find(script_hash); it != m_native_registrations.end()) - { - it->second.emplace_back(hash, detour); - - return; - } - - m_native_registrations.emplace(script_hash, std::vector({ { hash, detour } })); - } - - bool check_for_thread(const GtaThread* gta_thread) - { - std::unordered_map native_replacements; - const auto script_hash = gta_thread->m_script_hash; - - const auto& pair = m_native_registrations.find(script_hash); - if (pair == m_native_registrations.end()) - return false; - - for (const auto& native_hook_reg : pair->second) - native_replacements.insert(native_hook_reg); - - if (!native_replacements.empty()) - { - if (m_script_hooks.find(gta_thread->m_script_hash) != m_script_hooks.end()) - { - // this should never happen but if it does we catch it - LOG(INFO) << "Dynamic native script hook still active for script, cleaning up..."; - - m_script_hooks.erase(gta_thread->m_script_hash); - } - - m_script_hooks.emplace( - gta_thread->m_script_hash, - std::make_unique(gta_thread->m_script_hash, native_replacements) - ); - - return true; - } - return false; - } - - void do_cleanup_for_thread(const GtaThread* gta_thread) - { - if (m_script_hooks.erase(gta_thread->m_script_hash)) - { - LOG(INFO) << gta_thread->m_name << " script terminated, cleaning up native hooks"; - } - } + /** + * @brief Add a detour for all script threads + * + * @param hash Hash of the native to detour + * @param detour Detour Function + */ + void add_native_detour(rage::scrNativeHash hash, rage::scrNativeHandler detour); + /** + * @brief Add a detour for a specifik script + * + * @param script_hash Hash of the script to detour + * @param hash Hash of the native to detour + * @param detour Detour Function + */ + void add_native_detour(rage::joaat_t script_hash, rage::scrNativeHash hash, rage::scrNativeHandler detour); + /** + * @brief Check if this thread requires us to hook anything + * + * @param gta_thread A GtaThread pointer to hook natives from + * @return true If we detoured a function + * @return false If no functions have been detoured + */ + bool check_for_thread(const GtaThread* gta_thread); + /** + * @brief If a GtaThread terminates call this function to remove the unused script_hook + * + * @param gta_thread + */ + void do_cleanup_for_thread(const GtaThread* gta_thread); }; + + inline native_hooks* g_native_hooks{}; } \ No newline at end of file diff --git a/BigBaseV2/src/pointers.cpp b/BigBaseV2/src/pointers.cpp index c04b28e8..e11a8c53 100644 --- a/BigBaseV2/src/pointers.cpp +++ b/BigBaseV2/src/pointers.cpp @@ -227,12 +227,6 @@ namespace big m_blame_explode = ptr.as(); }); - // Is DLC Present - main_batch.add("IDP", "48 89 5C 24 ? 57 48 83 EC ? 81 F9", [this](memory::handle ptr) - { - m_is_dlc_present = ptr.as(); - }); - // Send NET Info to Lobby main_batch.add("SNITL", "33 DB 48 83 C1 68 45 8B F0 ", [this](memory::handle ptr) { diff --git a/BigBaseV2/src/pointers.hpp b/BigBaseV2/src/pointers.hpp index 8e46f376..00fe8774 100644 --- a/BigBaseV2/src/pointers.hpp +++ b/BigBaseV2/src/pointers.hpp @@ -45,7 +45,6 @@ namespace big PVOID m_blame_explode; PVOID m_model_spawn_bypass; PVOID m_native_return; - PVOID m_is_dlc_present; PVOID m_network_group_override; PUSHORT m_spectator_check; PVOID m_get_label_text; diff --git a/BigBaseV2/src/views/settings/view_settings.cpp b/BigBaseV2/src/views/settings/view_settings.cpp index 35235ef2..d48ef567 100644 --- a/BigBaseV2/src/views/settings/view_settings.cpp +++ b/BigBaseV2/src/views/settings/view_settings.cpp @@ -13,7 +13,8 @@ namespace big ImGui::Spacing(); components::sub_title("These scripts are responsible for all looped features.\nOnly disable if you know what you are doing."); - for (const auto& script : g_script_mgr.scripts()) { + for (const auto& script : g_script_mgr.scripts()) + { if (script->is_toggleable()) if (ImGui::Checkbox(script->name(), script->toggle_ptr())) g_notification_service->push(std::string(script->name()).append(" script"), script->is_enabled() ? "Resumed" : "Halted"); @@ -24,6 +25,10 @@ namespace big void view::settings() { + components::sub_title("Misc"); + ImGui::Checkbox("Enable Dev DLC", &g->settings.dev_dlc); + + ImGui::Separator(); components::sub_title("Hotkeys"); ImGui::PushItemWidth(350.f);