From 99d0dfb9e6798d8cbc0d04214aad6dac0960ac9e Mon Sep 17 00:00:00 2001 From: illusion0001 <37698908+illusion0001@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:16:16 -0600 Subject: [PATCH 1/3] FreeCam: Hide Disable Movement on unsupported games (#1123) * FreeCam: Hide Disable Movement on non RE8 * Update FreeCam.cpp * Update FreeCam.cpp --------- Co-authored-by: praydog --- src/mods/FreeCam.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mods/FreeCam.cpp b/src/mods/FreeCam.cpp index 6f73c3469..abc732897 100644 --- a/src/mods/FreeCam.cpp +++ b/src/mods/FreeCam.cpp @@ -8,6 +8,10 @@ using namespace utility; +#if defined(RE2) || defined(RE3) || defined(RE8) || defined(RE4) +#define MOVEMENT_DISABLE_FEATURE +#endif + void FreeCam::on_config_load(const Config& cfg) { for (IModValue& option : m_options) { option.config_load(cfg); @@ -49,7 +53,7 @@ void FreeCam::on_draw_ui() { ImGui::SameLine(); m_lock_camera->draw("Lock Position"); -#ifndef SF6 +#ifdef MOVEMENT_DISABLE_FEATURE m_disable_movement->draw("Disable Character Movement"); #endif @@ -57,7 +61,7 @@ void FreeCam::on_draw_ui() { m_move_up_key->draw("Move camera up Key"); m_move_down_key->draw("Move camera down Key"); m_lock_camera_key->draw("Lock Position Toggle Key"); -#ifndef SF6 +#ifdef MOVEMENT_DISABLE_FEATURE m_disable_movement_key->draw("Disable Movement Toggle Key"); #endif m_speed_modifier_fast_key->draw("Speed modifier Fast key"); From d0617bc1e7e00cdc240db6bcf13cfdece513fb44 Mon Sep 17 00:00:00 2001 From: shadowcookie <45361488+kagenocookie@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:48:56 +0100 Subject: [PATCH 2/3] Pre-emptively store all types in lookup map (#1148) --- shared/sdk/RETypeDB.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/shared/sdk/RETypeDB.cpp b/shared/sdk/RETypeDB.cpp index aaa580ba6..2550e8f2f 100644 --- a/shared/sdk/RETypeDB.cpp +++ b/shared/sdk/RETypeDB.cpp @@ -46,27 +46,33 @@ reframework::InvokeRet invoke_object_func(::REManagedObject* obj, std::string_vi } sdk::RETypeDefinition* RETypeDB::find_type(std::string_view name) const { + static bool map_populated = false; + { std::shared_lock _{ g_tdb_type_mtx }; if (auto it = g_tdb_type_map.find(name.data()); it != g_tdb_type_map.end()) { return it->second; } + + if (map_populated) { + return nullptr; + } } - for (uint32_t i = 0; i < this->numTypes; ++i) { - auto t = get_type(i); + { + std::unique_lock _{ g_tdb_type_mtx }; + + map_populated = true; - if (t->get_full_name() == name) { - std::unique_lock _{ g_tdb_type_mtx }; + for (uint32_t i = 0; i < this->numTypes; ++i) { + auto t = get_type(i); - g_tdb_type_map[name.data()] = t; - return g_tdb_type_map[name.data()]; + g_tdb_type_map[t->get_full_name()] = t; } } - std::unique_lock _{ g_tdb_type_mtx }; - return g_tdb_type_map[name.data()]; + return this->find_type(name); } sdk::RETypeDefinition* RETypeDB::find_type_by_fqn(uint32_t fqn) const { @@ -1152,4 +1158,4 @@ std::vector REMethodDefinition::get_param_names() const { return out; #endif } -} // namespace sdk \ No newline at end of file +} // namespace sdk From 3e8c47d32f9a28537a777adb8d88a61e639a0dc9 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 10 Nov 2024 16:38:34 -0800 Subject: [PATCH 3/3] VM (DD2/MHWilds): Fix LocalFrameGC and cleanup code not getting found --- shared/sdk/REContext.cpp | 68 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/shared/sdk/REContext.cpp b/shared/sdk/REContext.cpp index 3b40883f3..e9aff381c 100644 --- a/shared/sdk/REContext.cpp +++ b/shared/sdk/REContext.cpp @@ -469,6 +469,7 @@ namespace sdk { static void* (*s_context_unhandled_exception_fn)(::REThreadContext*) = nullptr; static void* (*s_context_local_frame_gc_fn)(::REThreadContext*) = nullptr; static void* (*s_context_end_global_frame_fn)(::REThreadContext*) = nullptr; + static void* (*s_context_full_cleanup_fn)(::REThreadContext*) = nullptr; void sdk::VMContext::update_pointers() { { @@ -489,7 +490,7 @@ namespace sdk { s_fully_updated_vm_context_pointers = true; }}; - spdlog::info("Locating funcs"); + spdlog::info("[VMContext] Locating funcs"); // Version 1 //auto ref = utility::scan(g_framework->getModule().as(), "48 83 78 18 00 74 ? 48 89 D9 E8 ? ? ? ? 48 89 D9 E8 ? ? ? ?"); @@ -498,7 +499,65 @@ namespace sdk { auto ref = utility::scan(utility::get_executable(), "48 83 78 18 00 74 ? 48 ? ? E8 ? ? ? ? 48 ? ? E8 ? ? ? ? 48 ? ? E8 ? ? ? ?"); if (!ref) { - spdlog::error("We're going to crash"); + spdlog::info("[VMContext] Could not locate functions we need, trying fallback for full cleanup..."); + + auto full_cleanup_ref = utility::scan(utility::get_executable(), "48 8B 41 50 48 83 78 18 00"); + + if (full_cleanup_ref) { + auto fn = utility::find_function_start_with_call(*full_cleanup_ref); + + if (!fn) { + spdlog::error("[VMContext] Could not locate full cleanup function."); + return; + } + + s_context_full_cleanup_fn = (decltype(s_context_full_cleanup_fn))*fn; + spdlog::info("Context::FullCleanup {:x}", (uintptr_t)s_context_full_cleanup_fn); + + // We need LocalFrameGC at least now, the other functions are not important if we have the full cleanup function. + // Because we actually do call LocalFrameGC by itself when needed. + // Doing this because I'm seeing tail calls which can confuse the disassembler + auto basic_blocks = utility::collect_basic_blocks(*fn); + + if (basic_blocks.empty()) { + spdlog::error("[VMContext] Could not locate LocalFrameGC function (basic blocks)."); + return; + } + + for (const auto& bb : basic_blocks) { + if (s_context_local_frame_gc_fn != nullptr) { + break; + } + + for (const auto& ix : bb.instructions) { + if (s_context_local_frame_gc_fn != nullptr) { + break; + } + + // Hit a call + if (*(uint8_t*)ix.addr == 0xE8) { + const auto dst = utility::calculate_absolute(ix.addr + 1); + + // This is always near the very start of the function entry, seen back in RE8 up to MHWilds. + // However it's such a common set of instructions which is why we narrow it to this function. + if (utility::scan_disasm(dst, 20, "48 8B 41 50")) { + s_context_local_frame_gc_fn = (decltype(s_context_local_frame_gc_fn))dst; + spdlog::info("[VMContext] Context::LocalFrameGC {:x}", (uintptr_t)s_context_local_frame_gc_fn); + break; + } + } + } + } + + if (s_context_local_frame_gc_fn == nullptr) { + spdlog::error("[VMContext] Could not locate LocalFrameGC function."); + return; + } + + return; + } + + spdlog::error("[VMContext] We're going to crash, could not locate functions we need."); return; } @@ -535,6 +594,11 @@ namespace sdk { spdlog::error("{}", reference_count); if (count_delta >= 1) { + if (s_context_full_cleanup_fn != nullptr) { + s_context_full_cleanup_fn(this); + return; + } + --reference_count; // Perform object cleanup that was missed because an exception occurred.