Added light attach crash fix by powerofthree
This commit is contained in:
parent
fe6bfad3e9
commit
343039ddd8
@ -4,3 +4,4 @@ MapMarkerPlacementFixes = true
|
||||
AchievementFix = true
|
||||
VideoInterruptPatch = true
|
||||
ForceBorderless = true
|
||||
AttachLightHitEffectCrashFix = true
|
||||
|
@ -1 +1 @@
|
||||
version = 2.1.1
|
||||
version = 2.1.2
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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<std::string, bool> 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());
|
||||
|
33
source/Enderal DLL/src/PCH.cpp
Normal file
33
source/Enderal DLL/src/PCH.cpp
Normal file
@ -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<const std::byte*>(), 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);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <spdlog/sinks/basic_file_sink.h>
|
||||
#include <spdlog/sinks/msvc_sink.h>
|
||||
#include <xbyak/xbyak.h>
|
||||
|
||||
// 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 <class T>
|
||||
void asm_replace(std::uintptr_t a_from, std::size_t a_size)
|
||||
{
|
||||
asm_replace(a_from, a_size, reinterpret_cast<std::uintptr_t>(T::func));
|
||||
}
|
||||
}
|
||||
|
37
source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h
Normal file
37
source/Enderal DLL/src/Patches/AttachLightHitEffectCrash.h
Normal file
@ -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<std::uintptr_t> 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<AttachLightHitEffectVisitor>(func.address(), size);
|
||||
}
|
||||
}
|
@ -13,7 +13,8 @@
|
||||
"simpleini",
|
||||
"spdlog",
|
||||
"directxtk",
|
||||
"rapidcsv"
|
||||
"rapidcsv",
|
||||
"xbyak"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user