From 103556bd5ede0fdb92c4f1124f9ad2197a5edc66 Mon Sep 17 00:00:00 2001 From: Jade Macho Date: Sun, 6 Jul 2025 16:04:03 +0200 Subject: [PATCH] config: Add "Game hang protection" (auto-disable on 1s+ hangs) --- CustomResolution2782/Configuration.cs | 3 +- CustomResolution2782/ConfigurationV1.cs | 2 +- CustomResolution2782/Plugin.cs | 53 +++++++++++--------- CustomResolution2782/Service.cs | 3 ++ CustomResolution2782/Windows/ConfigWindow.cs | 13 +++++ 5 files changed, 49 insertions(+), 25 deletions(-) diff --git a/CustomResolution2782/Configuration.cs b/CustomResolution2782/Configuration.cs index 3935425..8bf9d70 100644 --- a/CustomResolution2782/Configuration.cs +++ b/CustomResolution2782/Configuration.cs @@ -59,7 +59,8 @@ public class Configuration : IPluginConfiguration { Service.PluginLog.Info("Migrating config V0 to V1"); V1 = new(); - // V1.Display.IsEnabled = IsEnabled; // Was enabled by default before, but let's disable. + // V1.Display.IsEnabled = IsEnabled; + // ... was enabled by default before, but let's disable for the migration. V1.Display.IsScale = IsScale; V1.Display.Scale = Scale; V1.Display.Width = Width; diff --git a/CustomResolution2782/ConfigurationV1.cs b/CustomResolution2782/ConfigurationV1.cs index 8c401ff..28ebe61 100644 --- a/CustomResolution2782/ConfigurationV1.cs +++ b/CustomResolution2782/ConfigurationV1.cs @@ -12,6 +12,7 @@ public struct ConfigurationV1 public ResolutionScalingMode ResolutionScalingMode = ResolutionScalingMode.FSR; public DXVKDWMHackMode DXVKDWMHackMode = DXVKDWMHackMode.Off; public MinSizeMode MinSizeMode = MinSizeMode.Unchanged; + public bool DisableOnHang = true; public ConfigurationV1() { @@ -38,7 +39,6 @@ public struct ConfigurationV1 public VirtualKey HotkeyKey = VirtualKey.NO_KEY; public ModifierKey HotkeyModifier = ModifierKey.NONE; - [NonSerialized] public bool HotkeyKeyDown = false; diff --git a/CustomResolution2782/Plugin.cs b/CustomResolution2782/Plugin.cs index c4785c9..62893ca 100644 --- a/CustomResolution2782/Plugin.cs +++ b/CustomResolution2782/Plugin.cs @@ -2,6 +2,7 @@ using Dalamud.Game.Config; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using FFXIVClientStructs.FFXIV.Client.System.Framework; using ImGuiNET; using System; using System.Collections.Generic; @@ -78,40 +79,46 @@ public sealed unsafe class Plugin : IDalamudPlugin Service.PluginUI.Dispose(); } - private void OnFrameworkUpdateForSize(ref ConfigurationV1.SizeConfig size) + private void OnFrameworkUpdateForSize(IFramework framework, string type, ref ConfigurationV1.SizeConfig size) { - if (size.HotkeyKey == VirtualKey.NO_KEY) + if (Service.ClientState.IsLoggedIn && framework.UpdateDelta.TotalSeconds >= 1 && Service.Config._.DisableOnHang && size.IsEnabled) { - return; - } - - var io = ImGui.GetIO(); - var keyPressedIm = ImGuiNative.igIsKeyPressed((ImGuiKey) size.HotkeyKey, 0) != 0; - var keyDownXiv = Service.KeyState.GetRawValue(size.HotkeyKey) != 0; - - if ((keyPressedIm || (keyDownXiv && !size.HotkeyKeyDown)) && - (size.HotkeyModifier switch - { - ModifierKey.NONE => !io.KeyCtrl && !io.KeyAlt && !io.KeyShift, - ModifierKey.CTRL => io.KeyCtrl && !io.KeyAlt && !io.KeyShift, - ModifierKey.ALT => !io.KeyCtrl && io.KeyAlt && !io.KeyShift, - ModifierKey.SHIFT => !io.KeyCtrl && !io.KeyAlt && io.KeyShift, - _ => false, - })) - { - size.IsEnabled = !size.IsEnabled; + Service.PluginLog.Warning($"Disabling because hang: {type}"); + Service.PrintChat($"Lag detected, \"{type}\" custom resolution disabled."); + size.IsEnabled = false; Service.Config.Save(); } - size.HotkeyKeyDown = keyDownXiv; + if (size.HotkeyKey != VirtualKey.NO_KEY) + { + var io = ImGui.GetIO(); + var keyPressedIm = ImGuiNative.igIsKeyPressed((ImGuiKey) size.HotkeyKey, 0) != 0; + var keyDownXiv = Service.KeyState.GetRawValue(size.HotkeyKey) != 0; + + if ((keyPressedIm || (keyDownXiv && !size.HotkeyKeyDown)) && + (size.HotkeyModifier switch + { + ModifierKey.NONE => !io.KeyCtrl && !io.KeyAlt && !io.KeyShift, + ModifierKey.CTRL => io.KeyCtrl && !io.KeyAlt && !io.KeyShift, + ModifierKey.ALT => !io.KeyCtrl && io.KeyAlt && !io.KeyShift, + ModifierKey.SHIFT => !io.KeyCtrl && !io.KeyAlt && io.KeyShift, + _ => false, + })) + { + size.IsEnabled = !size.IsEnabled; + Service.Config.Save(); + } + + size.HotkeyKeyDown = keyDownXiv; + } } private void OnFrameworkUpdate(IFramework framework) { lock (_disposeLock) { - OnFrameworkUpdateForSize(ref Service.Config._.Display); - OnFrameworkUpdateForSize(ref Service.Config._.Game); + OnFrameworkUpdateForSize(framework, "Display", ref Service.Config._.Display); + OnFrameworkUpdateForSize(framework, "Gameplay", ref Service.Config._.Game); Service.DisplaySize.Update(); Service.GameSize.Update(); diff --git a/CustomResolution2782/Service.cs b/CustomResolution2782/Service.cs index d3577e5..d1f185c 100644 --- a/CustomResolution2782/Service.cs +++ b/CustomResolution2782/Service.cs @@ -9,6 +9,9 @@ namespace CustomResolution; public sealed class Service { + + public static readonly string PluginName = typeof(Plugin).Assembly.GetName().Name!; + public static Plugin Plugin { get; internal set; } = null!; public static DisplaySizeState DisplaySize { get; internal set; } = null!; diff --git a/CustomResolution2782/Windows/ConfigWindow.cs b/CustomResolution2782/Windows/ConfigWindow.cs index 758f8bb..ab251ac 100644 --- a/CustomResolution2782/Windows/ConfigWindow.cs +++ b/CustomResolution2782/Windows/ConfigWindow.cs @@ -304,5 +304,18 @@ Not intended to be used with proper fullscreen."); ImGui.EndCombo(); } + + ImGui.Checkbox("Game hang protection", ref _.DisableOnHang); + + if (ImGui.IsItemHovered()) + { + ImGui.SetTooltip(@$"Automatically disables scaling if the game hangs for more than a second. + +Leave this option enabled if you want this plugin to disable itself as a protection +in case the resolution changes unexpectedly, or in case the resolution goes too high. + +In the absolute worst case, delete the following file to reset your settings: +%%AppData%%\XIVLauncher\pluginConfigs\{Service.PluginName}.json"); + } } }