From 6aa64e43ef2cf02fdb3af2d5bae11d0fcb1e2b04 Mon Sep 17 00:00:00 2001 From: RisaDev <151885272+RisaDev@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:56:31 +0300 Subject: [PATCH] Lock UI on hook failure --- CustomizePlus/Core/Services/HookingService.cs | 33 ++++++++++++------- .../UI/Windows/Controls/PluginStateBlock.cs | 12 +++++-- .../UI/Windows/MainWindow/MainWindow.cs | 11 ++++--- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/CustomizePlus/Core/Services/HookingService.cs b/CustomizePlus/Core/Services/HookingService.cs index db44507..cca048f 100644 --- a/CustomizePlus/Core/Services/HookingService.cs +++ b/CustomizePlus/Core/Services/HookingService.cs @@ -32,6 +32,9 @@ public class HookingService : IDisposable [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void GameObjectMovementDelegate(nint gameObject); + public bool RenderHookFailed { get; private set; } + public bool MovementHookFailed { get; private set; } + public HookingService( PluginConfiguration configuration, ISigScanner sigScanner, @@ -56,6 +59,9 @@ public class HookingService : IDisposable public void ReloadHooks() { + RenderHookFailed = false; + MovementHookFailed = false; + try { if (_configuration.PluginEnabled) @@ -74,27 +80,25 @@ public class HookingService : IDisposable _logger.Debug("Movement hook established"); } - _logger.Debug("Hooking render & movement functions"); - _renderManagerHook.Enable(); - _gameObjectMovementHook.Enable(); _logger.Debug("Hooking render manager"); _renderManagerHook.Enable(); - //Send current player's profile update message to IPC - //IPCManager.OnProfileUpdate(null); + _logger.Debug("Hooking movement functions"); + _gameObjectMovementHook.Enable(); } else { _logger.Debug("Unhooking..."); _renderManagerHook?.Disable(); _gameObjectMovementHook?.Disable(); - _renderManagerHook?.Disable(); } } catch (Exception e) { - _logger.Error($"Failed to hook Render::Manager::Render {e}"); + _logger.Error($"Failed to hook into the game: {e}"); + RenderHookFailed = true; + MovementHookFailed = true; throw; } } @@ -109,8 +113,8 @@ public class HookingService : IDisposable if (_fantasiaPlusDetectService.IsFantasiaPlusInstalled) { _logger.Error($"Fantasia+ detected, disabling all hooks"); - _renderManagerHook?.Disable(); - _gameObjectMovementHook.Disable(); + _renderManagerHook.Disable(); + _gameObjectMovementHook?.Disable(); return _renderManagerHook.Original(a1, a2, a3, a4); } @@ -122,23 +126,27 @@ public class HookingService : IDisposable } catch (Exception e) { + RenderHookFailed = true; _logger.Error($"Error in Customize+ render hook {e}"); _renderManagerHook?.Disable(); } - return _renderManagerHook.Original(a1, a2, a3, a4); + return _renderManagerHook!.Original(a1, a2, a3, a4); } private unsafe void OnGameObjectMove(nint gameObjectPtr) { + if (_gameObjectMovementHook == null) + { + throw new Exception(); + } + // Call the original function. _gameObjectMovementHook.Original(gameObjectPtr); // If GPose and a 3rd-party posing service are active simultneously, abort if (_gameStateService.GameInPosingMode()) - { return; - } try { @@ -148,6 +156,7 @@ public class HookingService : IDisposable } catch (Exception ex) { + MovementHookFailed = true; _logger.Error($"Exception in Customize+ movement hook: {ex}"); _gameObjectMovementHook?.Disable(); } diff --git a/CustomizePlus/UI/Windows/Controls/PluginStateBlock.cs b/CustomizePlus/UI/Windows/Controls/PluginStateBlock.cs index 10ae822..e70dacf 100644 --- a/CustomizePlus/UI/Windows/Controls/PluginStateBlock.cs +++ b/CustomizePlus/UI/Windows/Controls/PluginStateBlock.cs @@ -16,6 +16,7 @@ public class PluginStateBlock private readonly PluginConfiguration _configuration; private readonly GameStateService _gameStateService; private readonly FantasiaPlusDetectService _fantasiaPlusDetectService; + private readonly HookingService _hookingService; private static Vector4 normalColor = new Vector4(1, 1, 1, 1); private static Vector4 warnColor = new Vector4(1, 0.5f, 0, 1); @@ -25,12 +26,14 @@ public class PluginStateBlock BoneEditorPanel boneEditorPanel, PluginConfiguration configuration, GameStateService gameStateService, - FantasiaPlusDetectService fantasiaPlusDetectService) + FantasiaPlusDetectService fantasiaPlusDetectService, + HookingService hookingService) { _boneEditorPanel = boneEditorPanel; _configuration = configuration; _gameStateService = gameStateService; _fantasiaPlusDetectService = fantasiaPlusDetectService; + _hookingService = hookingService; } public void Draw(float yPos) @@ -38,7 +41,12 @@ public class PluginStateBlock var severity = PluginStateSeverity.Normal; string? message = null; - if (_fantasiaPlusDetectService.IsFantasiaPlusInstalled) + if(_hookingService.RenderHookFailed || _hookingService.MovementHookFailed) + { + severity = PluginStateSeverity.Error; + message = $"Detected failure in game hooks. Customize+ disabled."; + } + else if (_fantasiaPlusDetectService.IsFantasiaPlusInstalled) { severity = PluginStateSeverity.Error; message = $"Fantasia+ detected. The plugin is disabled until Fantasia+ is disabled and the game is restarted."; diff --git a/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs b/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs index efe25e0..c7374d3 100644 --- a/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs +++ b/CustomizePlus/UI/Windows/MainWindow/MainWindow.cs @@ -28,8 +28,9 @@ public class MainWindow : Window, IDisposable private readonly PluginStateBlock _pluginStateBlock; private readonly TemplateEditorManager _templateEditorManager; - private readonly FantasiaPlusDetectService _cPlusDetectService; + private readonly FantasiaPlusDetectService _fantasiaPlusDetectService; private readonly PluginConfiguration _configuration; + private readonly HookingService _hookingService; public MainWindow( DalamudPluginInterface pluginInterface, @@ -42,7 +43,8 @@ public class MainWindow : Window, IDisposable PluginStateBlock pluginStateBlock, TemplateEditorManager templateEditorManager, PluginConfiguration configuration, - FantasiaPlusDetectService cPlusDetectService + FantasiaPlusDetectService fantasiaPlusDetectService, + HookingService hookingService ) : base($"Customize+ v{Plugin.Version}###CPlusMainWindow") { _settingsTab = settingsTab; @@ -55,8 +57,9 @@ public class MainWindow : Window, IDisposable _pluginStateBlock = pluginStateBlock; _templateEditorManager = templateEditorManager; - _cPlusDetectService = cPlusDetectService; _configuration = configuration; + _fantasiaPlusDetectService = fantasiaPlusDetectService; + _hookingService = hookingService; pluginInterface.UiBuilder.DisableGposeUiHide = true; SizeConstraints = new WindowSizeConstraints() @@ -77,7 +80,7 @@ public class MainWindow : Window, IDisposable { var yPos = ImGui.GetCursorPosY(); - using (var disabled = ImRaii.Disabled(_cPlusDetectService.IsFantasiaPlusInstalled)) + using (var disabled = ImRaii.Disabled(_fantasiaPlusDetectService.IsFantasiaPlusInstalled || _hookingService.RenderHookFailed || _hookingService.MovementHookFailed)) { LockWindowClosureIfNeeded(); if (ImGui.BeginTabBar("##tabs", ImGuiTabBarFlags.None)) //todo: remember last selected tab