diff --git a/XivCommon/Functions/BattleTalk.cs b/XivCommon/Functions/BattleTalk.cs index 428533c..89c565f 100755 --- a/XivCommon/Functions/BattleTalk.cs +++ b/XivCommon/Functions/BattleTalk.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.InteropServices; using Dalamud.Game; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Hooking; @@ -8,35 +9,43 @@ namespace XivCommon.Functions { public class BattleTalk : IDisposable { private GameFunctions Functions { get; } private SeStringManager SeStringManager { get; } - private bool Enabled { get; } + private bool HookEnabled { get; } public delegate void BattleTalkEventDelegate(ref SeString sender, ref SeString message, ref BattleTalkOptions options, ref bool isHandled); /// + /// /// The event that is fired when a BattleTalk window is shown. + /// + /// + /// Requires the hook to be enabled. + /// /// public event BattleTalkEventDelegate? OnBattleTalk; private delegate byte AddBattleTalkDelegate(IntPtr uiModule, IntPtr sender, IntPtr message, float duration, byte style); - private Hook? AddBattleTextHook { get; } + private AddBattleTalkDelegate AddBattleTalk { get; } + private Hook? AddBattleTalkHook { get; } internal BattleTalk(GameFunctions functions, SigScanner scanner, SeStringManager seStringManager, bool hook) { this.Functions = functions; this.SeStringManager = seStringManager; - this.Enabled = hook; + this.HookEnabled = hook; - if (!hook) { + var addBattleTalkPtr = scanner.ScanText("48 89 5C 24 ?? 57 48 83 EC 50 48 8B 01 49 8B D8 0F 29 74 24 ?? 48 8B FA 0F 28 F3 FF 50 40 C7 44 24 ?? ?? ?? ?? ??"); + this.AddBattleTalk = Marshal.GetDelegateForFunctionPointer(addBattleTalkPtr); + + if (!this.HookEnabled) { return; } - var addBattleTextPtr = scanner.ScanText("48 89 5C 24 ?? 57 48 83 EC 50 48 8B 01 49 8B D8 0F 29 74 24 ?? 48 8B FA 0F 28 F3 FF 50 40 C7 44 24 ?? ?? ?? ?? ??"); - this.AddBattleTextHook = new Hook(addBattleTextPtr, new AddBattleTalkDelegate(this.AddBattleTalkDetour)); - this.AddBattleTextHook.Enable(); + this.AddBattleTalkHook = new Hook(addBattleTalkPtr, new AddBattleTalkDelegate(this.AddBattleTalkDetour)); + this.AddBattleTalkHook.Enable(); } public void Dispose() { - this.AddBattleTextHook?.Dispose(); + this.AddBattleTalkHook?.Dispose(); } private unsafe byte AddBattleTalkDetour(IntPtr uiModule, IntPtr senderPtr, IntPtr messagePtr, float duration, byte style) { @@ -66,7 +75,7 @@ namespace XivCommon.Functions { var finalMessage = message.Encode().Terminate(); fixed (byte* fSenderPtr = finalSender, fMessagePtr = finalMessage) { - return this.AddBattleTextHook!.Original(uiModule, (IntPtr) fSenderPtr, (IntPtr) fMessagePtr, options.Duration, (byte) options.Style); + return this.AddBattleTalkHook!.Original(uiModule, (IntPtr) fSenderPtr, (IntPtr) fMessagePtr, options.Duration, (byte) options.Style); } } @@ -76,16 +85,12 @@ namespace XivCommon.Functions { /// The name to attribute to the message /// The message to show in the window /// Optional options for the window - /// If the hook is not enabled + /// If sender or message are empty public void Show(SeString sender, SeString message, BattleTalkOptions? options = null) { this.Show(sender.Encode(), message.Encode(), options); } private void Show(byte[] sender, byte[] message, BattleTalkOptions? options) { - if (!this.Enabled) { - throw new InvalidOperationException("BattleTalk hooks are not enabled"); - } - if (sender.Length == 0) { throw new ArgumentException("sender cannot be empty", nameof(sender)); } @@ -100,7 +105,11 @@ namespace XivCommon.Functions { unsafe { fixed (byte* senderPtr = sender.Terminate(), messagePtr = message.Terminate()) { - this.AddBattleTalkDetour(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style); + if (this.HookEnabled) { + this.AddBattleTalkDetour(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style); + } else { + this.AddBattleTalk(uiModule, (IntPtr) senderPtr, (IntPtr) messagePtr, options.Duration, (byte) options.Style); + } } } }