feat: add automatic UI hiding to GameGui, UiBuilder

This commit is contained in:
goat 2020-08-14 02:51:55 +02:00
parent b7e36fb2e6
commit 5f9efaaea0
5 changed files with 52 additions and 5 deletions

View file

@ -378,6 +378,9 @@ namespace Dalamud {
}
}
if (this.Framework.Gui.GameUiHidden)
return;
if (this.isImguiDrawLogWindow)
{
this.isImguiDrawLogWindow = this.logWindow != null && this.logWindow.Draw();

View file

@ -44,6 +44,17 @@ namespace Dalamud.Game.Internal.Gui {
float *camPos, float *clipPos, float rayDistance, float *worldPos, int *unknown);
private readonly ScreenToWorldNativeDelegate screenToWorldNative;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte);
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
public bool GameUiHidden { get; private set; }
/// <summary>
/// Event which is fired when the game UI hiding is toggled.
/// </summary>
public event EventHandler<bool> OnUiHideToggled;
/// <summary>
/// The item ID that is currently hovered by the player. 0 when no item is hovered.
/// If > 1.000.000, subtract 1.000.000 and treat it as HQ
@ -90,6 +101,8 @@ namespace Dalamud.Game.Internal.Gui {
this.screenToWorldNative =
Marshal.GetDelegateForFunctionPointer<ScreenToWorldNativeDelegate>(Address.ScreenToWorld);
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(Address.ToggleUiHide, new ToggleUiHideDelegate(ToggleUiHideDetour), this);
}
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@ -279,6 +292,20 @@ namespace Dalamud.Game.Internal.Gui {
return isSuccess;
}
private IntPtr ToggleUiHideDetour(IntPtr thisPtr, byte unknownByte) {
GameUiHidden = !GameUiHidden;
try {
OnUiHideToggled?.Invoke(this, GameUiHidden);
} catch (Exception ex) {
Log.Error(ex, "Error on OnUiHideToggled event dispatch");
}
Log.Debug("UiHide toggled: {0}", GameUiHidden);
return this.toggleUiHideHook.Original(thisPtr, unknownByte);
}
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() {
@ -286,6 +313,7 @@ namespace Dalamud.Game.Internal.Gui {
this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable();
this.toggleUiHideHook.Enable();
}
public void Dispose() {
@ -293,6 +321,7 @@ namespace Dalamud.Game.Internal.Gui {
this.setGlobalBgmHook.Dispose();
this.handleItemHoverHook.Dispose();
this.handleItemOutHook.Dispose();
this.toggleUiHideHook.Dispose();
}
}
}

View file

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using Serilog;
namespace Dalamud.Game.Internal.Gui {
public sealed class GameGuiAddressResolver : BaseAddressResolver {
internal sealed class GameGuiAddressResolver : BaseAddressResolver {
public IntPtr BaseAddress { get; private set; }
public IntPtr ChatManager { get; private set; }
@ -14,6 +14,7 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr GetUIObject { get; private set; }
public IntPtr GetMatrixSingleton { get; private set; }
public IntPtr ScreenToWorld { get; private set; }
public IntPtr ToggleUiHide { get; set; }
public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress;
@ -34,7 +35,8 @@ namespace Dalamud.Game.Internal.Gui {
HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
}
}
}

View file

@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Game.Internal.Gui;
using ImGuiNET;
using ImGuiScene;
using Serilog;
using SharpDX.Direct3D11;
namespace Dalamud.Interface
{
@ -31,8 +33,14 @@ namespace Dalamud.Interface
/// </summary>
public event RawDX11Scene.BuildUIDelegate OnBuildUi;
/// <summary>
/// Choose if this plugin should hide its UI automatically when the whole game hides its UI.
/// </summary>
public bool DisableAutomaticUiHide { get; set; } = false;
private readonly InterfaceManager interfaceManager;
#if DEBUG
private readonly GameGui gameGui;
#if DEBUG
internal static bool DoStats { get; set; } = true;
#else
internal static bool DoStats { get; set; } = false;
@ -47,10 +55,11 @@ namespace Dalamud.Interface
/// </summary>
/// <param name="interfaceManager">The interface manager to register on.</param>
/// <param name="namespaceName">The plugin namespace.</param>
internal UiBuilder(InterfaceManager interfaceManager, string namespaceName) {
internal UiBuilder(InterfaceManager interfaceManager, GameGui gameGui, string namespaceName) {
this.namespaceName = namespaceName;
this.interfaceManager = interfaceManager;
this.gameGui = gameGui;
this.interfaceManager.OnDraw += OnDraw;
this.stopwatch = new System.Diagnostics.Stopwatch();
}
@ -118,6 +127,10 @@ namespace Dalamud.Interface
private bool hasErrorWindow;
private void OnDraw() {
if (this.gameGui.GameUiHidden && !DisableAutomaticUiHide)
return;
ImGui.PushID(this.namespaceName);
if (DoStats) {
this.stopwatch.Restart();

View file

@ -75,7 +75,7 @@ namespace Dalamud.Plugin
this.CommandManager = dalamud.CommandManager;
this.Framework = dalamud.Framework;
this.ClientState = dalamud.ClientState;
this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, pluginName);
this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, dalamud.Framework.Gui, pluginName);
this.TargetModuleScanner = dalamud.SigScanner;
this.Data = dalamud.Data;
this.SeStringManager = dalamud.SeStringManager;