From 60d1771c9530164bf25e04bdfe19ff8857a296da Mon Sep 17 00:00:00 2001 From: Anna Date: Sat, 22 Jan 2022 16:57:40 -0500 Subject: [PATCH] feat: start adding native shortcut support --- ChatTwo/GameFunctions/Chat.cs | 40 +++++++++++++++++++++++++++++++---- ChatTwo/Ui/ChatLog.cs | 34 +++++++++++++++++++++++++---- ChatTwo/Util/DataUtil.cs | 5 +++++ 3 files changed, 71 insertions(+), 8 deletions(-) create mode 100755 ChatTwo/Util/DataUtil.cs diff --git a/ChatTwo/GameFunctions/Chat.cs b/ChatTwo/GameFunctions/Chat.cs index 3937988..adca8ec 100755 --- a/ChatTwo/GameFunctions/Chat.cs +++ b/ChatTwo/GameFunctions/Chat.cs @@ -58,11 +58,14 @@ internal sealed unsafe class Chat : IDisposable { [Signature("8B B9 ?? ?? ?? ?? 48 8B D9 83 FF FE 0F 84", Offset = 2)] private readonly int? _replyChannelOffset; + [Signature("89 83 ?? ?? ?? ?? 48 8B 01 83 FE 13 7C 05 41 8B D4 EB 03 83 CA FF FF 90", Offset = 2)] + private readonly int? _shellChannelOffset; + #pragma warning restore 0649 // Events - internal delegate void ChatActivatedEventDelegate(string? input); + internal delegate void ChatActivatedEventDelegate(string? input, InputChannel? channel, (string, string)? tellTarget); internal event ChatActivatedEventDelegate? Activated; @@ -121,7 +124,10 @@ internal sealed unsafe class Chat : IDisposable { return ret; } - var channel = *(uint*) (shellModule + 0xFD0); + var channel = 0u; + if (this._shellChannelOffset != null) { + channel = *(uint*) (shellModule + this._shellChannelOffset.Value); + } // var channel = *(uint*) (agent + 0x40); if (channel is 17 or 18) { @@ -157,6 +163,24 @@ internal sealed unsafe class Chat : IDisposable { return this.ChatLogRefreshHook!.Original(log, eventId, value); } + InputChannel? channel = null; + (string, string)? tellTarget = null; + // if (this._shellChannelOffset != null) { + // var shell = (IntPtr) Framework.Instance()->GetUiModule()->GetRaptureShellModule(); + // + // channel = (InputChannel) (*(uint*) (shell + this._shellChannelOffset.Value)); + // if ((int) channel is 17 or 18) { + // channel = InputChannel.Tell; + // + // var targetPtr = *(byte**) (shell + 0xFD8); + // var targetWorldPtr = *(byte**) (shell + 0x1040); + // + // var target = MemoryHelper.ReadStringNullTerminated((IntPtr) targetPtr); + // var targetWorld = MemoryHelper.ReadStringNullTerminated((IntPtr) targetWorldPtr); + // tellTarget = (target, targetWorld); + // } + // } + string? eventInput = null; var str = value + 2; @@ -168,12 +192,20 @@ internal sealed unsafe class Chat : IDisposable { } try { - this.Activated?.Invoke(eventInput); + this.Activated?.Invoke(eventInput, channel, tellTarget); } catch (Exception ex) { PluginLog.LogError(ex, "Error in ChatActivated event"); } - return 0; + // var ret = this.ChatLogRefreshHook!.Original(log, eventId, value); + // if (this._clearFocus != null) { + // this._clearFocus(AtkStage.GetSingleton()); + // } + + // return ret; + + // return this.ChatLogRefreshHook!.Original(log, eventId, value); + return 1; } private void ReplyInSelectedChatModeDetour(AgentInterface* agent) { diff --git a/ChatTwo/Ui/ChatLog.cs b/ChatTwo/Ui/ChatLog.cs index 67cdfdb..ffc244c 100755 --- a/ChatTwo/Ui/ChatLog.cs +++ b/ChatTwo/Ui/ChatLog.cs @@ -4,6 +4,8 @@ using ChatTwo.Util; using Dalamud.Game.Command; using Dalamud.Game.Text.SeStringHandling.Payloads; using Dalamud.Interface; +using Dalamud.Memory; +using Dalamud.Utility; using ImGuiNET; using ImGuiScene; using Lumina.Excel.GeneratedSheets; @@ -21,6 +23,8 @@ internal sealed class ChatLog : IUiComponent { private readonly List _inputBacklog = new(); private int _inputBacklogIdx = -1; private int _lastTab; + private InputChannel? _tempChannel; + private (string, string)? _tellTarget; private PayloadHandler PayloadHandler { get; } private Dictionary TextCommandChannels { get; } = new(); @@ -46,11 +50,17 @@ internal sealed class ChatLog : IUiComponent { this.Ui.Plugin.CommandManager.RemoveHandler("/clearlog2"); } - private void Activated(string? input) { + private void Activated(string? input, InputChannel? channel, (string, string)? tellTarget) { this.Activate = true; if (input != null && !this.Chat.Contains(input)) { this.Chat += input; } + + if (channel != null && this.Ui.Plugin.Functions.Chat.Channel.channel != channel) { + this._tempChannel = channel; + } + + this._tellTarget = tellTarget; } private void ClearLog(string command, string arguments) { @@ -171,7 +181,13 @@ internal sealed class ChatLog : IUiComponent { ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero); try { - if (activeTab is { Channel: { } channel }) { + if (this._tempChannel != null) { + if (this._tellTarget != null) { + ImGui.TextUnformatted($"Tell {this._tellTarget.Value.Item1}@{this._tellTarget.Value.Item2}"); + } else { + ImGui.TextUnformatted(this._tempChannel.Value.ToChatType().Name()); + } + } else if (activeTab is { Channel: { } channel }) { ImGui.TextUnformatted(channel.ToChatType().Name()); } else { this.DrawChunks(this.Ui.Plugin.Functions.Chat.Channel.name); @@ -213,7 +229,7 @@ internal sealed class ChatLog : IUiComponent { var buttonWidth = afterIcon.X - beforeIcon.X; var inputWidth = ImGui.GetContentRegionAvail().X - buttonWidth; - var inputType = activeTab?.Channel?.ToChatType() ?? this.Ui.Plugin.Functions.Chat.Channel.channel.ToChatType(); + var inputType = this._tempChannel?.ToChatType() ?? activeTab?.Channel?.ToChatType() ?? this.Ui.Plugin.Functions.Chat.Channel.channel.ToChatType(); if (this.Chat.Trim().StartsWith('/')) { var command = this.Chat.Split(' ')[0]; if (this.TextCommandChannels.TryGetValue(command, out var channel)) { @@ -239,7 +255,13 @@ internal sealed class ChatLog : IUiComponent { this.AddBacklog(trimmed); this._inputBacklogIdx = -1; - if (activeTab is { Channel: { } channel } && !trimmed.StartsWith('/')) { + if (this._tempChannel != null) { + if (this._tellTarget != null) { + trimmed = $"{this._tempChannel.Value.Prefix()} {this._tellTarget.Value.Item1}@{this._tellTarget.Value.Item2} {trimmed}"; + } else { + trimmed = $"{this._tempChannel.Value.Prefix()} {trimmed}"; + } + } else if (activeTab is { Channel: { } channel } && !trimmed.StartsWith('/')) { trimmed = $"{channel.Prefix()} {trimmed}"; } @@ -249,6 +271,10 @@ internal sealed class ChatLog : IUiComponent { this.Chat = string.Empty; } + if (!this.Activate && !ImGui.IsItemActive()) { + this._tempChannel = null; + } + if (inputColour != null) { ImGui.PopStyleColor(); } diff --git a/ChatTwo/Util/DataUtil.cs b/ChatTwo/Util/DataUtil.cs new file mode 100755 index 0000000..3fa8538 --- /dev/null +++ b/ChatTwo/Util/DataUtil.cs @@ -0,0 +1,5 @@ +namespace ChatTwo.Util; + +public class DataUtil { + +}