Lock UI on hook failure

This commit is contained in:
RisaDev
2024-02-04 22:56:31 +03:00
parent 205f60480c
commit 6aa64e43ef
3 changed files with 38 additions and 18 deletions

View File

@@ -32,6 +32,9 @@ public class HookingService : IDisposable
[UnmanagedFunctionPointer(CallingConvention.StdCall)] [UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void GameObjectMovementDelegate(nint gameObject); private delegate void GameObjectMovementDelegate(nint gameObject);
public bool RenderHookFailed { get; private set; }
public bool MovementHookFailed { get; private set; }
public HookingService( public HookingService(
PluginConfiguration configuration, PluginConfiguration configuration,
ISigScanner sigScanner, ISigScanner sigScanner,
@@ -56,6 +59,9 @@ public class HookingService : IDisposable
public void ReloadHooks() public void ReloadHooks()
{ {
RenderHookFailed = false;
MovementHookFailed = false;
try try
{ {
if (_configuration.PluginEnabled) if (_configuration.PluginEnabled)
@@ -74,27 +80,25 @@ public class HookingService : IDisposable
_logger.Debug("Movement hook established"); _logger.Debug("Movement hook established");
} }
_logger.Debug("Hooking render & movement functions");
_renderManagerHook.Enable();
_gameObjectMovementHook.Enable();
_logger.Debug("Hooking render manager"); _logger.Debug("Hooking render manager");
_renderManagerHook.Enable(); _renderManagerHook.Enable();
//Send current player's profile update message to IPC _logger.Debug("Hooking movement functions");
//IPCManager.OnProfileUpdate(null); _gameObjectMovementHook.Enable();
} }
else else
{ {
_logger.Debug("Unhooking..."); _logger.Debug("Unhooking...");
_renderManagerHook?.Disable(); _renderManagerHook?.Disable();
_gameObjectMovementHook?.Disable(); _gameObjectMovementHook?.Disable();
_renderManagerHook?.Disable();
} }
} }
catch (Exception e) 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; throw;
} }
} }
@@ -109,8 +113,8 @@ public class HookingService : IDisposable
if (_fantasiaPlusDetectService.IsFantasiaPlusInstalled) if (_fantasiaPlusDetectService.IsFantasiaPlusInstalled)
{ {
_logger.Error($"Fantasia+ detected, disabling all hooks"); _logger.Error($"Fantasia+ detected, disabling all hooks");
_renderManagerHook?.Disable(); _renderManagerHook.Disable();
_gameObjectMovementHook.Disable(); _gameObjectMovementHook?.Disable();
return _renderManagerHook.Original(a1, a2, a3, a4); return _renderManagerHook.Original(a1, a2, a3, a4);
} }
@@ -122,23 +126,27 @@ public class HookingService : IDisposable
} }
catch (Exception e) catch (Exception e)
{ {
RenderHookFailed = true;
_logger.Error($"Error in Customize+ render hook {e}"); _logger.Error($"Error in Customize+ render hook {e}");
_renderManagerHook?.Disable(); _renderManagerHook?.Disable();
} }
return _renderManagerHook.Original(a1, a2, a3, a4); return _renderManagerHook!.Original(a1, a2, a3, a4);
} }
private unsafe void OnGameObjectMove(nint gameObjectPtr) private unsafe void OnGameObjectMove(nint gameObjectPtr)
{ {
if (_gameObjectMovementHook == null)
{
throw new Exception();
}
// Call the original function. // Call the original function.
_gameObjectMovementHook.Original(gameObjectPtr); _gameObjectMovementHook.Original(gameObjectPtr);
// If GPose and a 3rd-party posing service are active simultneously, abort // If GPose and a 3rd-party posing service are active simultneously, abort
if (_gameStateService.GameInPosingMode()) if (_gameStateService.GameInPosingMode())
{
return; return;
}
try try
{ {
@@ -148,6 +156,7 @@ public class HookingService : IDisposable
} }
catch (Exception ex) catch (Exception ex)
{ {
MovementHookFailed = true;
_logger.Error($"Exception in Customize+ movement hook: {ex}"); _logger.Error($"Exception in Customize+ movement hook: {ex}");
_gameObjectMovementHook?.Disable(); _gameObjectMovementHook?.Disable();
} }

View File

@@ -16,6 +16,7 @@ public class PluginStateBlock
private readonly PluginConfiguration _configuration; private readonly PluginConfiguration _configuration;
private readonly GameStateService _gameStateService; private readonly GameStateService _gameStateService;
private readonly FantasiaPlusDetectService _fantasiaPlusDetectService; private readonly FantasiaPlusDetectService _fantasiaPlusDetectService;
private readonly HookingService _hookingService;
private static Vector4 normalColor = new Vector4(1, 1, 1, 1); private static Vector4 normalColor = new Vector4(1, 1, 1, 1);
private static Vector4 warnColor = new Vector4(1, 0.5f, 0, 1); private static Vector4 warnColor = new Vector4(1, 0.5f, 0, 1);
@@ -25,12 +26,14 @@ public class PluginStateBlock
BoneEditorPanel boneEditorPanel, BoneEditorPanel boneEditorPanel,
PluginConfiguration configuration, PluginConfiguration configuration,
GameStateService gameStateService, GameStateService gameStateService,
FantasiaPlusDetectService fantasiaPlusDetectService) FantasiaPlusDetectService fantasiaPlusDetectService,
HookingService hookingService)
{ {
_boneEditorPanel = boneEditorPanel; _boneEditorPanel = boneEditorPanel;
_configuration = configuration; _configuration = configuration;
_gameStateService = gameStateService; _gameStateService = gameStateService;
_fantasiaPlusDetectService = fantasiaPlusDetectService; _fantasiaPlusDetectService = fantasiaPlusDetectService;
_hookingService = hookingService;
} }
public void Draw(float yPos) public void Draw(float yPos)
@@ -38,7 +41,12 @@ public class PluginStateBlock
var severity = PluginStateSeverity.Normal; var severity = PluginStateSeverity.Normal;
string? message = null; 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; severity = PluginStateSeverity.Error;
message = $"Fantasia+ detected. The plugin is disabled until Fantasia+ is disabled and the game is restarted."; message = $"Fantasia+ detected. The plugin is disabled until Fantasia+ is disabled and the game is restarted.";

