- Handle NBSP payloads

- Use ingame version of axis font
This commit is contained in:
Infi
2024-11-21 08:34:24 +01:00
parent 56eff572b7
commit 1a1995759a
14 changed files with 60 additions and 95 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>1.29.8</Version>
<Version>1.29.9</Version>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
+2 -5
View File
@@ -20,7 +20,6 @@ public class FontManager
private ushort[] Ranges;
private ushort[] JpRange;
private readonly ushort[] SymRange = [0xE020, 0xE0DB, 0];
public static readonly HashSet<float> AxisFontSizeList =
@@ -123,8 +122,7 @@ public class FontManager
Plugin.Config.JapaneseFontV2.FontId.AddToBuildToolkit(tk, config);
config.SizePt = Plugin.Config.SymbolsFontSizeV2;
config.GlyphRanges = SymRange;
tk.AddFontFromMemory(GameSymFont, config, "ChatTwo2 Sym Font");
tk.AddGameSymbol(config);
tk.Font = config.MergeFont;
}
@@ -144,8 +142,7 @@ public class FontManager
Plugin.Config.JapaneseFontV2.FontId.AddToBuildToolkit(tk, config);
config.SizePt = Plugin.Config.SymbolsFontSizeV2;
config.GlyphRanges = SymRange;
tk.AddFontFromMemory(GameSymFont, config, "ChatTwo2 Sym Font");
tk.AddGameSymbol(config);
tk.Font = config.MergeFont;
}
+5 -17
View File
@@ -1,32 +1,20 @@
using System.Text;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI;
namespace ChatTwo.GameFunctions;
// From: https://git.anna.lgbt/anna/XivCommon/src/branch/main/XivCommon/Functions/Chat.cs
public unsafe class ChatCommon
public unsafe class ChatBox
{
[Signature("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B F2 48 8B F9 45 84 C9")]
private readonly delegate* unmanaged<UIModule*, Utf8String*, nint, byte, void> ProcessChatBox = null!;
internal ChatCommon()
public static void SendMessageUnsafe(byte[] message)
{
Plugin.GameInteropProvider.InitializeFromAttributes(this);
}
public void SendMessageUnsafe(byte[] message)
{
if (ProcessChatBox == null)
throw new InvalidOperationException("Could not find signature for chat sending");
var mes = Utf8String.FromSequence(message);
ProcessChatBox(UIModule.Instance(), mes, IntPtr.Zero, 0);
UIModule.Instance()->ProcessChatBoxEntry(mes);
mes->Dtor(true);
}
public void SendMessage(string message)
public static void SendMessage(string message)
{
var bytes = Encoding.UTF8.GetBytes(message);
if (bytes.Length == 0)
@@ -45,7 +33,7 @@ public unsafe class ChatCommon
{
var uText = Utf8String.FromString(text);
uText->SanitizeString( 0x27F, (Utf8String*)nint.Zero);
uText->SanitizeString(0x27F, (Utf8String*)nint.Zero);
var sanitised = uText->ToString();
uText->Dtor(true);
+3 -2
View File
@@ -12,6 +12,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Info;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel;
using Lumina.Excel.Sheets;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
namespace ChatTwo.GameFunctions;
@@ -66,10 +67,10 @@ internal unsafe class GameFunctions : IDisposable
var worldName = row.Name.ExtractText();
ReplacementName = $"{name}@{worldName}";
Plugin.Common.SendMessage($"/{commandName} add {Placeholder}");
ChatBox.SendMessage($"/{commandName} add {Placeholder}");
}
internal static T* GetAddon<T>(string name) where T : unmanaged
private static T* GetAddon<T>(string name) where T : unmanaged
{
var addon = RaptureAtkModule.Instance()->RaptureAtkUnitManager.GetAddonByName(name);
return addon != null && addon->IsReady ? (T*)addon : null;
-3
View File
@@ -1,7 +1,6 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using ChatTwo.GameFunctions;
using ChatTwo.Http;
using ChatTwo.Ipc;
using ChatTwo.Resources;
@@ -53,7 +52,6 @@ public sealed class Plugin : IDalamudPlugin
public DebuggerWindow DebuggerWindow { get; }
internal Commands Commands { get; }
internal ChatCommon Common { get; }
internal GameFunctions.GameFunctions Functions { get; }
internal MessageManager MessageManager { get; }
internal IpcManager Ipc { get; }
@@ -97,7 +95,6 @@ public sealed class Plugin : IDalamudPlugin
ServerCore = new ServerCore(this);
Commands = new Commands(this);
Common = new ChatCommon();
Functions = new GameFunctions.GameFunctions(this);
Ipc = new IpcManager();
ExtraChat = new ExtraChat(this);
+4 -4
View File
@@ -877,7 +877,7 @@ public sealed class ChatLogWindow : Window
// registers stub handlers and actually processes its commands in a
// SendMessage detour.
var bytes = Encoding.UTF8.GetBytes(channel.Value.Prefix());
Plugin.Common.SendMessageUnsafe(bytes);
ChatBox.SendMessageUnsafe(bytes);
return;
}
@@ -921,7 +921,7 @@ public sealed class ChatLogWindow : Window
var tellBytes = Encoding.UTF8.GetBytes(trimmed);
AutoTranslate.ReplaceWithPayload(ref tellBytes);
Plugin.Common.SendMessageUnsafe(tellBytes);
ChatBox.SendMessageUnsafe(tellBytes);
Chat = string.Empty;
return;
@@ -949,14 +949,14 @@ public sealed class ChatLogWindow : Window
if (activeTab.CurrentChannel.UseTempChannel)
trimmed = $"{activeTab.CurrentChannel.TempChannel.Prefix()} {trimmed}";
else // (activeTab is { Channel: { } channel }) TODO Check this channel selection
else
trimmed = $"{activeTab.CurrentChannel.Channel.Prefix()} {trimmed}";
}
var bytes = Encoding.UTF8.GetBytes(trimmed);
AutoTranslate.ReplaceWithPayload(ref bytes);
Plugin.Common.SendMessageUnsafe(bytes);
ChatBox.SendMessageUnsafe(bytes);
}
Chat = string.Empty;
-1
View File
@@ -1,6 +1,5 @@
using System.Numerics;
using Dalamud.Interface.Windowing;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using ImGuiNET;
+17 -32
View File
@@ -1,12 +1,13 @@
using System.Numerics;
using System.Globalization;
using System.Numerics;
using System.Text;
using ChatTwo.Util;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Interface.Windowing;
using ImGuiNET;
using Lumina.Excel;
using Lumina.Excel.Sheets;
using DalamudPartyFinderPayload = Dalamud.Game.Text.SeStringHandling.Payloads.PartyFinderPayload;
namespace ChatTwo.Ui;
@@ -15,7 +16,7 @@ public class SeStringDebugger : Window
{
private readonly Plugin Plugin;
public SeStringDebugger(Plugin plugin) : base($"SeString Debugger###chat2-sestringdebugger")
public SeStringDebugger(Plugin plugin) : base("SeString Debugger###chat2-sestringdebugger")
{
Plugin = plugin;
@@ -92,8 +93,8 @@ public class SeStringDebugger : Window
{ "TerritoryType.RowId", map.TerritoryType.RowId.ToString() },
{ "RawX", map.RawX.ToString() },
{ "RawY", map.RawY.ToString() },
{ "XCoord", map.XCoord.ToString() },
{ "YCoord", map.YCoord.ToString() },
{ "XCoord", map.XCoord.ToString(CultureInfo.InvariantCulture) },
{ "YCoord", map.YCoord.ToString(CultureInfo.InvariantCulture) },
{ "CoordinateString", map.CoordinateString },
{ "DataString", map.DataString },
});
@@ -160,7 +161,7 @@ public class SeStringDebugger : Window
}
case IconPayload icon:
{
var found = IconUtil.GfdFileView.TryGetEntry((uint) icon.Icon, out var entry);
var found = IconUtil.GfdFileView.TryGetEntry((uint) icon.Icon, out _);
RenderMetadataDictionary("Link IconPayload", new Dictionary<string, string?>
{
{ "Found", found.ToString() },
@@ -173,15 +174,12 @@ public class SeStringDebugger : Window
var colorPayload = ColorPayload.From(raw.Data);
if (colorPayload != null)
{
var push = colorPayload.Enabled && colorPayload.Color != 0;
// if (push) ImGui.PushStyleColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(colorPayload.U));
RenderMetadataDictionary("Link ColorPayload", new Dictionary<string, string?>
{
{ "Unshifted", colorPayload.UnshiftedColor.ToString("X8") },
{ "Color", colorPayload.Color.ToString("X8") },
{ "Enabled?", colorPayload.Enabled.ToString() },
});
// if (push) ImGui.PopStyleColor();
}
else
{
@@ -289,10 +287,8 @@ public class SeStringDebugger : Window
{
if (string.IsNullOrEmpty(original))
{
var str = original == null ? "(null)" : "(empty)";
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
ImGui.TextUnformatted(str);
ImGui.PopStyleColor();
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
ImGui.TextUnformatted(original == null ? "(null)" : "(empty)");
return;
}
@@ -300,46 +296,35 @@ public class SeStringDebugger : Window
var start = 0;
var end = text.Length;
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
using var pushedStyle = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
void WriteText(string text)
void WriteText(string wText)
{
if (wrap)
{
ImGui.TextWrapped(text);
}
ImGui.TextWrapped(wText);
else
{
ImGui.TextUnformatted(text);
}
ImGui.TextUnformatted(wText);
}
while (start < end && char.IsWhiteSpace(text[start]))
{
start++;
}
if (start > 0)
{
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
WriteText(new string('_', start));
ImGui.PopStyleColor();
ImGui.SameLine();
}
while (end > start && char.IsWhiteSpace(text[end - 1]))
{
end--;
}
WriteText(text[start..end]);
if (end < text.Length)
{
ImGui.SameLine();
ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, new Vector4(1, 1, 1, 0.5f));
WriteText(new string('_', text.Length - end));
ImGui.PopStyleColor();
}
ImGui.PopStyleVar();
}
}
+6 -6
View File
@@ -31,21 +31,21 @@ public sealed class SettingsWindow : Window
Plugin = plugin;
Mutable = new Configuration();
Tabs = new List<ISettingsTab>
{
Tabs =
[
new Display(Mutable),
new ChatLog(Plugin, Mutable),
new Emote(Plugin, Mutable),
new Preview(Plugin, Mutable),
new Preview(Mutable),
new Fonts(Mutable),
new ChatColours(Plugin, Mutable),
new Tabs(Plugin, Mutable),
new Tabs(Mutable),
new Database(Plugin, Mutable),
new Webinterface(Plugin, Mutable),
new Miscellaneous(Mutable),
new Changelog(Mutable),
new About(),
};
new About()
];
RespectCloseHotkey = false;
DisableWindowSounds = true;
+3 -5
View File
@@ -13,7 +13,7 @@ internal sealed class About : ISettingsTab
{
public string Name => string.Format(Language.Options_About_Tab, Plugin.PluginName) + "###tabs-about";
private readonly List<string> _translators =
private readonly List<string> Translators =
[
"q673135110", "Akizem", "d0tiKs",
"Moonlight_Everlit", "Dark32", "andreycout",
@@ -28,7 +28,7 @@ internal sealed class About : ISettingsTab
internal About()
{
_translators.Sort((a, b) => string.Compare(a.ToLowerInvariant(), b.ToLowerInvariant(), StringComparison.Ordinal));
Translators.Sort((a, b) => string.Compare(a.ToLowerInvariant(), b.ToLowerInvariant(), StringComparison.Ordinal));
}
public void Draw(bool changed)
@@ -85,10 +85,8 @@ internal sealed class About : ISettingsTab
using var translatorChild = ImRaii.Child("translators");
if (translatorChild)
{
foreach (var translator in _translators)
{
foreach (var translator in Translators)
ImGui.TextUnformatted(translator);
}
}
}
}
+2 -4
View File
@@ -6,14 +6,12 @@ namespace ChatTwo.Ui.SettingsTabs;
internal sealed class Preview : ISettingsTab
{
private readonly Plugin Plugin;
private Configuration Mutable { get; }
public string Name => Language.Options_Preview_Tab + "###tabs-preview";
public string Name => $"{Language.Options_Preview_Tab}###tabs-preview";
internal Preview(Plugin plugin, Configuration mutable)
internal Preview(Configuration mutable)
{
Plugin = plugin;
Mutable = mutable;
}
+8 -10
View File
@@ -9,16 +9,14 @@ namespace ChatTwo.Ui.SettingsTabs;
internal sealed class Tabs : ISettingsTab
{
private Plugin Plugin { get; }
private Configuration Mutable { get; }
public string Name => Language.Options_Tabs_Tab + "###tabs-tabs";
private int _toOpen = -2;
private int ToOpen = -2;
internal Tabs(Plugin plugin, Configuration mutable)
internal Tabs(Configuration mutable)
{
Plugin = plugin;
Mutable = mutable;
}
@@ -47,13 +45,13 @@ internal sealed class Tabs : ISettingsTab
}
var toRemove = -1;
var doOpens = _toOpen > -2;
var doOpens = ToOpen > -2;
for (var i = 0; i < Mutable.Tabs.Count; i++)
{
var tab = Mutable.Tabs[i];
if (doOpens)
ImGui.SetNextItemOpen(i == _toOpen);
ImGui.SetNextItemOpen(i == ToOpen);
using var treeNode = ImRaii.TreeNode($"{tab.Name}###tab-{i}");
if (!treeNode.Success)
@@ -64,7 +62,7 @@ internal sealed class Tabs : ISettingsTab
if (ImGuiUtil.IconButton(FontAwesomeIcon.TrashAlt, tooltip: Language.Options_Tabs_Delete))
{
toRemove = i;
_toOpen = -1;
ToOpen = -1;
}
ImGui.SameLine();
@@ -72,7 +70,7 @@ internal sealed class Tabs : ISettingsTab
if (ImGuiUtil.IconButton(FontAwesomeIcon.ArrowUp, tooltip: Language.Options_Tabs_MoveUp) && i > 0)
{
(Mutable.Tabs[i - 1], Mutable.Tabs[i]) = (Mutable.Tabs[i], Mutable.Tabs[i - 1]);
_toOpen = i - 1;
ToOpen = i - 1;
}
ImGui.SameLine();
@@ -80,7 +78,7 @@ internal sealed class Tabs : ISettingsTab
if (ImGuiUtil.IconButton(FontAwesomeIcon.ArrowDown, tooltip: Language.Options_Tabs_MoveDown) && i < Mutable.Tabs.Count - 1)
{
(Mutable.Tabs[i + 1], Mutable.Tabs[i]) = (Mutable.Tabs[i], Mutable.Tabs[i + 1]);
_toOpen = i + 1;
ToOpen = i + 1;
}
ImGui.InputText(Language.Options_Tabs_Name, ref tab.Name, 512, ImGuiInputTextFlags.EnterReturnsTrue);
@@ -135,6 +133,6 @@ internal sealed class Tabs : ISettingsTab
Mutable.Tabs.RemoveAt(toRemove);
if (doOpens)
_toOpen = -2;
ToOpen = -2;
}
}
+8
View File
@@ -2,6 +2,9 @@ using ChatTwo.Code;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using System.Text;
using Lumina.Text.Payloads;
using PayloadType = Dalamud.Game.Text.SeStringHandling.PayloadType;
namespace ChatTwo.Util;
@@ -112,6 +115,11 @@ internal static class ChunkUtil
var id = GetInteger(reader);
link = new AchievementPayload(id);
}
else if (rawPayload.Data is [_, (byte)MacroCode.NonBreakingSpace, _, _])
{
// NonBreakingSpace payload
Append(" ");
}
// NOTE: no URIPayload because it originates solely from
// new Message(). The game doesn't have a URI payload type.
else if (Equals(rawPayload, RawPayload.LinkTerminator))
+1 -5
View File
@@ -1,8 +1,4 @@
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.UI.Misc;
using FFXIVClientStructs.FFXIV.Component.Text;
namespace ChatTwo.Util;
namespace ChatTwo.Util;
public class ColorPayload
{