- No emote parsing on AutoTranslate
- nint everything
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.25.4</Version>
|
<Version>1.25.5</Version>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ internal static class ExtraGlyphRangesExt
|
|||||||
_ => throw new ArgumentOutOfRangeException(nameof(ranges), ranges, null),
|
_ => 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.ChineseFull => ImGui.GetIO().Fonts.GetGlyphRangesChineseFull(),
|
||||||
ExtraGlyphRanges.ChineseSimplifiedCommon => ImGui.GetIO().Fonts.GetGlyphRangesChineseSimplifiedCommon(),
|
ExtraGlyphRanges.ChineseSimplifiedCommon => ImGui.GetIO().Fonts.GetGlyphRangesChineseSimplifiedCommon(),
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class FontManager
|
|||||||
|
|
||||||
private unsafe void SetUpRanges()
|
private unsafe void SetUpRanges()
|
||||||
{
|
{
|
||||||
ushort[] BuildRange(IReadOnlyList<ushort>? chars, params IntPtr[] ranges)
|
ushort[] BuildRange(IReadOnlyList<ushort>? chars, params nint[] ranges)
|
||||||
{
|
{
|
||||||
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
||||||
// text
|
// text
|
||||||
@@ -85,7 +85,7 @@ public class FontManager
|
|||||||
return builder.BuildRangesToArray();
|
return builder.BuildRangesToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var ranges = new List<IntPtr> { ImGui.GetIO().Fonts.GetGlyphRangesDefault() };
|
var ranges = new List<nint> { ImGui.GetIO().Fonts.GetGlyphRangesDefault() };
|
||||||
foreach (var extraRange in Enum.GetValues<ExtraGlyphRanges>())
|
foreach (var extraRange in Enum.GetValues<ExtraGlyphRanges>())
|
||||||
if (Plugin.Config.ExtraGlyphRanges.HasFlag(extraRange))
|
if (Plugin.Config.ExtraGlyphRanges.HasFlag(extraRange))
|
||||||
ranges.Add(extraRange.Range());
|
ranges.Add(extraRange.Range());
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
private readonly delegate* unmanaged<RaptureShellModule*, Utf8String*, Utf8String*, ushort, ulong, ushort, byte, bool> SetChannelTargetTell = null!;
|
private readonly delegate* unmanaged<RaptureShellModule*, Utf8String*, Utf8String*, ushort, ulong, ushort, byte, bool> SetChannelTargetTell = null!;
|
||||||
|
|
||||||
[Signature("E8 ?? ?? ?? ?? 48 8D 4D A0 8B F8")]
|
[Signature("E8 ?? ?? ?? ?? 48 8D 4D A0 8B F8")]
|
||||||
private readonly delegate* unmanaged<nint, Utf8String*, IntPtr, uint> GetKeybindNative = null!;
|
private readonly delegate* unmanaged<nint, Utf8String*, nint, uint> GetKeybindNative = null!;
|
||||||
|
|
||||||
// TODO Replace with CS in AcquaintanceModule
|
// TODO Replace with CS in AcquaintanceModule
|
||||||
[Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1 45 85 C9")]
|
[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)
|
internal string? GetLinkshellName(uint idx)
|
||||||
{
|
{
|
||||||
var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.LinkShell);
|
var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.LinkShell);
|
||||||
if (infoProxy == IntPtr.Zero)
|
if (infoProxy == nint.Zero)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var lsInfo = GetLinkshellInfo(infoProxy, idx);
|
var lsInfo = GetLinkshellInfo(infoProxy, idx);
|
||||||
@@ -190,13 +190,13 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var utf = GetLinkshellNameNative(infoProxy, *lsInfo);
|
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)
|
internal string? GetCrossLinkshellName(uint idx)
|
||||||
{
|
{
|
||||||
var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.CrossWorldLinkShell);
|
var infoProxy = Plugin.Functions.GetInfoProxyByIndex(InfoProxyId.CrossWorldLinkShell);
|
||||||
if (infoProxy == IntPtr.Zero)
|
if (infoProxy == nint.Zero)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var utf = GetCrossLinkshellNameNative(infoProxy, idx);
|
var utf = GetCrossLinkshellNameNative(infoProxy, idx);
|
||||||
@@ -208,7 +208,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (mode == RotateMode.None && LinkshellCycleOffset != null)
|
if (mode == RotateMode.None && LinkshellCycleOffset != null)
|
||||||
{
|
{
|
||||||
// for the branch at 6.08: 5E1680
|
// for the branch at 6.08: 5E1680
|
||||||
var uiModule = (IntPtr) Framework.Instance()->GetUiModule();
|
var uiModule = (nint) Framework.Instance()->GetUiModule();
|
||||||
*(int*) (uiModule + LinkshellCycleOffset.Value) = -1;
|
*(int*) (uiModule + LinkshellCycleOffset.Value) = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,10 +428,10 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (agent == null)
|
if (agent == null)
|
||||||
return;
|
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 })
|
if (Plugin is { ChatLogWindow.CurrentTab.InputDisabled: true })
|
||||||
return ChatLogRefreshHook!.Original(log, eventId, value);
|
return ChatLogRefreshHook!.Original(log, eventId, value);
|
||||||
@@ -472,7 +472,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
var str = value + 2;
|
var str = value + 2;
|
||||||
if (str != null && ((int) str->Type & 0xF) == (int) ValueType.String && str->String != null)
|
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)
|
if (add.Length > 0)
|
||||||
addIfNotPresent = add;
|
addIfNotPresent = add;
|
||||||
}
|
}
|
||||||
@@ -490,7 +490,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr ChangeChannelNameDetour(IntPtr agent)
|
private nint ChangeChannelNameDetour(nint agent)
|
||||||
{
|
{
|
||||||
// Last ShB patch
|
// Last ShB patch
|
||||||
// +0x40 = chat channel (byte or uint?)
|
// +0x40 = chat channel (byte or uint?)
|
||||||
@@ -499,13 +499,13 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
// +0xDA = player name string for tells
|
// +0xDA = player name string for tells
|
||||||
// +0x120 = player world id for tells
|
// +0x120 = player world id for tells
|
||||||
var ret = ChangeChannelNameHook!.Original(agent);
|
var ret = ChangeChannelNameHook!.Original(agent);
|
||||||
if (agent == IntPtr.Zero)
|
if (agent == nint.Zero)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
// E8 ?? ?? ?? ?? 8D 48 F7
|
// E8 ?? ?? ?? ?? 8D 48 F7
|
||||||
// RaptureShellModule + 0xFD0
|
// RaptureShellModule + 0xFD0
|
||||||
var shellModule = (IntPtr) Framework.Instance()->GetUiModule()->GetRaptureShellModule();
|
var shellModule = (nint) Framework.Instance()->GetUiModule()->GetRaptureShellModule();
|
||||||
if (shellModule == IntPtr.Zero)
|
if (shellModule == nint.Zero)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
var channel = (uint) InputChannel.Say;
|
var channel = (uint) InputChannel.Say;
|
||||||
@@ -521,7 +521,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (namePtrPtr != null)
|
if (namePtrPtr != null)
|
||||||
{
|
{
|
||||||
var namePtr = *namePtrPtr;
|
var namePtr = *namePtrPtr;
|
||||||
name = MemoryHelper.ReadSeStringNullTerminated((IntPtr) namePtr);
|
name = MemoryHelper.ReadSeStringNullTerminated((nint) namePtr);
|
||||||
if (name.Payloads.Count == 0)
|
if (name.Payloads.Count == 0)
|
||||||
name = null;
|
name = null;
|
||||||
}
|
}
|
||||||
@@ -552,7 +552,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
if (ReplyChannelOffset == null)
|
if (ReplyChannelOffset == null)
|
||||||
goto Original;
|
goto Original;
|
||||||
|
|
||||||
var replyMode = *(int*) ((IntPtr) agent + ReplyChannelOffset.Value);
|
var replyMode = *(int*) ((nint) agent + ReplyChannelOffset.Value);
|
||||||
if (replyMode == -2)
|
if (replyMode == -2)
|
||||||
goto Original;
|
goto Original;
|
||||||
|
|
||||||
@@ -562,7 +562,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
ReplyInSelectedChatModeHook!.Original(agent);
|
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)
|
if (name != null)
|
||||||
{
|
{
|
||||||
@@ -655,8 +655,8 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
|
|
||||||
private Keybind? GetKeybind(string id)
|
private Keybind? GetKeybind(string id)
|
||||||
{
|
{
|
||||||
var agent = (IntPtr) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Configkey);
|
var agent = (nint) Framework.Instance()->GetUiModule()->GetAgentModule()->GetAgentByInternalId(AgentId.Configkey);
|
||||||
if (agent == IntPtr.Zero)
|
if (agent == nint.Zero)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var a1 = *(void**) (agent + 0x78);
|
var a1 = *(void**) (agent + 0x78);
|
||||||
@@ -665,7 +665,7 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
|
|
||||||
var outData = stackalloc byte[32];
|
var outData = stackalloc byte[32];
|
||||||
var idString = Utf8String.FromString(id);
|
var idString = Utf8String.FromString(id);
|
||||||
GetKeybindNative((IntPtr) a1, idString, (IntPtr) outData);
|
GetKeybindNative((nint) a1, idString, (nint) outData);
|
||||||
idString->Dtor(true);
|
idString->Dtor(true);
|
||||||
|
|
||||||
var key1 = (VirtualKey) outData[0];
|
var key1 = (VirtualKey) outData[0];
|
||||||
@@ -692,10 +692,10 @@ internal sealed unsafe class Chat : IDisposable
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
var ptr = GetTellHistory(acquaintanceModule, index);
|
var ptr = GetTellHistory(acquaintanceModule, index);
|
||||||
if (ptr == IntPtr.Zero)
|
if (ptr == nint.Zero)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var name = MemoryHelper.ReadStringNullTerminated(*(IntPtr*) ptr);
|
var name = MemoryHelper.ReadStringNullTerminated(*(nint*) ptr);
|
||||||
var world = *(ushort*) (ptr + 0xD0);
|
var world = *(ushort*) (ptr + 0xD0);
|
||||||
var contentId = *(ulong*) (ptr + 0xD8);
|
var contentId = *(ulong*) (ptr + 0xD8);
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -157,12 +157,15 @@ internal partial class Message
|
|||||||
newChunks.Add(chunk);
|
newChunks.Add(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nextIsAutoTranslate = false;
|
||||||
var checkForEmotes = (Code.IsPlayerMessage() || extraChatChannel != Guid.Empty) && Plugin.Config.ShowEmotes;
|
var checkForEmotes = (Code.IsPlayerMessage() || extraChatChannel != Guid.Empty) && Plugin.Config.ShowEmotes;
|
||||||
foreach (var chunk in oldChunks)
|
foreach (var chunk in oldChunks)
|
||||||
{
|
{
|
||||||
// Use as is if it's not a text chunk, or it already has a payload.
|
// 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)
|
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
|
// No need to call AddChunkWithMessage here since the chunk
|
||||||
// already has the Message field set.
|
// already has the Message field set.
|
||||||
newChunks.Add(chunk);
|
newChunks.Add(chunk);
|
||||||
|
|||||||
@@ -1483,7 +1483,7 @@ public sealed class ChatLogWindow : Window
|
|||||||
}
|
}
|
||||||
|
|
||||||
Plugin.CommandHelpWindow.IsOpen = false;
|
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('/'))
|
if (text.StartsWith('/'))
|
||||||
{
|
{
|
||||||
var command = text.Split(' ')[0];
|
var command = text.Split(' ')[0];
|
||||||
|
|||||||
@@ -177,13 +177,8 @@ public partial class InputPreview : Window
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
NextChunkIsAutoTranslate = true;
|
NextChunkIsAutoTranslate = true;
|
||||||
|
var payload = (AutoTranslatePayload) chunk.Link!;
|
||||||
// TODO: Remove after Key and Group in AutoTranslatePayload became public
|
CursorPosition += $"<at:{payload.Group},{payload.Key}>".Length;
|
||||||
// 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 += $"<at:{group},{key}>".Length;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ internal static class AutoTranslate
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
[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)
|
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;
|
start = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,33 +2,6 @@ using Dalamud.Game.Text.SeStringHandling;
|
|||||||
|
|
||||||
namespace ChatTwo.Util;
|
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
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieve the packed integer from SE's native data format.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The BinaryReader instance.</param>
|
|
||||||
/// <returns>An integer.</returns>
|
|
||||||
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 {
|
internal class PartyFinderPayload : Payload {
|
||||||
public override PayloadType Type => (PayloadType) 0x50;
|
public override PayloadType Type => (PayloadType) 0x50;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ internal static class StringUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Taken from https://stackoverflow.com/a/4975942
|
// 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
|
string[] suf = ["B", "KB", "MB", "GB", "TB", "PB", "EB"]; // Longs run out around EB
|
||||||
if (byteCount == 0)
|
if (byteCount == 0)
|
||||||
return "0" + suf[0];
|
return "0" + suf[0];
|
||||||
|
|||||||
Reference in New Issue
Block a user