config: Add "Game hang protection" (auto-disable on 1s+ hangs)

This commit is contained in:
Jade Macho 2025-07-06 16:04:03 +02:00
parent 23f5a22b2c
commit 103556bd5e
Signed by: 0x0ade
GPG key ID: E1960710FE4FBEEF
5 changed files with 49 additions and 25 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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,13 +79,18 @@ 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;
Service.PluginLog.Warning($"Disabling because hang: {type}");
Service.PrintChat($"Lag detected, \"{type}\" custom resolution disabled.");
size.IsEnabled = false;
Service.Config.Save();
}
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;
@ -105,13 +111,14 @@ public sealed unsafe class Plugin : IDalamudPlugin
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();

View file

@ -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!;

View file

@ -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");
}
}
}