From 9c4b975605293ba90176c34d33884dcbc5d0a91c Mon Sep 17 00:00:00 2001 From: Infi Date: Sun, 2 Jun 2024 14:17:45 +0200 Subject: [PATCH] - No emote parsing on AutoTranslate - nint everything --- ChatTwo/ChatTwo.csproj | 2 +- ChatTwo/Configuration.cs | 2 +- ChatTwo/FontManager.cs | 4 ++-- ChatTwo/GameFunctions/Chat.cs | 40 +++++++++++++++++------------------ ChatTwo/Message.cs | 7 ++++-- ChatTwo/Ui/ChatLogWindow.cs | 2 +- ChatTwo/Ui/InputPreview.cs | 9 ++------ ChatTwo/Util/AutoTranslate.cs | 4 ++-- ChatTwo/Util/Payloads.cs | 27 ----------------------- ChatTwo/Util/StringUtil.cs | 2 +- 10 files changed, 35 insertions(+), 64 deletions(-) diff --git a/ChatTwo/ChatTwo.csproj b/ChatTwo/ChatTwo.csproj index 25ead3d..0a77aef 100755 --- a/ChatTwo/ChatTwo.csproj +++ b/ChatTwo/ChatTwo.csproj @@ -1,6 +1,6 @@ - 1.25.4 + 1.25.5 net8.0-windows enable enable diff --git a/ChatTwo/Configuration.cs b/ChatTwo/Configuration.cs index caf595d..3da4c0b 100755 --- a/ChatTwo/Configuration.cs +++ b/ChatTwo/Configuration.cs @@ -506,7 +506,7 @@ internal static class ExtraGlyphRangesExt _ => throw new ArgumentOutOfRangeException(nameof(ranges), ranges, null), }; - internal static IntPtr Range(this ExtraGlyphRanges ranges) => ranges switch + internal static nint Range(this ExtraGlyphRanges ranges) => ranges switch { ExtraGlyphRanges.ChineseFull => ImGui.GetIO().Fonts.GetGlyphRangesChineseFull(), ExtraGlyphRanges.ChineseSimplifiedCommon => ImGui.GetIO().Fonts.GetGlyphRangesChineseSimplifiedCommon(), diff --git a/ChatTwo/FontManager.cs b/ChatTwo/FontManager.cs index c0e8b95..f55622e 100644 --- a/ChatTwo/FontManager.cs +++ b/ChatTwo/FontManager.cs @@ -50,7 +50,7 @@ public class FontManager private unsafe void SetUpRanges() { - ushort[] BuildRange(IReadOnlyList? chars, params IntPtr[] ranges) + ushort[] BuildRange(IReadOnlyList? chars, params nint[] ranges) { var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder()); // text @@ -85,7 +85,7 @@ public class FontManager return builder.BuildRangesToArray(); } - var ranges = new List { ImGui.GetIO().Fonts.GetGlyphRangesDefault() }; + var ranges = new List { ImGui.GetIO().Fonts.GetGlyphRangesDefault() }; foreach (var extraRange in Enum.GetValues()) if (Plugin.Config.ExtraGlyphRanges.HasFlag(extraRange)) ranges.Add(extraRange.Range()); diff --git a/ChatTwo/GameFunctions/Chat.cs b/ChatTwo/GameFunctions/Chat.cs index 4921ff4..a57e78b 100755 --- a/ChatTwo/GameFunctions/Chat.cs +++ b/ChatTwo/GameFunctions/Chat.cs @@ -38,7 +38,7 @@ internal sealed unsafe class Chat : IDisposable private readonly delegate* unmanaged SetChannelTargetTell = null!; [Signature("E8 ?? ?? ?? ?? 48 8D 4D A0 8B F8")] - private readonly delegate* unmanaged GetKeybindNative = null!; + private readonly delegate* unmanaged GetKeybindNative = null!; // TODO Replace with CS in AcquaintanceModule [Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1 45 85 C9")] @@ -182,7 +182,7 @@ internal sealed unsafe class Chat : IDisposable internal string? GetLinkshellName(uint idx) { var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.LinkShell); - if (infoProxy == IntPtr.Zero) + if (infoProxy == nint.Zero) return null; var lsInfo = GetLinkshellInfo(infoProxy, idx); @@ -190,13 +190,13 @@ internal sealed unsafe class Chat : IDisposable return null; var utf = GetLinkshellNameNative(infoProxy, *lsInfo); - return utf == null ? null : MemoryHelper.ReadStringNullTerminated((IntPtr) utf); + return utf == null ? null : MemoryHelper.ReadStringNullTerminated((nint) utf); } internal string? GetCrossLinkshellName(uint idx) { var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.CrossWorldLinkShell); - if (infoProxy == IntPtr.Zero) + if (infoProxy == nint.Zero) return null; var utf = GetCrossLinkshellNameNative(infoProxy, idx); @@ -208,7 +208,7 @@ internal sealed unsafe class Chat : IDisposable if (mode == RotateMode.None && LinkshellCycleOffset != null) { // for the branch at 6.08: 5E1680 - var uiModule = (IntPtr) Framework.Instance()->GetUiModule(); + var uiModule = (nint) Framework.Instance()->GetUiModule(); *(int*) (uiModule + LinkshellCycleOffset.Value) = -1; } @@ -428,10 +428,10 @@ internal sealed unsafe class Chat : IDisposable if (agent == null) return; - ChangeChannelNameDetour((IntPtr) agent); + ChangeChannelNameDetour((nint) agent); } - private byte ChatLogRefreshDetour(IntPtr log, ushort eventId, AtkValue* value) + private byte ChatLogRefreshDetour(nint log, ushort eventId, AtkValue* value) { if (Plugin is { ChatLogWindow.CurrentTab.InputDisabled: true }) return ChatLogRefreshHook!.Original(log, eventId, value); @@ -472,7 +472,7 @@ internal sealed unsafe class Chat : IDisposable var str = value + 2; if (str != null && ((int) str->Type & 0xF) == (int) ValueType.String && str->String != null) { - var add = MemoryHelper.ReadStringNullTerminated((IntPtr) str->String); + var add = MemoryHelper.ReadStringNullTerminated((nint) str->String); if (add.Length > 0) addIfNotPresent = add; } @@ -490,7 +490,7 @@ internal sealed unsafe class Chat : IDisposable return 1; } - private IntPtr ChangeChannelNameDetour(IntPtr agent) + private nint ChangeChannelNameDetour(nint agent) { // Last ShB patch // +0x40 = chat channel (byte or uint?) @@ -499,13 +499,13 @@ internal sealed unsafe class Chat : IDisposable // +0xDA = player name string for tells // +0x120 = player world id for tells var ret = ChangeChannelNameHook!.Original(agent); - if (agent == IntPtr.Zero) + if (agent == nint.Zero) return ret; // E8 ?? ?? ?? ?? 8D 48 F7 // RaptureShellModule + 0xFD0 - var shellModule = (IntPtr) Framework.Instance()->GetUiModule()->GetRaptureShellModule(); - if (shellModule == IntPtr.Zero) + var shellModule = (nint) Framework.Instance()->GetUiModule()->GetRaptureShellModule(); + if (shellModule == nint.Zero) return ret; var channel = (uint) InputChannel.Say; @@ -521,7 +521,7 @@ internal sealed unsafe class Chat : IDisposable if (namePtrPtr != null) { var namePtr = *namePtrPtr; - name = MemoryHelper.ReadSeStringNullTerminated((IntPtr) namePtr); + name = MemoryHelper.ReadSeStringNullTerminated((nint) namePtr); if (name.Payloads.Count == 0) name = null; } @@ -552,7 +552,7 @@ internal sealed unsafe class Chat : IDisposable if (ReplyChannelOffset == null) goto Original; - var replyMode = *(int*) ((IntPtr) agent + ReplyChannelOffset.Value); + var replyMode = *(int*) ((nint) agent + ReplyChannelOffset.Value); if (replyMode == -2) goto Original; @@ -562,7 +562,7 @@ internal sealed unsafe class Chat : IDisposable ReplyInSelectedChatModeHook!.Original(agent); } - private byte SetChatLogTellTargetDetour(IntPtr a1, Utf8String* name, Utf8String* a3, ushort world, ulong contentId, ushort reason, byte a7) + private byte SetChatLogTellTargetDetour(nint a1, Utf8String* name, Utf8String* a3, ushort world, ulong contentId, ushort reason, byte a7) { if (name != null) { @@ -655,8 +655,8 @@ internal sealed unsafe class Chat : IDisposable private Keybind? GetKeybind(string id) { - var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Configkey); - if (agent == IntPtr.Zero) + var agent = (nint) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Configkey); + if (agent == nint.Zero) return null; var a1 = *(void**) (agent + 0x78); @@ -665,7 +665,7 @@ internal sealed unsafe class Chat : IDisposable var outData = stackalloc byte[32]; var idString = Utf8String.FromString(id); - GetKeybindNative((IntPtr) a1, idString, (IntPtr) outData); + GetKeybindNative((nint) a1, idString, (nint) outData); idString->Dtor(true); var key1 = (VirtualKey) outData[0]; @@ -692,10 +692,10 @@ internal sealed unsafe class Chat : IDisposable return null; var ptr = GetTellHistory(acquaintanceModule, index); - if (ptr == IntPtr.Zero) + if (ptr == nint.Zero) return null; - var name = MemoryHelper.ReadStringNullTerminated(*(IntPtr*) ptr); + var name = MemoryHelper.ReadStringNullTerminated(*(nint*) ptr); var world = *(ushort*) (ptr + 0xD0); var contentId = *(ulong*) (ptr + 0xD8); diff --git a/ChatTwo/Message.cs b/ChatTwo/Message.cs index e411185..4e4555f 100755 --- a/ChatTwo/Message.cs +++ b/ChatTwo/Message.cs @@ -157,12 +157,15 @@ internal partial class Message newChunks.Add(chunk); } + var nextIsAutoTranslate = false; var checkForEmotes = (Code.IsPlayerMessage() || extraChatChannel != Guid.Empty) && Plugin.Config.ShowEmotes; foreach (var chunk in oldChunks) { - // Use as is if it's not a text chunk, or it already has a payload. - if (chunk is not TextChunk text || chunk.Link != null) + // Use as is if it's not a text chunk, it already has a payload, or is auto translate + if (chunk is not TextChunk text || chunk.Link != null || nextIsAutoTranslate) { + nextIsAutoTranslate = ((IconChunk)chunk).Icon == BitmapFontIcon.AutoTranslateBegin; + // No need to call AddChunkWithMessage here since the chunk // already has the Message field set. newChunks.Add(chunk); diff --git a/ChatTwo/Ui/ChatLogWindow.cs b/ChatTwo/Ui/ChatLogWindow.cs index 20a0194..73460ea 100644 --- a/ChatTwo/Ui/ChatLogWindow.cs +++ b/ChatTwo/Ui/ChatLogWindow.cs @@ -1483,7 +1483,7 @@ public sealed class ChatLogWindow : Window } Plugin.CommandHelpWindow.IsOpen = false; - var text = MemoryHelper.ReadString((IntPtr) data->Buf, data->BufTextLen); + var text = MemoryHelper.ReadString((nint) data->Buf, data->BufTextLen); if (text.StartsWith('/')) { var command = text.Split(' ')[0]; diff --git a/ChatTwo/Ui/InputPreview.cs b/ChatTwo/Ui/InputPreview.cs index 997af7d..6ff815a 100644 --- a/ChatTwo/Ui/InputPreview.cs +++ b/ChatTwo/Ui/InputPreview.cs @@ -177,13 +177,8 @@ public partial class InputPreview : Window return; NextChunkIsAutoTranslate = true; - - // TODO: Remove after Key and Group in AutoTranslatePayload became public - // Skipping: StartByte, PayloadType, PayloadLength - using var reader = new BinaryReader(new MemoryStream(chunk.Link!.Encode().Skip(3).ToArray())); - var group = (uint) reader.ReadByte(); - var key = PayloadExt.GetInteger(reader); - CursorPosition += $"".Length; + var payload = (AutoTranslatePayload) chunk.Link!; + CursorPosition += $"".Length; return; } diff --git a/ChatTwo/Util/AutoTranslate.cs b/ChatTwo/Util/AutoTranslate.cs index b3379d6..6ad9dbe 100644 --- a/ChatTwo/Util/AutoTranslate.cs +++ b/ChatTwo/Util/AutoTranslate.cs @@ -268,7 +268,7 @@ internal static class AutoTranslate } [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int memcmp(byte[] b1, byte[] b2, UIntPtr count); + private static extern int memcmp(byte[] b1, byte[] b2, nuint count); internal static void ReplaceWithPayload(ref byte[] bytes) { @@ -312,7 +312,7 @@ internal static class AutoTranslate } } - if (i + search.Length < bytes.Length && memcmp(bytes[i..], search, (UIntPtr) search.Length) == 0) + if (i + search.Length < bytes.Length && memcmp(bytes[i..], search, (nuint) search.Length) == 0) start = i; } } diff --git a/ChatTwo/Util/Payloads.cs b/ChatTwo/Util/Payloads.cs index d075f2f..f8761ad 100755 --- a/ChatTwo/Util/Payloads.cs +++ b/ChatTwo/Util/Payloads.cs @@ -2,33 +2,6 @@ using Dalamud.Game.Text.SeStringHandling; namespace ChatTwo.Util; -internal static class PayloadExt -{ - // TODO: Remove after Key and Group in AutoTranslatePayload became public - // From: https://github.com/goatcorp/Dalamud/blob/master/Dalamud/Game/Text/SeStringHandling/Payload.cs#L366 - /// - /// Retrieve the packed integer from SE's native data format. - /// - /// The BinaryReader instance. - /// An integer. - internal static uint GetInteger(BinaryReader input) - { - uint marker = input.ReadByte(); - if (marker < 0xD0) - return marker - 1; - - marker = (marker + 1) & 0b1111; - - var ret = new byte[4]; - for (var i = 3; i >= 0; i--) - { - ret[i] = (marker & (1 << i)) == 0 ? (byte)0 : input.ReadByte(); - } - - return BitConverter.ToUInt32(ret, 0); - } -} - internal class PartyFinderPayload : Payload { public override PayloadType Type => (PayloadType) 0x50; diff --git a/ChatTwo/Util/StringUtil.cs b/ChatTwo/Util/StringUtil.cs index d54456e..c21b9b7 100755 --- a/ChatTwo/Util/StringUtil.cs +++ b/ChatTwo/Util/StringUtil.cs @@ -12,7 +12,7 @@ internal static class StringUtil { } // Taken from https://stackoverflow.com/a/4975942 - internal static String BytesToString(long byteCount) { + internal static string BytesToString(long byteCount) { string[] suf = ["B", "KB", "MB", "GB", "TB", "PB", "EB"]; // Longs run out around EB if (byteCount == 0) return "0" + suf[0];