Added light attach crash fix by powerofthree
This commit is contained in:
parent
fe6bfad3e9
commit
343039ddd8
@ -4,3 +4,4 @@ MapMarkerPlacementFixes = true
|
|||||||
AchievementFix = true
|
AchievementFix = true
|
||||||
VideoInterruptPatch = true
|
VideoInterruptPatch = true
|
||||||
ForceBorderless = true
|
ForceBorderless = true
|
||||||
|
AttachLightHitEffectCrashFix = true
|
||||||
|
@ -1 +1 @@
|
|||||||
version = 2.1.1
|
version = 2.1.2
|
||||||
|
@ -42,7 +42,7 @@ include(FetchContent)
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
CommonLibNG
|
CommonLibNG
|
||||||
GIT_REPOSITORY https://github.com/alandtse/CommonLibVR.git
|
GIT_REPOSITORY https://github.com/alandtse/CommonLibVR.git
|
||||||
GIT_TAG 735fa6dae8ec72966ee02673dd689c6516d49f71
|
GIT_TAG 5e5417e3585c9434295e919bdda27737244e9c5a
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ENABLE_SKYRIM_SE ON CACHE BOOL " " FORCE)
|
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(ENABLE_SKYRIM_VR ON CACHE BOOL " " FORCE)
|
||||||
set(BUILD_TESTS OFF CACHE BOOL " " FORCE)
|
set(BUILD_TESTS OFF CACHE BOOL " " FORCE)
|
||||||
|
|
||||||
#FetchContent_MakeAvailable(CommonLibNG)
|
FetchContent_MakeAvailable(CommonLibNG)
|
||||||
|
|
||||||
# Use a local copy instead
|
# 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)
|
#find_package(CommonLibSSE CONFIG REQUIRED)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "Patches/HeroMenuPatch.h"
|
#include "Patches/HeroMenuPatch.h"
|
||||||
#include "Patches/HUDMenuPatch.h"
|
#include "Patches/HUDMenuPatch.h"
|
||||||
#include "Patches/ForceBorderless.h"
|
#include "Patches/ForceBorderless.h"
|
||||||
|
#include "Patches/AttachLightHitEffectCrash.h"
|
||||||
|
|
||||||
using namespace SKSE;
|
using namespace SKSE;
|
||||||
|
|
||||||
@ -21,7 +22,8 @@ static std::map<std::string, bool> g_settings{
|
|||||||
{ "MapMarkerPlacementFixes", true },
|
{ "MapMarkerPlacementFixes", true },
|
||||||
{ "AchievementFix", true },
|
{ "AchievementFix", true },
|
||||||
{ "VideoInterruptPatch", true },
|
{ "VideoInterruptPatch", true },
|
||||||
{ "ForceBorderless", true }
|
{ "ForceBorderless", true },
|
||||||
|
{ "AttachLightHitEffectCrashFix", true }
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -213,6 +215,10 @@ SKSEPluginLoad(const LoadInterface* skse) {
|
|||||||
logger::info("Initializing Stay At The System Page...");
|
logger::info("Initializing Stay At The System Page...");
|
||||||
JournalMenuEx::InstallHooks();
|
JournalMenuEx::InstallHooks();
|
||||||
}
|
}
|
||||||
|
if (g_settings.at("AttachLightHitEffectCrashFix")) {
|
||||||
|
logger::info("Installing light attach crash fix...");
|
||||||
|
AttachLightHitEffectCrash::Install();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger::info("{} has finished loading.", plugin->GetName());
|
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/basic_file_sink.h>
|
||||||
#include <spdlog/sinks/msvc_sink.h>
|
#include <spdlog/sinks/msvc_sink.h>
|
||||||
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
// Compatible declarations with other sample projects.
|
// Compatible declarations with other sample projects.
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
@ -17,3 +18,14 @@ using namespace std::literals;
|
|||||||
using namespace REL::literals;
|
using namespace REL::literals;
|
||||||
|
|
||||||
namespace logger = SKSE::log;
|
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",
|
"simpleini",
|
||||||
"spdlog",
|
"spdlog",
|
||||||
"directxtk",
|
"directxtk",
|
||||||
"rapidcsv"
|
"rapidcsv",
|
||||||
|
"xbyak"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user