From eb44a02b06c44b4c27a81134eaac345dd03d34bb Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Sun, 19 Mar 2023 19:02:44 +0100 Subject: [PATCH 01/16] ci: delete artifact purge workflow --- .github/workflows/delete-artifacts.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/delete-artifacts.yml diff --git a/.github/workflows/delete-artifacts.yml b/.github/workflows/delete-artifacts.yml deleted file mode 100644 index 6191e6cba..000000000 --- a/.github/workflows/delete-artifacts.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Remove old artifacts - -on: - schedule: - # Every day at 1am - - cron: '0 1 * * *' - -jobs: - remove-old-artifacts: - runs-on: ubuntu-latest - timeout-minutes: 10 - - steps: - - name: Remove old artifacts - uses: c-hive/gha-remove-artifacts@v1.2.0 - with: - age: '1 month' - skip-tags: true - skip-recent: 3 From 6d41fa20b886ddc11830e1408a42454712cfb8bf Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 19 Mar 2023 19:05:16 +0100 Subject: [PATCH 02/16] feat: write revision to output folder --- Dalamud/Dalamud.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index beb14c61e..861d8d353 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -123,6 +123,7 @@ $(OutputPath)TEMP_gitver.txt + $(OutputPath)revision.txt @@ -134,6 +135,8 @@ $([System.Text.RegularExpressions.Regex]::Replace($(DalamudGitCommitCount), @"\t|\n|\r", "")) + + From 5a6ac8da07660cb5ff8e67a961eaac12bc9421f5 Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Sun, 19 Mar 2023 19:10:20 +0100 Subject: [PATCH 03/16] ci: add revision to version jsons --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ddc03558b..e3be36187 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,6 +71,7 @@ jobs: } $newVersion = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\TEMP_gitver.txt") + $revision = [System.IO.File]::ReadAllText("$(Get-Location)\scratch\revision.txt") Remove-Item -Force -Recurse .\scratch if (Test-Path -Path $branchName) { @@ -81,6 +82,7 @@ jobs: } else { Move-Item -Force ".\canary.zip" ".\${branchName}\latest.zip" $versionData.AssemblyVersion = $newVersion + $versionData.Revision = $revision $versionData | add-member -Force -Name "GitSha" $newVersion -MemberType NoteProperty $versionData | ConvertTo-Json -Compress | Out-File ".\${branchName}\version" } From 4f1257e79b244b29b53835bb284831973594ca9a Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Sun, 19 Mar 2023 19:23:04 +0100 Subject: [PATCH 04/16] ci: correctly add new member to json --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e3be36187..7ccf0c2d1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -82,8 +82,8 @@ jobs: } else { Move-Item -Force ".\canary.zip" ".\${branchName}\latest.zip" $versionData.AssemblyVersion = $newVersion - $versionData.Revision = $revision $versionData | add-member -Force -Name "GitSha" $newVersion -MemberType NoteProperty + $versionData | add-member -Force -Name "Revision" $revision -MemberType NoteProperty $versionData | ConvertTo-Json -Compress | Out-File ".\${branchName}\version" } From ec0f52b7c3e3efc40dfbec472a57e2465ac2568d Mon Sep 17 00:00:00 2001 From: goat Date: Mon, 20 Mar 2023 20:15:24 +0100 Subject: [PATCH 05/16] chore: don't report crashes when shutting down the game, if no devplugin is loaded --- .../Internal/DalamudConfiguration.cs | 5 +++++ Dalamud/Dalamud.cs | 11 ++++++++++ .../Interface/Internal/DalamudInterface.cs | 6 ++++++ DalamudCrashHandler/DalamudCrashHandler.cpp | 20 ++++++++++++++++++- 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index d2f8c4aa1..f6cf88d90 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -244,6 +244,11 @@ internal sealed class DalamudConfiguration : IServiceType /// public int? PluginWaitBeforeFree { get; set; } + /// + /// Gets or sets a value indicating whether or not crashes during shutdown should be reported. + /// + public bool ReportShutdownCrashes { get; set; } + /// /// Gets or sets a list of saved styles. /// diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index e78776955..73914d2a7 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -11,6 +11,7 @@ using Dalamud.Game.Gui.Internal; using Dalamud.Interface.Internal; using Dalamud.Plugin.Internal; using Dalamud.Utility; +using PInvoke; using Serilog; #if DEBUG @@ -103,6 +104,16 @@ internal sealed class Dalamud : IServiceType public void Unload() { Log.Information("Trigger unload"); + + var reportCrashesSetting = Service.GetNullable()?.ReportShutdownCrashes ?? true; + var pmHasDevPlugins = Service.GetNullable()?.InstalledPlugins.Any(x => x.IsDev) ?? false; + if (!reportCrashesSetting && !pmHasDevPlugins) + { + // Leaking on purpose for now + var attribs = Kernel32.SECURITY_ATTRIBUTES.Create(); + Kernel32.CreateMutex(attribs, false, "DALAMUD_CRASHES_NO_MORE"); + } + this.unloadSignal.Set(); } diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 3da633c86..45b31e7a8 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -759,6 +759,12 @@ internal class DalamudInterface : IDisposable, IServiceType } } + if (ImGui.MenuItem("Report crashes at shutdown", null, configuration.ReportShutdownCrashes)) + { + configuration.ReportShutdownCrashes = !configuration.ReportShutdownCrashes; + configuration.QueueSave(); + } + ImGui.Separator(); if (ImGui.MenuItem("Open Dalamud branch switcher")) diff --git a/DalamudCrashHandler/DalamudCrashHandler.cpp b/DalamudCrashHandler/DalamudCrashHandler.cpp index f31715c5e..18f7f0791 100644 --- a/DalamudCrashHandler/DalamudCrashHandler.cpp +++ b/DalamudCrashHandler/DalamudCrashHandler.cpp @@ -739,6 +739,11 @@ int main() { std::cout << "Crash triggered" << std::endl; + auto shutup_mutex = CreateMutex(NULL, false, L"DALAMUD_CRASHES_NO_MORE"); + bool shutup = false; + if (shutup_mutex == NULL && GetLastError() == ERROR_ALREADY_EXISTS) + shutup = true; + /* Hard won wisdom: changing symbol path with SymSetSearchPath() after modules have been loaded (invadeProcess=TRUE in SymInitialize() or SymRefreshModuleList()) @@ -795,7 +800,11 @@ int main() { std::wstring dumpError; if (dumpPath.empty()) { std::cout << "Skipping dump path, as log directory has not been specified" << std::endl; - } else { + } else if (shutup) { + std::cout << "Skipping dump, was shutdown" << std::endl; + } + else + { MINIDUMP_EXCEPTION_INFORMATION mdmp_info{}; mdmp_info.ThreadId = GetThreadId(exinfo.hThreadHandle); mdmp_info.ExceptionPointers = exinfo.pExceptionPointers; @@ -821,6 +830,10 @@ int main() { std::wostringstream log; log << std::format(L"Unhandled native exception occurred at {}", to_address_string(exinfo.ContextRecord.Rip, false)) << std::endl; log << std::format(L"Code: {:X}", exinfo.ExceptionRecord.ExceptionCode) << std::endl; + + if (shutup) + log << L"======= Crash handler was globally muted(shutdown?) =======" << std::endl; + if (dumpPath.empty()) log << L"Dump skipped" << std::endl; else if (dumpError.empty()) @@ -971,6 +984,11 @@ int main() { submitThread = {}; } + if (shutup) { + TerminateProcess(g_hProcess, exinfo.ExceptionRecord.ExceptionCode); + return 0; + } + int nButtonPressed = 0, nRadioButton = 0; if (FAILED(TaskDialogIndirect(&config, &nButtonPressed, &nRadioButton, nullptr))) { ResumeThread(exinfo.hThreadHandle); From ec4b5935d89ab4160c4853600dafabe8651e9792 Mon Sep 17 00:00:00 2001 From: goat Date: Tue, 21 Mar 2023 19:48:02 +0100 Subject: [PATCH 06/16] fix: specify a fallback value for chat channel settings entry --- .../Windows/Settings/Tabs/SettingsTabGeneral.cs | 3 ++- .../Windows/Settings/Widgets/SettingsEntry{T}.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabGeneral.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabGeneral.cs index 7b4e29980..53869ca16 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabGeneral.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabGeneral.cs @@ -27,7 +27,8 @@ public class SettingsTabGeneral : SettingsTab return Loc.Localize("DalamudSettingsChannelNone", "Do not pick \"None\"."); return null; - }), + }, + fallbackValue: XivChatType.Debug), new GapSettingsEntry(5), diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs index b5fada8fd..c8ebfca88 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs @@ -20,8 +20,10 @@ internal sealed class SettingsEntry : SettingsEntry private readonly Action? change; private object? valueBacking; + private object? fallbackValue; - public SettingsEntry(string name, string description, LoadSettingDelegate load, SaveSettingDelegate save, Action? change = null, Func? warning = null, Func? validity = null, Func? visibility = null) + public SettingsEntry(string name, string description, LoadSettingDelegate load, SaveSettingDelegate save, Action? change = null, Func? warning = null, Func? validity = null, Func? visibility = null, + object? fallbackValue = null) { this.load = load; this.save = save; @@ -31,6 +33,8 @@ internal sealed class SettingsEntry : SettingsEntry this.CheckWarning = warning; this.CheckValidity = validity; this.CheckVisibility = visibility; + + this.fallbackValue = fallbackValue; } public delegate T? LoadSettingDelegate(DalamudConfiguration config); @@ -97,6 +101,12 @@ internal sealed class SettingsEntry : SettingsEntry var descriptions = values.Cast().ToDictionary(x => x, x => x.GetAttribute() ?? new SettingsAnnotationAttribute(x.ToString(), string.Empty)); + if (!descriptions.ContainsKey(idx)) + { + idx = (Enum)this.fallbackValue ?? throw new Exception("No fallback value for enum"); + this.valueBacking = idx; + } + if (ImGui.BeginCombo($"###{this.Id.ToString()}", descriptions[idx].FriendlyName)) { foreach (Enum value in values) From 70d5cb5856c9a9e1d80c6641e5ec099dacdf0ac7 Mon Sep 17 00:00:00 2001 From: goat Date: Tue, 21 Mar 2023 19:49:00 +0100 Subject: [PATCH 07/16] build: 7.4.8.0 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index 861d8d353..eb5c1118c 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 7.4.7.5 + 7.4.8.0 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion) From 9169063e04550d5cf40c7137945af87ea8fb76fa Mon Sep 17 00:00:00 2001 From: marzent Date: Sat, 25 Mar 2023 22:17:08 +0100 Subject: [PATCH 08/16] add prevent_icmphandle_crashes xivfix --- Dalamud.Boot/xivfixes.cpp | 39 +++++++++++++++++++++++++++++++++- Dalamud.Boot/xivfixes.h | 1 + Dalamud.Injector/EntryPoint.cs | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp index 21786a4c1..e16dd6e5a 100644 --- a/Dalamud.Boot/xivfixes.cpp +++ b/Dalamud.Boot/xivfixes.cpp @@ -6,6 +6,8 @@ #include "hooks.h" #include "logging.h" #include "utils.h" +#include +#include template static std::span assume_nonempty_span(std::span t, const char* descr) { @@ -554,6 +556,40 @@ void xivfixes::clr_failfast_hijack(bool bApply) } } + +void xivfixes::prevent_icmphandle_crashes(bool bApply) { + static const char* LogTag = "[xivfixes:prevent_icmphandle_crashes]"; + + static std::optional> s_hookIcmpCloseHandle; + + if (bApply) { + if (!g_startInfo.BootEnabledGameFixes.contains("prevent_icmphandle_crashes")) { + logging::I("{} Turned off via environment variable.", LogTag); + return; + } + + s_hookIcmpCloseHandle.emplace("iphlpapi.dll!IcmpCloseHandle (import, prevent_icmphandle_crashes)", "iphlpapi.dll", "IcmpCloseHandle", 0); + + s_hookIcmpCloseHandle->set_detour([](HANDLE IcmpHandle) noexcept { + // this is exactly how windows behaves, however calling IcmpCloseHandle with + // an invalid handle will segfault on wine... + if (IcmpHandle == INVALID_HANDLE_VALUE) { + logging::W("{} IcmpCloseHandle was called with INVALID_HANDLE_VALUE", LogTag); + return FALSE; + } + return s_hookIcmpCloseHandle->call_original(IcmpHandle); + }); + + logging::I("{} Enable", LogTag); + } + else { + if (s_hookIcmpCloseHandle) { + logging::I("{} Disable", LogTag); + s_hookIcmpCloseHandle.reset(); + } + } +} + void xivfixes::apply_all(bool bApply) { for (const auto& [taskName, taskFunction] : std::initializer_list> { @@ -562,7 +598,8 @@ 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 } + { "clr_failfast_hijack", &clr_failfast_hijack }, + { "prevent_icmphandle_crashes", &prevent_icmphandle_crashes } } ) { try { diff --git a/Dalamud.Boot/xivfixes.h b/Dalamud.Boot/xivfixes.h index 894c60880..701913c88 100644 --- a/Dalamud.Boot/xivfixes.h +++ b/Dalamud.Boot/xivfixes.h @@ -7,6 +7,7 @@ namespace xivfixes { void redirect_openprocess(bool bApply); void backup_userdata_save(bool bApply); void clr_failfast_hijack(bool bApply); + void prevent_icmphandle_crashes(bool bApply); void apply_all(bool bApply); } diff --git a/Dalamud.Injector/EntryPoint.cs b/Dalamud.Injector/EntryPoint.cs index 5ca1bfa12..c29fada83 100644 --- a/Dalamud.Injector/EntryPoint.cs +++ b/Dalamud.Injector/EntryPoint.cs @@ -325,7 +325,7 @@ namespace Dalamud.Injector startInfo.BootShowConsole = args.Contains("--console"); startInfo.BootEnableEtw = args.Contains("--etw"); startInfo.BootLogPath = GetLogPath("dalamud.boot", startInfo.LogName); - startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack" }; + startInfo.BootEnabledGameFixes = new List { "prevent_devicechange_crashes", "disable_game_openprocess_access_check", "redirect_openprocess", "backup_userdata_save", "clr_failfast_hijack", "prevent_icmphandle_crashes" }; startInfo.BootDotnetOpenProcessHookMode = 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox1") ? 1 : 0; startInfo.BootWaitMessageBox |= args.Contains("--msgbox2") ? 2 : 0; From 14ce85627de373df72c262ead31206c3a2abacfa Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 26 Mar 2023 00:22:09 +0100 Subject: [PATCH 09/16] fix: correctly enqueue textures for destroy if they're GC'd --- .../Interface/Internal/DalamudTextureWrap.cs | 19 ++++++++++++++++++- .../Interface/Internal/InterfaceManager.cs | 12 ++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Dalamud/Interface/Internal/DalamudTextureWrap.cs b/Dalamud/Interface/Internal/DalamudTextureWrap.cs index 346b7cd24..97fb1dd0b 100644 --- a/Dalamud/Interface/Internal/DalamudTextureWrap.cs +++ b/Dalamud/Interface/Internal/DalamudTextureWrap.cs @@ -21,6 +21,14 @@ public class DalamudTextureWrap : TextureWrap this.wrappedWrap = wrappingWrap; } + /// + /// Finalizes an instance of the class. + /// + ~DalamudTextureWrap() + { + this.Dispose(false); + } + /// /// Gets the ImGui handle of the texture. /// @@ -41,7 +49,8 @@ public class DalamudTextureWrap : TextureWrap /// public void Dispose() { - Service.Get().EnqueueDeferredDispose(this); + this.Dispose(true); + GC.SuppressFinalize(this); } /// @@ -51,4 +60,12 @@ public class DalamudTextureWrap : TextureWrap { this.wrappedWrap.Dispose(); } + + private void Dispose(bool disposing) + { + if (disposing) + { + Service.GetNullable()?.EnqueueDeferredDispose(this); + } + } } diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index aa721ad39..9a8da773c 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -606,12 +606,16 @@ internal class InterfaceManager : IDisposable, IServiceType this.RenderImGui(); - foreach (var texture in this.deferredDisposeTextures) + if (this.deferredDisposeTextures.Count > 0) { - texture.RealDispose(); - } + Log.Verbose("[IM] Disposing {Count} textures", this.deferredDisposeTextures.Count); + foreach (var texture in this.deferredDisposeTextures) + { + texture.RealDispose(); + } - this.deferredDisposeTextures.Clear(); + this.deferredDisposeTextures.Clear(); + } return this.presentHook.Original(swapChain, syncInterval, presentFlags); } From 1ce98a235053bbe2a6ffa998f2dd175b402abbdd Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 26 Mar 2023 00:38:34 +0100 Subject: [PATCH 10/16] chore: some imraii conversion --- Dalamud/Interface/ImGuiHelpers.cs | 8 ++- .../Interface/Internal/DalamudInterface.cs | 30 ++++---- .../Windows/Settings/SettingsWindow.cs | 27 +++---- .../Windows/Settings/Tabs/SettingsTabAbout.cs | 72 +++++++++---------- .../Widgets/DevPluginsSettingsEntry.cs | 10 +-- .../Settings/Widgets/SettingsEntry{T}.cs | 25 ++++--- .../Widgets/ThirdRepoSettingsEntry.cs | 10 +-- .../Internal/Windows/TitleScreenMenuWindow.cs | 42 +++++------ 8 files changed, 115 insertions(+), 109 deletions(-) diff --git a/Dalamud/Interface/ImGuiHelpers.cs b/Dalamud/Interface/ImGuiHelpers.cs index 396a3b007..2356d90e2 100644 --- a/Dalamud/Interface/ImGuiHelpers.cs +++ b/Dalamud/Interface/ImGuiHelpers.cs @@ -5,6 +5,7 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using Dalamud.Game.ClientState.Keys; +using Dalamud.Interface.Raii; using ImGuiNET; using ImGuiScene; @@ -161,9 +162,10 @@ public static class ImGuiHelpers /// The text to write. public static void SafeTextColoredWrapped(Vector4 color, string text) { - ImGui.PushStyleColor(ImGuiCol.Text, color); - ImGui.TextWrapped(text.Replace("%", "%%")); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, color)) + { + ImGui.TextWrapped(text.Replace("%", "%%")); + } } /// diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs index 45b31e7a8..8848cd481 100644 --- a/Dalamud/Interface/Internal/DalamudInterface.cs +++ b/Dalamud/Interface/Internal/DalamudInterface.cs @@ -20,6 +20,7 @@ using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.Interface.Internal.Windows.SelfTest; using Dalamud.Interface.Internal.Windows.Settings; using Dalamud.Interface.Internal.Windows.StyleEditor; +using Dalamud.Interface.Raii; using Dalamud.Interface.Style; using Dalamud.Interface.Windowing; using Dalamud.Logging; @@ -522,7 +523,8 @@ internal class DalamudInterface : IDisposable, IServiceType private void DrawCreditsDarkeningAnimation() { - ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0f); + using var style = ImRaii.PushStyle(ImGuiStyleVar.WindowRounding, 0f); + ImGui.SetNextWindowPos(new Vector2(0, 0)); ImGui.SetNextWindowSize(ImGuiHelpers.MainViewport.Size); ImGuiHelpers.ForceNextWindowMainViewport(); @@ -536,8 +538,6 @@ internal class DalamudInterface : IDisposable, IServiceType ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoBringToFrontOnFocus | ImGuiWindowFlags.NoNav); ImGui.End(); - - ImGui.PopStyleVar(); } private void DrawHiddenDevMenuOpener() @@ -546,18 +546,17 @@ internal class DalamudInterface : IDisposable, IServiceType if (!this.isImGuiDrawDevMenu && !condition.Any()) { - ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero); - ImGui.PushStyleColor(ImGuiCol.ButtonActive, Vector4.Zero); - ImGui.PushStyleColor(ImGuiCol.ButtonHovered, Vector4.Zero); - ImGui.PushStyleColor(ImGuiCol.TextSelectedBg, new Vector4(0, 0, 0, 1)); - ImGui.PushStyleColor(ImGuiCol.Border, new Vector4(0, 0, 0, 1)); - ImGui.PushStyleColor(ImGuiCol.BorderShadow, new Vector4(0, 0, 0, 1)); - ImGui.PushStyleColor(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 1)); + using var color = ImRaii.PushColor(ImGuiCol.Button, Vector4.Zero); + color.Push(ImGuiCol.ButtonActive, Vector4.Zero); + color.Push(ImGuiCol.ButtonHovered, Vector4.Zero); + color.Push(ImGuiCol.TextSelectedBg, new Vector4(0, 0, 0, 1)); + color.Push(ImGuiCol.Border, new Vector4(0, 0, 0, 1)); + color.Push(ImGuiCol.BorderShadow, new Vector4(0, 0, 0, 1)); + color.Push(ImGuiCol.WindowBg, new Vector4(0, 0, 0, 1)); - ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); - ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero); - ImGui.PushStyleVar(ImGuiStyleVar.WindowBorderSize, 0); - ImGui.PushStyleVar(ImGuiStyleVar.FrameBorderSize, 0); + using var style = ImRaii.PushStyle(ImGuiStyleVar.WindowPadding, Vector2.Zero); + style.Push(ImGuiStyleVar.WindowBorderSize, 0); + style.Push(ImGuiStyleVar.FrameBorderSize, 0); var windowPos = ImGui.GetMainViewport().Pos + new Vector2(20); ImGui.SetNextWindowPos(windowPos, ImGuiCond.Always); @@ -589,9 +588,6 @@ internal class DalamudInterface : IDisposable, IServiceType ImGui.End(); } - - ImGui.PopStyleVar(4); - ImGui.PopStyleColor(7); } } diff --git a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs index 519a0dc58..6dbf902eb 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/SettingsWindow.cs @@ -5,6 +5,7 @@ using CheapLoc; using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; using Dalamud.Interface.Internal.Windows.Settings.Tabs; +using Dalamud.Interface.Raii; using Dalamud.Interface.Windowing; using Dalamud.Plugin.Internal; using Dalamud.Utility; @@ -159,33 +160,27 @@ internal class SettingsWindow : Window if (ImGui.BeginChild("###settingsFinishButton")) { - ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 100f); - ImGui.PushFont(InterfaceManager.IconFont); + using var disabled = ImRaii.Disabled(this.tabs.Any(x => x.Entries.Any(y => !y.IsValid))); - var invalid = this.tabs.Any(x => x.Entries.Any(y => !y.IsValid)); - if (invalid) - ImGui.BeginDisabled(); - - if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40))) + using (ImRaii.PushStyle(ImGuiStyleVar.FrameRounding, 100f)) { - this.Save(); + using var font = ImRaii.PushFont(InterfaceManager.IconFont); - if (!ImGui.IsKeyDown(ImGuiKey.ModShift)) - this.IsOpen = false; + if (ImGui.Button(FontAwesomeIcon.Save.ToIconString(), new Vector2(40))) + { + this.Save(); + + if (!ImGui.IsKeyDown(ImGuiKey.ModShift)) + this.IsOpen = false; + } } - ImGui.PopStyleVar(); - ImGui.PopFont(); - if (ImGui.IsItemHovered()) { ImGui.SetTooltip(!ImGui.IsKeyDown(ImGuiKey.ModShift) ? Loc.Localize("DalamudSettingsSaveAndExit", "Save changes and close") : Loc.Localize("DalamudSettingsSaveAndExit", "Save changes")); } - - if (invalid) - ImGui.EndDisabled(); } ImGui.EndChild(); diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs index b0f3e7e02..325d0b8b7 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabAbout.cs @@ -8,6 +8,7 @@ using System.Numerics; using CheapLoc; using Dalamud.Game.Gui; using Dalamud.Interface.GameFonts; +using Dalamud.Interface.Raii; using Dalamud.Plugin.Internal; using Dalamud.Utility; using FFXIVClientStructs.FFXIV.Client.Game.UI; @@ -243,46 +244,45 @@ Contribute at: https://github.com/goatcorp/Dalamud this.resetNow = false; } - ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); - - ImGuiHelpers.ScaledDummy(0, windowSize.Y + 20f); - ImGui.Text(string.Empty); - - const float imageSize = 190f; - ImGui.SameLine((ImGui.GetWindowWidth() / 2) - (imageSize / 2)); - ImGui.Image(this.logoTexture.ImGuiHandle, ImGuiHelpers.ScaledVector2(imageSize)); - - ImGuiHelpers.ScaledDummy(0, 20f); - - var windowX = ImGui.GetWindowSize().X; - - foreach (var creditsLine in this.creditsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)) + using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)) { - var lineLenX = ImGui.CalcTextSize(creditsLine).X; + ImGuiHelpers.ScaledDummy(0, windowSize.Y + 20f); + ImGui.Text(string.Empty); - ImGui.Dummy(new Vector2((windowX / 2) - (lineLenX / 2), 0f)); - ImGui.SameLine(); - ImGui.TextUnformatted(creditsLine); + const float imageSize = 190f; + ImGui.SameLine((ImGui.GetWindowWidth() / 2) - (imageSize / 2)); + ImGui.Image(this.logoTexture.ImGuiHandle, ImGuiHelpers.ScaledVector2(imageSize)); + + ImGuiHelpers.ScaledDummy(0, 20f); + + var windowX = ImGui.GetWindowSize().X; + + foreach (var creditsLine in this.creditsText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)) + { + var lineLenX = ImGui.CalcTextSize(creditsLine).X; + + ImGui.Dummy(new Vector2((windowX / 2) - (lineLenX / 2), 0f)); + ImGui.SameLine(); + ImGui.TextUnformatted(creditsLine); + } + + ImGuiHelpers.ScaledDummy(0, 40f); + + if (this.thankYouFont != null) + { + ImGui.PushFont(this.thankYouFont.ImFont); + var thankYouLenX = ImGui.CalcTextSize(ThankYouText).X; + + ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f)); + ImGui.SameLine(); + ImGui.TextUnformatted(ThankYouText); + + ImGui.PopFont(); + } + + ImGuiHelpers.ScaledDummy(0, windowSize.Y + 50f); } - ImGuiHelpers.ScaledDummy(0, 40f); - - if (this.thankYouFont != null) - { - ImGui.PushFont(this.thankYouFont.ImFont); - var thankYouLenX = ImGui.CalcTextSize(ThankYouText).X; - - ImGui.Dummy(new Vector2((windowX / 2) - (thankYouLenX / 2), 0f)); - ImGui.SameLine(); - ImGui.TextUnformatted(ThankYouText); - - ImGui.PopFont(); - } - - ImGuiHelpers.ScaledDummy(0, windowSize.Y + 50f); - - ImGui.PopStyleVar(); - if (this.creditsThrottler.Elapsed.TotalMilliseconds > (1000.0f / CreditFps)) { var curY = ImGui.GetScrollY(); diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs index b1a231335..1973a305e 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/DevPluginsSettingsEntry.cs @@ -10,6 +10,7 @@ using Dalamud.Configuration; using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; +using Dalamud.Interface.Raii; using Dalamud.Plugin.Internal; using ImGuiNET; @@ -57,10 +58,11 @@ public class DevPluginsSettingsEntry : SettingsEntry ImGui.Text(this.Name); if (this.devPluginLocationsChanged) { - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen); - ImGui.SameLine(); - ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)")); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen)) + { + ImGui.SameLine(); + ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)")); + } } ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingsDevPluginLocationsHint", "Add additional dev plugin load locations.\nThese can be either the directory or DLL path.")); diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs index c8ebfca88..5937ea706 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs @@ -7,6 +7,7 @@ using System.Linq; using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; +using Dalamud.Interface.Raii; using Dalamud.Utility; using ImGuiNET; @@ -121,9 +122,11 @@ internal sealed class SettingsEntry : SettingsEntry } } - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudGrey); - ImGuiHelpers.SafeTextWrapped(this.Description); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudGrey)) + { + ImGuiHelpers.SafeTextWrapped(this.Description); + ImGui.PopStyleColor(); + } if (this.CheckValidity != null) { @@ -132,9 +135,11 @@ internal sealed class SettingsEntry : SettingsEntry if (!this.IsValid) { - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); - ImGui.Text(validityMsg); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed)) + { + ImGui.Text(validityMsg); + ImGui.PopStyleColor(); + } } } else @@ -146,9 +151,11 @@ internal sealed class SettingsEntry : SettingsEntry if (warningMessage != null) { - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); - ImGui.Text(warningMessage); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed)) + { + ImGui.Text(warningMessage); + ImGui.PopStyleColor(); + } } } diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/ThirdRepoSettingsEntry.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/ThirdRepoSettingsEntry.cs index 37876811f..3a1601e14 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/ThirdRepoSettingsEntry.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/ThirdRepoSettingsEntry.cs @@ -10,6 +10,7 @@ using Dalamud.Configuration; using Dalamud.Configuration.Internal; using Dalamud.Interface.Colors; using Dalamud.Interface.Components; +using Dalamud.Interface.Raii; using Dalamud.Plugin.Internal; using ImGuiNET; @@ -53,10 +54,11 @@ public class ThirdRepoSettingsEntry : SettingsEntry ImGui.Text(Loc.Localize("DalamudSettingsCustomRepo", "Custom Plugin Repositories")); if (this.thirdRepoListChanged) { - ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen); - ImGui.SameLine(); - ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)")); - ImGui.PopStyleColor(); + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen)) + { + ImGui.SameLine(); + ImGui.Text(Loc.Localize("DalamudSettingsChanged", "(Changed)")); + } } ImGuiHelpers.SafeTextColoredWrapped(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingCustomRepoHint", "Add custom plugin repositories.")); diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs index 284559a4e..3c70c644c 100644 --- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs +++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs @@ -9,6 +9,7 @@ using Dalamud.Game; using Dalamud.Game.ClientState; using Dalamud.Game.Gui; using Dalamud.Interface.Animation.EasingFunctions; +using Dalamud.Interface.Raii; using Dalamud.Interface.Windowing; using ImGuiNET; using ImGuiScene; @@ -169,23 +170,22 @@ internal class TitleScreenMenuWindow : Window, IDisposable this.fadeOutEasing.Update(); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value); - - for (var i = 0; i < tsm.Entries.Count; i++) + using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value)) { - var entry = tsm.Entries[i]; + for (var i = 0; i < tsm.Entries.Count; i++) + { + var entry = tsm.Entries[i]; - var finalPos = (i + 1) * this.shadeTexture.Height * scale; + var finalPos = (i + 1) * this.shadeTexture.Height * scale; - this.DrawEntry(entry, i != 0, true, i == 0, false, false); + this.DrawEntry(entry, i != 0, true, i == 0, false, false); - var cursor = ImGui.GetCursorPos(); - cursor.Y = finalPos; - ImGui.SetCursorPos(cursor); + var cursor = ImGui.GetCursorPos(); + cursor.Y = finalPos; + ImGui.SetCursorPos(cursor); + } } - ImGui.PopStyleVar(); - var isHover = ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | ImGuiHoveredFlags.AllowWhenBlockedByActiveItem); @@ -254,9 +254,11 @@ internal class TitleScreenMenuWindow : Window, IDisposable var initialCursor = ImGui.GetCursorPos(); - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)shadeEasing.Value); - ImGui.Image(this.shadeTexture.ImGuiHandle, new Vector2(this.shadeTexture.Width * scale, this.shadeTexture.Height * scale)); - ImGui.PopStyleVar(); + + using (ImRaii.PushStyle(ImGuiStyleVar.Alpha, (float)shadeEasing.Value)) + { + ImGui.Image(this.shadeTexture.ImGuiHandle, new Vector2(this.shadeTexture.Width * scale, this.shadeTexture.Height * scale)); + } var isHover = ImGui.IsItemHovered(); if (isHover && (!shadeEasing.IsRunning || (shadeEasing.IsDone && shadeEasing.IsInverse)) && !inhibitFadeout) @@ -331,15 +333,15 @@ internal class TitleScreenMenuWindow : Window, IDisposable } // Drop shadow - ImGui.PushStyleColor(ImGuiCol.Text, 0xFF000000); - for (int i = 0, i_ = (int)Math.Ceiling(1 * scale); i < i_; i++) + using (ImRaii.PushColor(ImGuiCol.Text, 0xFF000000)) { - ImGui.SetCursorPos(new Vector2(cursor.X, cursor.Y + i)); - ImGui.Text(entry.Name); + for (int i = 0, i_ = (int)Math.Ceiling(1 * scale); i < i_; i++) + { + ImGui.SetCursorPos(new Vector2(cursor.X, cursor.Y + i)); + ImGui.Text(entry.Name); + } } - ImGui.PopStyleColor(); - ImGui.SetCursorPos(cursor); ImGui.Text(entry.Name); From 193f9c886946d85dbbcc58c3f5fa301b4eb5a880 Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 26 Mar 2023 00:39:27 +0100 Subject: [PATCH 11/16] fix: orphaned plugins can never accept feedback --- .../Windows/PluginInstaller/PluginInstallerWindow.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs index c7847f58e..a2126089b 100644 --- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs +++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs @@ -2087,7 +2087,12 @@ internal class PluginInstallerWindow : Window, IDisposable ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadText); var isThirdParty = manifest.IsThirdParty; - var canFeedback = !isThirdParty && !plugin.IsDev && plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel && plugin.Manifest.AcceptsFeedback && availablePluginUpdate == default; + var canFeedback = !isThirdParty && + !plugin.IsDev && + !plugin.IsOrphaned && + plugin.Manifest.DalamudApiLevel == PluginManager.DalamudApiLevel && + plugin.Manifest.AcceptsFeedback && + availablePluginUpdate == default; // Installed from if (plugin.IsDev) From 4fb232e55f8530a43d369db01d0fbc4c0418a884 Mon Sep 17 00:00:00 2001 From: Aireil <33433913+Aireil@users.noreply.github.com> Date: Sun, 26 Mar 2023 00:50:25 +0100 Subject: [PATCH 12/16] chore: remove icon for changelogs --- Dalamud/Plugin/Internal/PluginManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dalamud/Plugin/Internal/PluginManager.cs b/Dalamud/Plugin/Internal/PluginManager.cs index 164aa083f..311172c97 100644 --- a/Dalamud/Plugin/Internal/PluginManager.cs +++ b/Dalamud/Plugin/Internal/PluginManager.cs @@ -251,7 +251,7 @@ Thanks and have fun!"; new TextPayload(" ["), new UIForegroundPayload(500), this.openInstallerWindowPluginChangelogsLink, - new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs") + " "), + new TextPayload(Loc.Localize("DalamudInstallerPluginChangelogHelp", "Open plugin changelogs")), RawPayload.LinkTerminator, new UIForegroundPayload(0), new TextPayload("]"), @@ -262,13 +262,13 @@ Thanks and have fun!"; { if (metadata.WasUpdated) { - chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty)); + chatGui.Print(Locs.DalamudPluginUpdateSuccessful(metadata.Name, metadata.Version)); } else { chatGui.PrintChat(new XivChatEntry { - Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version) + (metadata.HasChangelog ? " " : string.Empty), + Message = Locs.DalamudPluginUpdateFailed(metadata.Name, metadata.Version), Type = XivChatType.Urgent, }); } From ca9f932213fef38b422585bc48b71a39d34b9add Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 26 Mar 2023 01:31:34 +0100 Subject: [PATCH 13/16] fix: only hook reshade swapchain funcs if it's actually reshade --- Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs index ce42f6265..603324175 100644 --- a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs +++ b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs @@ -61,6 +61,14 @@ public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressRes { if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll")) { + var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName); + + if (fileInfo.FileDescription == null) + break; + + if (!fileInfo.FileDescription.Contains("GShade") && !fileInfo.FileDescription.Contains("ReShade")) + break; + // reshade master@4232872 RVA // var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present // var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present @@ -72,8 +80,6 @@ public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressRes try { - var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName); - // Looks like this sig only works for GShade 4 if (fileInfo.FileDescription?.Contains("GShade 4.") == true) { From 03a409306f31b7a622b4c07fd407cabb62b1fa6a Mon Sep 17 00:00:00 2001 From: goat Date: Sun, 26 Mar 2023 13:07:26 +0200 Subject: [PATCH 14/16] fix: remove some unnecessary pops I missed --- .../Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs index 5937ea706..6352d7b69 100644 --- a/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs +++ b/Dalamud/Interface/Internal/Windows/Settings/Widgets/SettingsEntry{T}.cs @@ -125,7 +125,6 @@ internal sealed class SettingsEntry : SettingsEntry using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudGrey)) { ImGuiHelpers.SafeTextWrapped(this.Description); - ImGui.PopStyleColor(); } if (this.CheckValidity != null) @@ -138,7 +137,6 @@ internal sealed class SettingsEntry : SettingsEntry using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed)) { ImGui.Text(validityMsg); - ImGui.PopStyleColor(); } } } @@ -154,7 +152,6 @@ internal sealed class SettingsEntry : SettingsEntry using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudRed)) { ImGui.Text(warningMessage); - ImGui.PopStyleColor(); } } } From 9ff7eb801feabb1411c63776fbaeb1695edcb106 Mon Sep 17 00:00:00 2001 From: goat Date: Mon, 27 Mar 2023 19:43:29 +0200 Subject: [PATCH 15/16] feat: add GameLifecycle service --- Dalamud/Game/ClientState/ClientState.cs | 8 +++- Dalamud/Game/Framework.cs | 11 ++++- Dalamud/Game/GameLifecycle.cs | 63 +++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 Dalamud/Game/GameLifecycle.cs diff --git a/Dalamud/Game/ClientState/ClientState.cs b/Dalamud/Game/ClientState/ClientState.cs index cacb42c0a..1f72d853f 100644 --- a/Dalamud/Game/ClientState/ClientState.cs +++ b/Dalamud/Game/ClientState/ClientState.cs @@ -23,6 +23,7 @@ namespace Dalamud.Game.ClientState; [ServiceManager.BlockingEarlyLoadedService] public sealed class ClientState : IDisposable, IServiceType { + private readonly GameLifecycle lifecycle; private readonly ClientStateAddressResolver address; private readonly Hook setupTerritoryTypeHook; @@ -36,8 +37,9 @@ public sealed class ClientState : IDisposable, IServiceType private bool lastFramePvP = false; [ServiceManager.ServiceConstructor] - private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo) + private ClientState(SigScanner sigScanner, DalamudStartInfo startInfo, GameLifecycle lifecycle) { + this.lifecycle = lifecycle; this.address = new ClientStateAddressResolver(); this.address.Setup(sigScanner); @@ -174,6 +176,8 @@ public sealed class ClientState : IDisposable, IServiceType this.IsLoggedIn = true; this.Login?.InvokeSafely(this, null); gameGui.ResetUiHideState(); + + this.lifecycle.ResetLogout(); } if (!condition.Any() && this.lastConditionNone == false) @@ -183,6 +187,8 @@ public sealed class ClientState : IDisposable, IServiceType this.IsLoggedIn = false; this.Logout?.InvokeSafely(this, null); gameGui.ResetUiHideState(); + + this.lifecycle.SetLogout(); } this.IsPvP = GameMain.IsInPvPArea(); diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs index f2c65723c..21bd9e646 100644 --- a/Dalamud/Game/Framework.cs +++ b/Dalamud/Game/Framework.cs @@ -25,6 +25,8 @@ namespace Dalamud.Game; [ServiceManager.BlockingEarlyLoadedService] public sealed class Framework : IDisposable, IServiceType { + private readonly GameLifecycle lifecycle; + private static Stopwatch statsStopwatch = new(); private readonly Stopwatch updateStopwatch = new(); @@ -41,10 +43,11 @@ public sealed class Framework : IDisposable, IServiceType [ServiceManager.ServiceDependency] private readonly DalamudConfiguration configuration = Service.Get(); - + [ServiceManager.ServiceConstructor] - private Framework(SigScanner sigScanner) + private Framework(SigScanner sigScanner, GameLifecycle lifecycle) { + this.lifecycle = lifecycle; this.hitchDetector = new HitchDetector("FrameworkUpdate", this.configuration.FrameworkUpdateHitch); this.Address = new FrameworkAddressResolver(); @@ -489,6 +492,10 @@ public sealed class Framework : IDisposable, IServiceType this.IsFrameworkUnloading = true; this.DispatchUpdateEvents = false; + // All the same, for now... + this.lifecycle.SetShuttingDown(); + this.lifecycle.SetUnloading(); + Log.Information("Framework::Destroy!"); Service.Get().Unload(); this.RunPendingTickTasks(); diff --git a/Dalamud/Game/GameLifecycle.cs b/Dalamud/Game/GameLifecycle.cs new file mode 100644 index 000000000..3a6733512 --- /dev/null +++ b/Dalamud/Game/GameLifecycle.cs @@ -0,0 +1,63 @@ +using System.Threading; + +using Dalamud.IoC; +using Dalamud.IoC.Internal; + +namespace Dalamud.Game; + +/// +/// Class offering cancellation tokens for common gameplay events. +/// +[PluginInterface] +[InterfaceVersion("1.0")] +[ServiceManager.BlockingEarlyLoadedService] +public class GameLifecycle : IServiceType +{ + private readonly CancellationTokenSource dalamudUnloadCts = new(); + private readonly CancellationTokenSource gameShutdownCts = new(); + + private CancellationTokenSource logoutCts = new(); + + /// + /// Initializes a new instance of the class. + /// + [ServiceManager.ServiceConstructor] + internal GameLifecycle() + { + } + + /// + /// Gets a token that is cancelled when Dalamud is unloading. + /// + public CancellationToken DalamudUnloadingToken => this.dalamudUnloadCts.Token; + + /// + /// Gets a token that is cancelled when the game is shutting down. + /// + public CancellationToken GameShuttingDownToken => this.gameShutdownCts.Token; + + /// + /// Gets a token that is cancelled when a character is logging out. + /// + public CancellationToken LogoutToken => this.logoutCts.Token; + + /// + /// Mark an unload. + /// + internal void SetUnloading() => this.dalamudUnloadCts.Cancel(); + + /// + /// Mark a shutdown. + /// + internal void SetShuttingDown() => this.gameShutdownCts.Cancel(); + + /// + /// Mark a logout. + /// + internal void SetLogout() => this.logoutCts.Cancel(); + + /// + /// Unmark a logout. + /// + internal void ResetLogout() => this.logoutCts = new(); +} From c526c9454513ef6582ae15ffddd712cc995bfd6d Mon Sep 17 00:00:00 2001 From: goat <16760685+goaaats@users.noreply.github.com> Date: Tue, 28 Mar 2023 20:08:36 +0200 Subject: [PATCH 16/16] build: 7.4.9.0 --- Dalamud/Dalamud.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dalamud/Dalamud.csproj b/Dalamud/Dalamud.csproj index eb5c1118c..63b66f3b6 100644 --- a/Dalamud/Dalamud.csproj +++ b/Dalamud/Dalamud.csproj @@ -8,7 +8,7 @@ - 7.4.8.0 + 7.4.9.0 XIV Launcher addon framework $(DalamudVersion) $(DalamudVersion)