From ab3b35dfc1e3cdd03358d4c3eb0d58c20d4696d7 Mon Sep 17 00:00:00 2001 From: Anna Clemens Date: Tue, 6 Apr 2021 05:09:20 -0400 Subject: [PATCH] feat: add functions for toasting --- Dalamud/Game/Internal/Gui/GameGui.cs | 12 +++++ .../Internal/Gui/GameGuiAddressResolver.cs | 4 ++ Dalamud/Game/Internal/Gui/ToastGui.cs | 51 +++++++++++++++++++ .../Internal/Gui/ToastGuiAddressResolver.cs | 14 +++++ 4 files changed, 81 insertions(+) create mode 100755 Dalamud/Game/Internal/Gui/ToastGui.cs create mode 100755 Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs diff --git a/Dalamud/Game/Internal/Gui/GameGui.cs b/Dalamud/Game/Internal/Gui/GameGui.cs index a1c53c504..6cbbe37f7 100644 --- a/Dalamud/Game/Internal/Gui/GameGui.cs +++ b/Dalamud/Game/Internal/Gui/GameGui.cs @@ -13,6 +13,7 @@ namespace Dalamud.Game.Internal.Gui { public ChatGui Chat { get; private set; } public PartyFinderGui PartyFinder { get; private set; } + public ToastGui Toast { get; private set; } [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr SetGlobalBgmDelegate(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6); @@ -68,6 +69,9 @@ namespace Dalamud.Game.Internal.Gui { private delegate IntPtr GetUIObjectByNameDelegate(IntPtr thisPtr, string uiName, int index); private readonly GetUIObjectByNameDelegate getUIObjectByName; + private delegate IntPtr GetUiModuleDelegate(IntPtr basePtr); + private readonly GetUiModuleDelegate getUiModule; + public bool GameUiHidden { get; private set; } /// @@ -110,6 +114,7 @@ namespace Dalamud.Game.Internal.Gui { Chat = new ChatGui(Address.ChatManager, scanner, dalamud); PartyFinder = new PartyFinderGui(scanner, dalamud); + Toast = new ToastGui(scanner, dalamud); this.setGlobalBgmHook = new Hook(Address.SetGlobalBgm, @@ -146,6 +151,8 @@ namespace Dalamud.Game.Internal.Gui { this.GetBaseUIObject = Marshal.GetDelegateForFunctionPointer(Address.GetBaseUIObject); this.getUIObjectByName = Marshal.GetDelegateForFunctionPointer(Address.GetUIObjectByName); + + this.getUiModule = Marshal.GetDelegateForFunctionPointer(Address.GetUIModule); } private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) { @@ -411,6 +418,11 @@ namespace Dalamud.Game.Internal.Gui { return this.toggleUiHideHook.Original(thisPtr, unknownByte); } + public IntPtr GetUIModule() + { + return this.getUiModule(Marshal.ReadIntPtr(Address.GetUIModulePtr)); + } + /// /// Gets the pointer to the UI Object with the given name and index. /// diff --git a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs index 7a06ae264..ca617bc84 100644 --- a/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs +++ b/Dalamud/Game/Internal/Gui/GameGuiAddressResolver.cs @@ -19,6 +19,8 @@ namespace Dalamud.Game.Internal.Gui { public IntPtr ToggleUiHide { get; set; } public IntPtr GetBaseUIObject { get; private set; } public IntPtr GetUIObjectByName { get; private set; } + public IntPtr GetUIModule { get; private set; } + public IntPtr GetUIModulePtr { get; private set; } public GameGuiAddressResolver(IntPtr baseAddress) { BaseAddress = baseAddress; @@ -45,6 +47,8 @@ namespace Dalamud.Game.Internal.Gui { ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??"); GetBaseUIObject = sig.ScanText("E8 ?? ?? ?? ?? 41 B8 01 00 00 00 48 8D 15 ?? ?? ?? ?? 48 8B 48 20 E8 ?? ?? ?? ?? 48 8B CF"); GetUIObjectByName = sig.ScanText("E8 ?? ?? ?? ?? 48 8B CF 48 89 87 ?? ?? 00 00 E8 ?? ?? ?? ?? 41 B8 01 00 00 00"); + GetUIModule = sig.ScanText("E8 ?? ?? ?? ?? 83 3B 01"); + GetUIModulePtr = sig.GetStaticAddressFromSig("48 8B 0D ?? ?? ?? ?? 48 8D 54 24 ?? 48 83 C1 10 E8 ?? ?? ?? ??"); } } } diff --git a/Dalamud/Game/Internal/Gui/ToastGui.cs b/Dalamud/Game/Internal/Gui/ToastGui.cs new file mode 100755 index 000000000..21c6e92a4 --- /dev/null +++ b/Dalamud/Game/Internal/Gui/ToastGui.cs @@ -0,0 +1,51 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using Dalamud.Game.Text.SeStringHandling; + +namespace Dalamud.Game.Internal.Gui +{ + public class ToastGui + { + private Dalamud Dalamud { get; } + + private ToastGuiAddressResolver Address { get; } + + private delegate IntPtr ShowToastDelegate(IntPtr manager, IntPtr text, int layer, byte bool1, byte bool2, int logMessageId); + + private readonly ShowToastDelegate showToast; + + public ToastGui(SigScanner scanner, Dalamud dalamud) + { + Dalamud = dalamud; + + Address = new ToastGuiAddressResolver(); + Address.Setup(scanner); + + this.showToast = Marshal.GetDelegateForFunctionPointer(Address.ShowToast); + } + + public void Show(string message) + { + this.Show(Encoding.UTF8.GetBytes(message)); + } + + public void Show(SeString message) + { + this.Show(message.Encode()); + } + + private void Show(byte[] bytes) + { + var manager = Dalamud.Framework.Gui.GetUIModule(); + + unsafe + { + fixed (byte* ptr = bytes) + { + this.showToast(manager, (IntPtr) ptr, 5, 0, 1, 0); + } + } + } + } +} diff --git a/Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs b/Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs new file mode 100755 index 000000000..e5ee511e1 --- /dev/null +++ b/Dalamud/Game/Internal/Gui/ToastGuiAddressResolver.cs @@ -0,0 +1,14 @@ +using System; + +namespace Dalamud.Game.Internal.Gui +{ + public class ToastGuiAddressResolver : BaseAddressResolver + { + public IntPtr ShowToast { get; private set; } + + protected override void Setup64Bit(SigScanner sig) + { + ShowToast = sig.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 83 3D ?? ?? ?? ?? ??"); + } + } +}