View File

@@ -28,8 +28,9 @@ public class MainWindow : Window, IDisposable
private readonly PluginStateBlock _pluginStateBlock; private readonly PluginStateBlock _pluginStateBlock;
private readonly TemplateEditorManager _templateEditorManager; private readonly TemplateEditorManager _templateEditorManager;
private readonly FantasiaPlusDetectService _cPlusDetectService; private readonly FantasiaPlusDetectService _fantasiaPlusDetectService;
private readonly PluginConfiguration _configuration; private readonly PluginConfiguration _configuration;
private readonly HookingService _hookingService;
public MainWindow( public MainWindow(
DalamudPluginInterface pluginInterface, DalamudPluginInterface pluginInterface,
@@ -42,7 +43,8 @@ public class MainWindow : Window, IDisposable
PluginStateBlock pluginStateBlock, PluginStateBlock pluginStateBlock,
TemplateEditorManager templateEditorManager, TemplateEditorManager templateEditorManager,
PluginConfiguration configuration, PluginConfiguration configuration,
FantasiaPlusDetectService cPlusDetectService FantasiaPlusDetectService fantasiaPlusDetectService,
HookingService hookingService
) : base($"Customize+ v{Plugin.Version}###CPlusMainWindow") ) : base($"Customize+ v{Plugin.Version}###CPlusMainWindow")
{ {
_settingsTab = settingsTab; _settingsTab = settingsTab;
@@ -55,8 +57,9 @@ public class MainWindow : Window, IDisposable
_pluginStateBlock = pluginStateBlock; _pluginStateBlock = pluginStateBlock;
_templateEditorManager = templateEditorManager; _templateEditorManager = templateEditorManager;
_cPlusDetectService = cPlusDetectService;
_configuration = configuration; _configuration = configuration;
_fantasiaPlusDetectService = fantasiaPlusDetectService;
_hookingService = hookingService;
pluginInterface.UiBuilder.DisableGposeUiHide = true; pluginInterface.UiBuilder.DisableGposeUiHide = true;
SizeConstraints = new WindowSizeConstraints() SizeConstraints = new WindowSizeConstraints()
@@ -77,7 +80,7 @@ public class MainWindow : Window, IDisposable
{ {
var yPos = ImGui.GetCursorPosY(); var yPos = ImGui.GetCursorPosY();
using (var disabled = ImRaii.Disabled(_cPlusDetectService.IsFantasiaPlusInstalled)) using (var disabled = ImRaii.Disabled(_fantasiaPlusDetectService.IsFantasiaPlusInstalled || _hookingService.RenderHookFailed || _hookingService.MovementHookFailed))
{ {
LockWindowClosureIfNeeded(); LockWindowClosureIfNeeded();
if (ImGui.BeginTabBar("##tabs", ImGuiTabBarFlags.None)) //todo: remember last selected tab if (ImGui.BeginTabBar("##tabs", ImGuiTabBarFlags.None)) //todo: remember last selected tab