From 343039ddd8d564956a25b831a31033339909bef2 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Mon, 29 Jul 2024 15:27:01 +0200 Subject: [PATCH] Added light attach crash fix by powerofthree --- SKSE/Plugins/EnderalSE.ini | 1 + SKSE/Plugins/EnderalVersion.ini | 2 +- source/Enderal DLL/CMakeLists.txt | 6 +-- source/Enderal DLL/src/Main.cpp | 8 +++- source/Enderal DLL/src/PCH.cpp | 33 +++++++++++++++++ source/Enderal DLL/src/PCH.h | 12 ++++++ .../src/Patches/AttachLightHitEffectCrash.h | 37 +++++++++++++++++++ source/Enderal DLL/vcpkg.json | 3 +- 8 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 source/Enderal DLL/src/PCH.cpp create mode 100644 source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h diff --git a/SKSE/Plugins/EnderalSE.ini b/SKSE/Plugins/EnderalSE.ini index d19e623b..0eee24e0 100644 --- a/SKSE/Plugins/EnderalSE.ini +++ b/SKSE/Plugins/EnderalSE.ini @@ -4,3 +4,4 @@ MapMarkerPlacementFixes = true AchievementFix = true VideoInterruptPatch = true ForceBorderless = true +AttachLightHitEffectCrashFix = true diff --git a/SKSE/Plugins/EnderalVersion.ini b/SKSE/Plugins/EnderalVersion.ini index 1bc9b518..c7c0056d 100644 --- a/SKSE/Plugins/EnderalVersion.ini +++ b/SKSE/Plugins/EnderalVersion.ini @@ -1 +1 @@ -version = 2.1.1 +version = 2.1.2 diff --git a/source/Enderal DLL/CMakeLists.txt b/source/Enderal DLL/CMakeLists.txt index d799b14f..98821769 100644 --- a/source/Enderal DLL/CMakeLists.txt +++ b/source/Enderal DLL/CMakeLists.txt @@ -42,7 +42,7 @@ include(FetchContent) FetchContent_Declare( CommonLibNG GIT_REPOSITORY https://github.com/alandtse/CommonLibVR.git - GIT_TAG 735fa6dae8ec72966ee02673dd689c6516d49f71 + GIT_TAG 5e5417e3585c9434295e919bdda27737244e9c5a ) set(ENABLE_SKYRIM_SE ON CACHE BOOL " " FORCE) @@ -50,10 +50,10 @@ set(ENABLE_SKYRIM_AE ON CACHE BOOL " " FORCE) set(ENABLE_SKYRIM_VR ON CACHE BOOL " " FORCE) set(BUILD_TESTS OFF CACHE BOOL " " FORCE) -#FetchContent_MakeAvailable(CommonLibNG) +FetchContent_MakeAvailable(CommonLibNG) # Use a local copy instead -add_subdirectory("d:/Git/CommonLibVR/" ${CMAKE_BINARY_DIR}/_deps/clib-build) +#add_subdirectory("d:/Git/CommonLibVR/" ${CMAKE_BINARY_DIR}/_deps/clib-build) #find_package(CommonLibSSE CONFIG REQUIRED) diff --git a/source/Enderal DLL/src/Main.cpp b/source/Enderal DLL/src/Main.cpp index 80d141b5..a80ec20e 100644 --- a/source/Enderal DLL/src/Main.cpp +++ b/source/Enderal DLL/src/Main.cpp @@ -12,6 +12,7 @@ #include "Patches/HeroMenuPatch.h" #include "Patches/HUDMenuPatch.h" #include "Patches/ForceBorderless.h" +#include "Patches/AttachLightHitEffectCrash.h" using namespace SKSE; @@ -21,7 +22,8 @@ static std::map g_settings{ { "MapMarkerPlacementFixes", true }, { "AchievementFix", true }, { "VideoInterruptPatch", true }, - { "ForceBorderless", true } + { "ForceBorderless", true }, + { "AttachLightHitEffectCrashFix", true } }; namespace { @@ -213,6 +215,10 @@ SKSEPluginLoad(const LoadInterface* skse) { logger::info("Initializing Stay At The System Page..."); JournalMenuEx::InstallHooks(); } + if (g_settings.at("AttachLightHitEffectCrashFix")) { + logger::info("Installing light attach crash fix..."); + AttachLightHitEffectCrash::Install(); + } } logger::info("{} has finished loading.", plugin->GetName()); diff --git a/source/Enderal DLL/src/PCH.cpp b/source/Enderal DLL/src/PCH.cpp new file mode 100644 index 00000000..29895d9e --- /dev/null +++ b/source/Enderal DLL/src/PCH.cpp @@ -0,0 +1,33 @@ +namespace SKSE::stl +{ + namespace detail + { + struct asm_patch : + Xbyak::CodeGenerator + { + asm_patch(std::uintptr_t a_dst) + { + Xbyak::Label dst; + + mov(rax, a_dst); + jmp(rax); + } + }; + } + + void asm_jump(std::uintptr_t a_from, [[maybe_unused]] std::size_t a_size, std::uintptr_t a_to) + { + detail::asm_patch p{ a_to }; + p.ready(); + assert(p.getSize() <= a_size); + REL::safe_write( + a_from, + std::span{ p.getCode(), p.getSize() }); + } + + void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to) + { + REL::safe_fill(a_from, REL::INT3, a_size); + asm_jump(a_from, a_size, a_to); + } +} diff --git a/source/Enderal DLL/src/PCH.h b/source/Enderal DLL/src/PCH.h index 98479db5..5dd7b649 100644 --- a/source/Enderal DLL/src/PCH.h +++ b/source/Enderal DLL/src/PCH.h @@ -9,6 +9,7 @@ #include #include +#include // Compatible declarations with other sample projects. #define DLLEXPORT __declspec(dllexport) @@ -17,3 +18,14 @@ using namespace std::literals; using namespace REL::literals; namespace logger = SKSE::log; + +namespace SKSE::stl +{ + void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to); + + template + void asm_replace(std::uintptr_t a_from, std::size_t a_size) + { + asm_replace(a_from, a_size, reinterpret_cast(T::func)); + } +} diff --git a/source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h b/source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h new file mode 100644 index 00000000..ead455a3 --- /dev/null +++ b/source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h @@ -0,0 +1,37 @@ +#pragma once + +// fix BSFadeNode nullptr crash re: AttachLightHitEffectVisitor +// Copied from powerofthree's Tweaks (MIT) +namespace AttachLightHitEffectCrash +{ + struct AttachLightHitEffectVisitor + { + static RE::BSContainer::ForEachResult func(RE::AttachLightHitEffectVisitor* a_this, RE::ReferenceEffect* a_hitEffect) + { + if (a_hitEffect->GetAttached()) { + auto root = a_hitEffect->GetAttachRoot(); + if (const auto attachLightObj = root ? root->GetObjectByName(RE::FixedStrings::GetSingleton()->attachLight) : //crash here because no null check + nullptr) { + root = attachLightObj; + } + if (root && root != a_this->attachRoot) { + a_this->attachLightNode = root; + } + if (a_this->attachLightNode) { + return RE::BSContainer::ForEachResult::kStop; + } + } else { + a_this->allAttached = false; + } + return RE::BSContainer::ForEachResult::kContinue; + } + }; + + void Install() + { + REL::Relocation func{ REL::RelocationID(33610, 34388) }; + + std::size_t size = REL::Module::get().version() > REL::Version(1, 5, 97, 0) ? 0xEC : 0x86; + SKSE::stl::asm_replace(func.address(), size); + } +} diff --git a/source/Enderal DLL/vcpkg.json b/source/Enderal DLL/vcpkg.json index d2d7ed11..a0cd6af3 100644 --- a/source/Enderal DLL/vcpkg.json +++ b/source/Enderal DLL/vcpkg.json @@ -13,7 +13,8 @@ "simpleini", "spdlog", "directxtk", - "rapidcsv" + "rapidcsv", + "xbyak" ] } },