diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp index 1f11d7ed5..13315669c 100644 --- a/Dalamud.Boot/xivfixes.cpp +++ b/Dalamud.Boot/xivfixes.cpp @@ -493,6 +493,40 @@ void xivfixes::backup_userdata_save(bool bApply) { } } +void xivfixes::clr_failfast_hijack(bool bApply) +{ + static const char* LogTag = "[xivfixes:clr_failfast_hijack]"; + static std::optional> s_HookClrFatalError; + + if (bApply) + { + if (!g_startInfo.BootEnabledGameFixes.contains("clr_failfast_hijack")) { + logging::I("{} Turned off via environment variable.", LogTag); + return; + } + + s_HookClrFatalError.emplace("kernel32.dll!RaiseFailFastException (import, backup_userdata_save)", "kernel32.dll", "RaiseFailFastException", 0); + + s_HookClrFatalError->set_detour([](PEXCEPTION_RECORD pExceptionRecord, + _In_opt_ PCONTEXT pContextRecord, + _In_ DWORD dwFlags) + { + MessageBoxW(nullptr, L"An error in a Dalamud plugin was detected and the game cannot continue.\n\nPlease take a screenshot of this error message and let us know about it.", L"Dalamud", MB_OK | MB_ICONERROR); + + return s_HookClrFatalError->call_original(pExceptionRecord, pContextRecord, dwFlags); + }); + + logging::I("{} Enable", LogTag); + } + else + { + if (s_HookClrFatalError) { + logging::I("{} Disable ClrFatalError", LogTag); + s_HookClrFatalError.reset(); + } + } +} + void xivfixes::apply_all(bool bApply) { for (const auto& [taskName, taskFunction] : std::initializer_list> { @@ -501,6 +535,7 @@ void xivfixes::apply_all(bool bApply) { { "disable_game_openprocess_access_check", &disable_game_openprocess_access_check }, { "redirect_openprocess", &redirect_openprocess }, { "backup_userdata_save", &backup_userdata_save }, + { "clr_failfast_hijack", &clr_failfast_hijack } } ) { try { diff --git a/Dalamud.Boot/xivfixes.h b/Dalamud.Boot/xivfixes.h index 556c5422f..894c60880 100644 --- a/Dalamud.Boot/xivfixes.h +++ b/Dalamud.Boot/xivfixes.h @@ -6,6 +6,7 @@ namespace xivfixes { void disable_game_openprocess_access_check(bool bApply); void redirect_openprocess(bool bApply); void backup_userdata_save(bool bApply); + void clr_failfast_hijack(bool bApply); void apply_all(bool bApply); } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 2ef37e4b0..39aaebfc2 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -317,7 +317,7 @@ namespace Dalamud.Injector startInfo.BootShowConsole = args.Contains("--console"); startInfo.BootEnableEtw = args.Contains("--etw"); startInfo.BootLogPath = GetLogPath("dalamud.boot"); - startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save" }; + startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack" }; startInfo.BootDotnetOpenProcessHookMode = 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox2") ? 2 : 0;