From 4c3aaf93799e9dbe4170f051cfc28915be6ad0fe Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 4 Feb 2024 12:38:44 -0800 Subject: [PATCH] BP: Fix IsHeadMountedDisplayEnabled on >= 4.18 --- src/CommitHash.hpp | 2 +- src/mods/vr/IXRTrackingSystemHook.cpp | 100 +++++++++++++++----------- src/mods/vr/IXRTrackingSystemHook.hpp | 8 +++ 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/CommitHash.hpp b/src/CommitHash.hpp index 01e0af42..b353c3ce 100644 --- a/src/CommitHash.hpp +++ b/src/CommitHash.hpp @@ -1,4 +1,4 @@ #pragma once -#define UEVR_COMMIT_HASH "98d675f7448ad9b14ae0ff288bc81006c8d70367" +#define UEVR_COMMIT_HASH "18ed2b9982e9573bc6c9c5be4c99e354b1c8acdf" #define UEVR_BUILD_DATE "04.02.2024" #define UEVR_BUILD_TIME "00:00" diff --git a/src/mods/vr/IXRTrackingSystemHook.cpp b/src/mods/vr/IXRTrackingSystemHook.cpp index 2b6dcd25..190a7dcd 100644 --- a/src/mods/vr/IXRTrackingSystemHook.cpp +++ b/src/mods/vr/IXRTrackingSystemHook.cpp @@ -937,7 +937,7 @@ bool IXRTrackingSystemHook::analyze_head_tracking_allowed(uintptr_t return_addre void* IXRTrackingSystemHook::get_orientation_and_position_native(void* rcx, void* rdx, void* r8, void* r9) { SPDLOG_INFO_ONCE("GetOrientationAndPosition native function {:x}", (uintptr_t)_ReturnAddress()); - auto og = g_hook->m_native_get_oap_hook->get_original(); + const auto og = g_hook->m_native_get_oap_hook->get_original(); g_hook->m_within_get_oap_native = true; @@ -948,6 +948,20 @@ void* IXRTrackingSystemHook::get_orientation_and_position_native(void* rcx, void return result; } +void* IXRTrackingSystemHook::is_head_mounted_display_enabled_native(void* rcx, void* rdx, void* r8, void* r9) { + SPDLOG_INFO_ONCE("IsHeadMountedDisplayEnabled native function {:x}", (uintptr_t)_ReturnAddress()); + + const auto og = g_hook->m_native_is_hmd_enabled_hook->get_original(); + + g_hook->m_within_is_hmd_enabled_native = true; + + const auto result = og(rcx, rdx, r8, r9); + + g_hook->m_within_is_hmd_enabled_native = false; + + return result; +} + bool IXRTrackingSystemHook::is_head_tracking_allowed(sdk::IXRTrackingSystem*) { SPDLOG_INFO_ONCE("is_head_tracking_allowed {:x}", (uintptr_t)_ReturnAddress()); @@ -961,62 +975,68 @@ bool IXRTrackingSystemHook::is_head_tracking_allowed(sdk::IXRTrackingSystem*) { return true; } - static bool is_allowed_return_true = false; static bool attempted_check = false; - if (vr->wants_blueprint_load()) { - if (!is_allowed_return_true && !attempted_check) try { - attempted_check = true; - const auto uobjectarray = sdk::FUObjectArray::get(); - - if (uobjectarray == nullptr) { - SPDLOG_ERROR("Failed to find FUObjectArray"); - return false; - } + if (vr->wants_blueprint_load() && !attempted_check) try { + attempted_check = true; + const auto uobjectarray = sdk::FUObjectArray::get(); - const auto hmd_lib = sdk::UHeadMountedDisplayFunctionLibrary::static_class(); + if (uobjectarray == nullptr) { + SPDLOG_ERROR("Failed to find FUObjectArray"); + return false; + } - if (hmd_lib == nullptr) { - SPDLOG_ERROR("Failed to find UHeadMountedDisplayFunctionLibrary"); - return false; - } + const auto hmd_lib = sdk::UHeadMountedDisplayFunctionLibrary::static_class(); - auto get_orientation_and_position_fn = hmd_lib->find_function(L"GetOrientationAndPosition"); + if (hmd_lib == nullptr) { + SPDLOG_ERROR("Failed to find UHeadMountedDisplayFunctionLibrary"); + return false; + } - if (get_orientation_and_position_fn == nullptr) { - SPDLOG_ERROR("Failed to find GetOrientationAndPosition"); - return false; - } + if (sdk::UFunction::get_native_function_offset() == 0) { + SPDLOG_ERROR("UFunction::get_native_function_offset is 0"); + return false; + } - if (sdk::UFunction::get_native_function_offset() == 0) { - SPDLOG_ERROR("UFunction::get_native_function_offset is 0"); - return false; - } + // GetOrientationAndPosition hook + auto get_orientation_and_position_fn = hmd_lib->find_function(L"GetOrientationAndPosition"); - auto& native_fn = get_orientation_and_position_fn->get_native_function(); + if (get_orientation_and_position_fn != nullptr) { + auto& native_fn_get_oap = get_orientation_and_position_fn->get_native_function(); - if (native_fn == nullptr || IsBadReadPtr(native_fn, sizeof(void*))) { - SPDLOG_ERROR("Failed to find native function for GetOrientationAndPosition"); - return false; + if (native_fn_get_oap != nullptr && !IsBadReadPtr(native_fn_get_oap, sizeof(void*))) { + g_hook->m_native_get_oap_hook = std::make_unique((void**)&native_fn_get_oap, get_orientation_and_position_native); + SPDLOG_INFO("Hooked GetOrientationAndPosition native function"); + } else { + SPDLOG_ERROR("Failed to hook GetOrientationAndPosition native function"); } + } else { + SPDLOG_ERROR("Failed to find GetOrientationAndPosition native function"); + } + + // IsHeadMountedDisplayEnabled hook + auto is_head_mounted_display_enabled_fn = hmd_lib->find_function(L"IsHeadMountedDisplayEnabled"); - g_hook->m_native_get_oap_hook = std::make_unique((void**)&native_fn, get_orientation_and_position_native); - is_allowed_return_true = true; + if (is_head_mounted_display_enabled_fn != nullptr) { + auto& native_fn_is_hmd_enabled = is_head_mounted_display_enabled_fn->get_native_function(); - SPDLOG_INFO("Hooked GetOrientationAndPosition native function"); - } catch(...) { - SPDLOG_ERROR("Failed to hook GetOrientationAndPosition native function due to exception"); + if (native_fn_is_hmd_enabled != nullptr && !IsBadReadPtr(native_fn_is_hmd_enabled, sizeof(void*))) { + g_hook->m_native_is_hmd_enabled_hook = std::make_unique((void**)&native_fn_is_hmd_enabled, is_head_mounted_display_enabled_native); + SPDLOG_INFO("Hooked IsHeadMountedDisplayEnabled native function"); + } else { + SPDLOG_ERROR("Failed to hook IsHeadMountedDisplayEnabled native function"); + } + } else { + SPDLOG_ERROR("Failed to find IsHeadMountedDisplayEnabled native function"); } + } catch(...) { + SPDLOG_ERROR("Failed to hook native functions due to exception"); } if (!vr->is_any_aim_method_active()) { // Only allow this to return true if BP functions are the ones calling it // Like GetOrientationAndPosition - if (is_allowed_return_true) { - return g_hook->m_within_get_oap_native; - } - - return false; + return g_hook->is_within_valid_head_tracking_allowed_code(); } if (!g_hook->m_process_view_rotation_hook && !g_hook->m_attempted_hook_view_rotation) { @@ -1029,7 +1049,7 @@ bool IXRTrackingSystemHook::is_head_tracking_allowed(sdk::IXRTrackingSystem*) { } - return !g_hook->m_process_view_rotation_hook || (is_allowed_return_true && g_hook->m_within_get_oap_native); + return !g_hook->m_process_view_rotation_hook || g_hook->is_within_valid_head_tracking_allowed_code(); } bool IXRTrackingSystemHook::is_head_tracking_allowed_for_world(sdk::IXRTrackingSystem*, void*) { diff --git a/src/mods/vr/IXRTrackingSystemHook.hpp b/src/mods/vr/IXRTrackingSystemHook.hpp index de4d6c22..e3d5b083 100644 --- a/src/mods/vr/IXRTrackingSystemHook.hpp +++ b/src/mods/vr/IXRTrackingSystemHook.hpp @@ -92,6 +92,7 @@ class IXRTrackingSystemHook : public ModComponent { // UHeadMountedDisplayFunctionLibrary static void* get_orientation_and_position_native(void*, void*, void*, void*); + static void* is_head_mounted_display_enabled_native(void*, void*, void*, void*); void pre_update_view_rotation(sdk::UObject* reference_obj, Rotator* rot); @@ -133,6 +134,13 @@ class IXRTrackingSystemHook : public ModComponent { std::unique_ptr m_native_get_oap_hook{}; bool m_within_get_oap_native{false}; + std::unique_ptr m_native_is_hmd_enabled_hook{}; + bool m_within_is_hmd_enabled_native{false}; + + bool is_within_valid_head_tracking_allowed_code() const { + return m_within_get_oap_native || m_within_is_hmd_enabled_native; + } + uintptr_t m_addr_of_process_view_rotation_ptr{}; //std::unique_ptr m_process_view_rotation_hook{}; safetyhook::InlineHook m_process_view_rotation_hook{};