Skip to content

Commit

Permalink
BP: Fix IsHeadMountedDisplayEnabled on >= 4.18
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Feb 4, 2024
1 parent 18ed2b9 commit 4c3aaf9
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 41 deletions.
2 changes: 1 addition & 1 deletion src/CommitHash.hpp
Original file line number Diff line number Diff line change
@@ -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"
100 changes: 60 additions & 40 deletions src/mods/vr/IXRTrackingSystemHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<decltype(&get_orientation_and_position_native)>();
const auto og = g_hook->m_native_get_oap_hook->get_original<decltype(&get_orientation_and_position_native)>();

g_hook->m_within_get_oap_native = true;

Expand All @@ -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<decltype(&is_head_mounted_display_enabled_native)>();

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());

Expand All @@ -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<PointerHook>((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<PointerHook>((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<PointerHook>((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) {
Expand All @@ -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*) {
Expand Down
8 changes: 8 additions & 0 deletions src/mods/vr/IXRTrackingSystemHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<float>* rot);

Expand Down Expand Up @@ -133,6 +134,13 @@ class IXRTrackingSystemHook : public ModComponent {
std::unique_ptr<PointerHook> m_native_get_oap_hook{};
bool m_within_get_oap_native{false};

std::unique_ptr<PointerHook> 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<PointerHook> m_process_view_rotation_hook{};
safetyhook::InlineHook m_process_view_rotation_hook{};
Expand Down

0 comments on commit 4c3aaf9

Please sign in to comment.