- More ImRaii
- Cleanup - Spanish, French, Dutch, Chinese loc update
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.29.9</Version>
|
<Version>1.29.10</Version>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
using Dalamud.Plugin;
|
|
||||||
using Dalamud.Plugin.Ipc;
|
using Dalamud.Plugin.Ipc;
|
||||||
|
|
||||||
namespace ChatTwo;
|
namespace ChatTwo;
|
||||||
|
|||||||
@@ -103,12 +103,8 @@ internal class MessageManager : IAsyncDisposable
|
|||||||
LastContentId = contentId;
|
LastContentId = contentId;
|
||||||
|
|
||||||
// Drain the PendingSync queue into the PendingAsync queue.
|
// Drain the PendingSync queue into the PendingAsync queue.
|
||||||
while (true)
|
while (PendingSync.TryDequeue(out var pending))
|
||||||
{
|
|
||||||
if (!PendingSync.TryDequeue(out var pending))
|
|
||||||
return;
|
|
||||||
PendingAsync.Enqueue(pending);
|
PendingAsync.Enqueue(pending);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessPendingMessages(CancellationToken token)
|
private void ProcessPendingMessages(CancellationToken token)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using MessagePack;
|
|||||||
using MessagePack.Formatters;
|
using MessagePack.Formatters;
|
||||||
using MessagePack.Resolvers;
|
using MessagePack.Resolvers;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
|
|
||||||
using DalamudUtil = Dalamud.Utility.Util;
|
using DalamudUtil = Dalamud.Utility.Util;
|
||||||
using Encoding = System.Text.Encoding;
|
using Encoding = System.Text.Encoding;
|
||||||
|
|
||||||
@@ -118,11 +119,7 @@ internal class MessageStore : IDisposable
|
|||||||
private SqliteConnection Connection { get; set; }
|
private SqliteConnection Connection { get; set; }
|
||||||
|
|
||||||
internal static readonly MessagePackSerializerOptions MsgPackOptions = MessagePackSerializerOptions.Standard
|
internal static readonly MessagePackSerializerOptions MsgPackOptions = MessagePackSerializerOptions.Standard
|
||||||
.WithResolver(CompositeResolver.Create(
|
.WithResolver(CompositeResolver.Create([new PayloadMessagePackFormatter(), new SeStringMessagePackFormatter()], [StandardResolver.Instance]));
|
||||||
new IMessagePackFormatter[] { new PayloadMessagePackFormatter(), new SeStringMessagePackFormatter(), },
|
|
||||||
new IFormatterResolver[] { StandardResolver.Instance }
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
internal MessageStore(string dbPath)
|
internal MessageStore(string dbPath)
|
||||||
{
|
{
|
||||||
|
|||||||
+51
-61
@@ -27,7 +27,8 @@ using ChatTwoPartyFinderPayload = ChatTwo.Util.PartyFinderPayload;
|
|||||||
|
|
||||||
namespace ChatTwo;
|
namespace ChatTwo;
|
||||||
|
|
||||||
public sealed class PayloadHandler {
|
public sealed class PayloadHandler
|
||||||
|
{
|
||||||
private const string PopupId = "chat2-context-popup";
|
private const string PopupId = "chat2-context-popup";
|
||||||
|
|
||||||
private ChatLogWindow LogWindow { get; }
|
private ChatLogWindow LogWindow { get; }
|
||||||
@@ -105,35 +106,33 @@ public sealed class PayloadHandler {
|
|||||||
var contentId = chunk.Message?.ContentId ?? 0;
|
var contentId = chunk.Message?.ContentId ?? 0;
|
||||||
var sender = chunk.Message?.Sender.Select(c => c.Link).FirstOrDefault(p => p is PlayerPayload) as PlayerPayload;
|
var sender = chunk.Message?.Sender.Select(c => c.Link).FirstOrDefault(p => p is PlayerPayload) as PlayerPayload;
|
||||||
|
|
||||||
if (ImGui.BeginMenu(Language.Context_Integrations))
|
using var menu = ImGuiUtil.Menu(Language.Context_Integrations);
|
||||||
|
if (!menu.Success)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var cursor = ImGui.GetCursorPos();
|
||||||
|
foreach (var id in registered)
|
||||||
{
|
{
|
||||||
var cursor = ImGui.GetCursorPos();
|
try
|
||||||
|
|
||||||
foreach (var id in registered)
|
|
||||||
{
|
{
|
||||||
try
|
LogWindow.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource);
|
||||||
{
|
|
||||||
LogWindow.Plugin.Ipc.Invoke(id, sender, contentId, payload, chunk.Message?.SenderSource, chunk.Message?.ContentSource);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Plugin.Log.Error(ex, "Error executing integration");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
if (cursor == ImGui.GetCursorPos())
|
|
||||||
{
|
{
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled]);
|
Plugin.Log.Error(ex, "Error executing integration");
|
||||||
ImGui.Text("No integrations available");
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.EndMenu();
|
if (cursor == ImGui.GetCursorPos())
|
||||||
|
{
|
||||||
|
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int)ImGuiCol.TextDisabled]);
|
||||||
|
ImGui.Text("No integrations available");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ContextFooter(bool didCustomContext, Chunk chunk)
|
private void ContextFooter(bool didCustomContext, Chunk chunk)
|
||||||
{
|
{
|
||||||
|
ImRaii.IEndObject? menu = null;
|
||||||
if (didCustomContext)
|
if (didCustomContext)
|
||||||
{
|
{
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
@@ -143,7 +142,8 @@ public sealed class PayloadHandler {
|
|||||||
//
|
//
|
||||||
// It makes it much more convenient in the majority of cases to
|
// It makes it much more convenient in the majority of cases to
|
||||||
// copy the message content without having to open a submenu.
|
// copy the message content without having to open a submenu.
|
||||||
if (!ImGui.BeginMenu(Plugin.PluginName))
|
menu = ImGuiUtil.Menu(Plugin.PluginName);
|
||||||
|
if (!menu.Success)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,19 +170,11 @@ public sealed class PayloadHandler {
|
|||||||
WrapperUtil.AddNotification(Language.Context_CopyContentSuccess, NotificationType.Info);
|
WrapperUtil.AddNotification(Language.Context_CopyContentSuccess, NotificationType.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
var col = ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled];
|
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled]);
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, col);
|
ImGui.TextUnformatted(message.Code.Type.Name());
|
||||||
try
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted(message.Code.Type.Name());
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ImGui.PopStyleColor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (didCustomContext) ImGui.EndMenu();
|
menu?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string StringifyMessage(Message? message, bool withSender = false)
|
private static string StringifyMessage(Message? message, bool withSender = false)
|
||||||
@@ -191,8 +183,7 @@ public sealed class PayloadHandler {
|
|||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
var chunks = withSender ? message.Sender.Concat(message.Content) : message.Content;
|
var chunks = withSender ? message.Sender.Concat(message.Content) : message.Content;
|
||||||
return chunks
|
return chunks.Where(chunk => chunk is TextChunk)
|
||||||
.Where(chunk => chunk is TextChunk)
|
|
||||||
.Cast<TextChunk>()
|
.Cast<TextChunk>()
|
||||||
.Select(text => text.Content)
|
.Select(text => text.Content)
|
||||||
.Aggregate(string.Concat);
|
.Aggregate(string.Concat);
|
||||||
@@ -214,7 +205,8 @@ public sealed class PayloadHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Hover(Payload payload) {
|
internal void Hover(Payload payload)
|
||||||
|
{
|
||||||
var hoverSize = 350f * ImGuiHelpers.GlobalScale;
|
var hoverSize = 350f * ImGuiHelpers.GlobalScale;
|
||||||
|
|
||||||
switch (payload)
|
switch (payload)
|
||||||
@@ -253,11 +245,12 @@ public sealed class PayloadHandler {
|
|||||||
{
|
{
|
||||||
ImGui.SetNextWindowSize(new Vector2(width, -1f));
|
ImGui.SetNextWindowSize(new Vector2(width, -1f));
|
||||||
|
|
||||||
using var tooltip = ImRaii.Tooltip();
|
using (ImRaii.Tooltip())
|
||||||
using var color = ImRaii.PushColor(ImGuiCol.Text, LogWindow.DefaultText);
|
using (ImGuiUtil.TextWrapPos())
|
||||||
using var wrap = ImGuiUtil.TextWrapPos();
|
using (ImRaii.PushColor(ImGuiCol.Text, LogWindow.DefaultText))
|
||||||
|
{
|
||||||
inside();
|
inside();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void MoveTooltip(AddonEvent type, AddonArgs args)
|
public unsafe void MoveTooltip(AddonEvent type, AddonArgs args)
|
||||||
@@ -348,22 +341,20 @@ public sealed class PayloadHandler {
|
|||||||
|
|
||||||
private void HoverEventItem(ItemPayload payload)
|
private void HoverEventItem(ItemPayload payload)
|
||||||
{
|
{
|
||||||
if (!Sheets.EventItemSheet.HasRow(payload.RawItemId))
|
if (!Sheets.EventItemSheet.TryGetRow(payload.RawItemId, out var itemRow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var item = Sheets.EventItemSheet.GetRow(payload.RawItemId);
|
if (Plugin.TextureProvider.GetFromGameIcon(new GameIconLookup(itemRow.Icon)).GetWrapOrDefault() is { } icon)
|
||||||
if (Plugin.TextureProvider.GetFromGameIcon(new GameIconLookup(item.Icon)).GetWrapOrDefault() is { } icon)
|
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
|
|
||||||
var name = ChunkUtil.ToChunks(item.Name.ToDalamudString(), ChunkSource.None, null);
|
var name = ChunkUtil.ToChunks(itemRow.Name.ToDalamudString(), ChunkSource.None, null);
|
||||||
LogWindow.DrawChunks(name.ToList());
|
LogWindow.DrawChunks(name.ToList());
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (!Sheets.EventItemHelpSheet.HasRow(payload.RawItemId))
|
if (!Sheets.EventItemHelpSheet.TryGetRow(payload.RawItemId, out var itemHelpRow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var help = Sheets.EventItemHelpSheet.GetRow(payload.RawItemId);
|
LogWindow.DrawChunks(ChunkUtil.ToChunks(itemHelpRow.Description.ToDalamudString(), ChunkSource.None, null).ToList());
|
||||||
LogWindow.DrawChunks(ChunkUtil.ToChunks(help.Description.ToDalamudString(), ChunkSource.None, null).ToList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HoverURI(UriPayload uri)
|
private void HoverURI(UriPayload uri)
|
||||||
@@ -452,15 +443,14 @@ public sealed class PayloadHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Sheets.ItemSheet.HasRow(payload.ItemId))
|
if (!Sheets.ItemSheet.TryGetRow(payload.ItemId, out var itemRow))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var item = Sheets.ItemSheet.GetRow(payload.ItemId);
|
|
||||||
var hq = payload.Kind == ItemPayload.ItemKind.Hq;
|
var hq = payload.Kind == ItemPayload.ItemKind.Hq;
|
||||||
if (Plugin.TextureProvider.GetFromGameIcon(new GameIconLookup(item.Icon, hq)).GetWrapOrDefault() is { } icon)
|
if (Plugin.TextureProvider.GetFromGameIcon(new GameIconLookup(itemRow.Icon, hq)).GetWrapOrDefault() is { } icon)
|
||||||
InlineIcon(icon);
|
InlineIcon(icon);
|
||||||
|
|
||||||
var name = item.Name.ToDalamudString();
|
var name = itemRow.Name.ToDalamudString();
|
||||||
// hq symbol
|
// hq symbol
|
||||||
if (hq)
|
if (hq)
|
||||||
name.Payloads.Add(new TextPayload(" "));
|
name.Payloads.Add(new TextPayload(" "));
|
||||||
@@ -471,7 +461,7 @@ public sealed class PayloadHandler {
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
var realItemId = payload.RawItemId;
|
var realItemId = payload.RawItemId;
|
||||||
if (item.EquipSlotCategory.RowId != 0)
|
if (itemRow.EquipSlotCategory.RowId != 0)
|
||||||
{
|
{
|
||||||
if (ImGui.Selectable(Language.Context_TryOn))
|
if (ImGui.Selectable(Language.Context_TryOn))
|
||||||
GameFunctions.Context.TryOn(realItemId, 0);
|
GameFunctions.Context.TryOn(realItemId, 0);
|
||||||
@@ -480,7 +470,7 @@ public sealed class PayloadHandler {
|
|||||||
GameFunctions.Context.OpenItemComparison(realItemId);
|
GameFunctions.Context.OpenItemComparison(realItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.ItemSearchCategory.Value.Category == 3)
|
if (itemRow.ItemSearchCategory.Value.Category == 3)
|
||||||
if (ImGui.Selectable(Language.Context_SearchRecipes))
|
if (ImGui.Selectable(Language.Context_SearchRecipes))
|
||||||
GameFunctions.Context.SearchForRecipesUsingItem(payload.ItemId);
|
GameFunctions.Context.SearchForRecipesUsingItem(payload.ItemId);
|
||||||
|
|
||||||
@@ -580,15 +570,17 @@ public sealed class PayloadHandler {
|
|||||||
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty))
|
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty))
|
||||||
GameFunctions.Party.InviteInInstance(chunk.Message!.ContentId);
|
GameFunctions.Party.InviteInInstance(chunk.Message!.ContentId);
|
||||||
}
|
}
|
||||||
else if (!inInstance && ImGui.BeginMenu(Language.Context_InviteToParty))
|
else if (!inInstance)
|
||||||
{
|
{
|
||||||
if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld))
|
using var menu = ImGuiUtil.Menu(Language.Context_InviteToParty);
|
||||||
GameFunctions.Party.InviteSameWorld(player.PlayerName, (ushort) world.RowId, chunk.Message?.ContentId ?? 0);
|
if (menu.Success)
|
||||||
|
{
|
||||||
|
if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld))
|
||||||
|
GameFunctions.Party.InviteSameWorld(player.PlayerName, (ushort)world.RowId, chunk.Message?.ContentId ?? 0);
|
||||||
|
|
||||||
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty_DifferentWorld))
|
if (validContentId && ImGui.Selectable(Language.Context_InviteToParty_DifferentWorld))
|
||||||
GameFunctions.Party.InviteOtherWorld(chunk.Message!.ContentId, (ushort) world.RowId);
|
GameFunctions.Party.InviteOtherWorld(chunk.Message!.ContentId, (ushort)world.RowId);
|
||||||
|
}
|
||||||
ImGui.EndMenu();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,8 +618,6 @@ public sealed class PayloadHandler {
|
|||||||
if (validContentId && ImGui.Selectable(Language.Context_AdventurerPlate))
|
if (validContentId && ImGui.Selectable(Language.Context_AdventurerPlate))
|
||||||
if (!GameFunctions.GameFunctions.TryOpenAdventurerPlate(chunk.Message!.ContentId))
|
if (!GameFunctions.GameFunctions.TryOpenAdventurerPlate(chunk.Message!.ContentId))
|
||||||
WrapperUtil.AddNotification(Language.Context_AdventurerPlateError, NotificationType.Warning);
|
WrapperUtil.AddNotification(Language.Context_AdventurerPlateError, NotificationType.Warning);
|
||||||
|
|
||||||
// View Party Finder 0x2E
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPlayerCharacter? FindCharacterForPayload(PlayerPayload payload)
|
private IPlayerCharacter? FindCharacterForPayload(PlayerPayload payload)
|
||||||
|
|||||||
+4
-2
@@ -28,7 +28,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
[PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
|
[PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
|
||||||
[PluginService] internal static ICondition Condition { get; private set; } = null!;
|
[PluginService] internal static ICondition Condition { get; private set; } = null!;
|
||||||
[PluginService] internal static IDataManager DataManager { get; private set; } = null!;
|
[PluginService] internal static IDataManager DataManager { get; private set; } = null!;
|
||||||
[PluginService] internal static IFramework Framework { get; set; } = null!;
|
[PluginService] internal static IFramework Framework { get; private set; } = null!;
|
||||||
[PluginService] internal static IGameGui GameGui { get; private set; } = null!;
|
[PluginService] internal static IGameGui GameGui { get; private set; } = null!;
|
||||||
[PluginService] internal static IKeyState KeyState { get; private set; } = null!;
|
[PluginService] internal static IKeyState KeyState { get; private set; } = null!;
|
||||||
[PluginService] internal static IObjectTable ObjectTable { get; private set; } = null!;
|
[PluginService] internal static IObjectTable ObjectTable { get; private set; } = null!;
|
||||||
@@ -115,6 +115,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
WindowSystem.AddWindow(CommandHelpWindow);
|
WindowSystem.AddWindow(CommandHelpWindow);
|
||||||
WindowSystem.AddWindow(SeStringDebugger);
|
WindowSystem.AddWindow(SeStringDebugger);
|
||||||
WindowSystem.AddWindow(DebuggerWindow);
|
WindowSystem.AddWindow(DebuggerWindow);
|
||||||
|
|
||||||
FontManager.BuildFonts();
|
FontManager.BuildFonts();
|
||||||
|
|
||||||
Interface.UiBuilder.DisableCutsceneUiHide = true;
|
Interface.UiBuilder.DisableCutsceneUiHide = true;
|
||||||
@@ -122,7 +123,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
|
|
||||||
MessageManager = new MessageManager(this); // requires Ui
|
MessageManager = new MessageManager(this); // requires Ui
|
||||||
|
|
||||||
// let all the other components register, then initialise commands
|
// let all the other components register, then initialize commands
|
||||||
Commands.Initialise();
|
Commands.Initialise();
|
||||||
|
|
||||||
if (Interface.Reason is not PluginLoadReason.Boot)
|
if (Interface.Reason is not PluginLoadReason.Boot)
|
||||||
@@ -156,6 +157,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
{
|
{
|
||||||
Log.Error(ex, "Plugin load threw an error, turning off plugin");
|
Log.Error(ex, "Plugin load threw an error, turning off plugin");
|
||||||
Dispose();
|
Dispose();
|
||||||
|
|
||||||
// Re-throw the exception to fail the plugin load.
|
// Re-throw the exception to fail the plugin load.
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+39
-39
@@ -137,7 +137,7 @@
|
|||||||
<value>Mostrar descripción del ítem</value>
|
<value>Mostrar descripción del ítem</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_NativeItemTooltips_Description">
|
<data name="Options_NativeItemTooltips_Description">
|
||||||
<value>Mostrar descripción del ítem cuando el cursor pase sobre el objeto en el {0}.</value>
|
<value>Mostrar información emergente de los objetos del juego al pasar el cursor sobre ellos en {0}.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_SidebarTabView_Name">
|
<data name="Options_SidebarTabView_Name">
|
||||||
<value>Mostrar pestañas en la barra lateral</value>
|
<value>Mostrar pestañas en la barra lateral</value>
|
||||||
@@ -152,10 +152,10 @@
|
|||||||
<value>Mostrar mensajes con un estilo más moderno.</value>
|
<value>Mostrar mensajes con un estilo más moderno.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Use24HourClock_Name">
|
<data name="Options_Use24HourClock_Name">
|
||||||
<value>24-hour clock</value>
|
<value>Reloj 24 horas</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Use24HourClock_Description">
|
<data name="Options_Use24HourClock_Description">
|
||||||
<value>Display timestamps as their 24-hour clock version.</value>
|
<value>Mostrar las marcas de tiempo en formato de reloj de 24 horas.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_MoreCompactPretty_Name">
|
<data name="Options_MoreCompactPretty_Name">
|
||||||
<value>Diseño más moderno y compacto</value>
|
<value>Diseño más moderno y compacto</value>
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
<value>Modo no leído</value>
|
<value>Modo no leído</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Tabs_InactivityBehaviour">
|
<data name="Options_Tabs_InactivityBehaviour">
|
||||||
<value>Unhide the chat window on activity</value>
|
<value>Mostrar la ventana de chat en la actividad</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Tabs_NoInputChannel">
|
<data name="Options_Tabs_NoInputChannel">
|
||||||
<value><Ninguno></value>
|
<value><Ninguno></value>
|
||||||
@@ -347,10 +347,10 @@
|
|||||||
<value>La fuente {0} se utilizará para mostrar el texto japonés.</value>
|
<value>La fuente {0} se utilizará para mostrar el texto japonés.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_ItalicFont_Name">
|
<data name="Options_ItalicFont_Name">
|
||||||
<value>Italic font</value>
|
<value>Fuente en cursiva</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Italic_Description">
|
<data name="Options_Italic_Description">
|
||||||
<value>If enabled, uses the italic font in {0}, else it will use the ingame italic font.</value>
|
<value>Si está activado, utiliza la fuente cursiva en {0}, de lo contrario usará la fuente cursiva del juego.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Tabs_ChannelTypes_Special">
|
<data name="Options_Tabs_ChannelTypes_Special">
|
||||||
<value>Especiales</value>
|
<value>Especiales</value>
|
||||||
@@ -443,7 +443,7 @@
|
|||||||
<value>Canales de chat considerados para la actividad</value>
|
<value>Canales de chat considerados para la actividad</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_InactivityHideChannels_Description">
|
<data name="Options_InactivityHideChannels_Description">
|
||||||
<value>Which chat channels should be considered for activity. Other channels will not restore the chat regardless of which tab they occur in.</value>
|
<value>Qué canales de chat deben ser considerados para la actividad. Otros canales no restaurarán el chat sin importar en qué pestaña se encuentren.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_InactivityHideChannels_All_Label">
|
<data name="Options_InactivityHideChannels_All_Label">
|
||||||
<value>Seleccionar Todo</value>
|
<value>Seleccionar Todo</value>
|
||||||
@@ -464,7 +464,7 @@
|
|||||||
<value>Otros</value>
|
<value>Otros</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Tab">
|
<data name="Options_Webinterface_Tab">
|
||||||
<value>Webinterface</value>
|
<value>Interfaz Web</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LanguageOverride_None">
|
<data name="LanguageOverride_None">
|
||||||
<value>Usar el idioma por defecto de Dalamud</value>
|
<value>Usar el idioma por defecto de Dalamud</value>
|
||||||
@@ -551,16 +551,16 @@
|
|||||||
<value>Si esto está habilitado, la lista del Traductor Automático se ordenará alfabéticamente.</value>
|
<value>Si esto está habilitado, la lista del Traductor Automático se ordenará alfabéticamente.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceEnable_Name">
|
<data name="Options_WebinterfaceEnable_Name">
|
||||||
<value>Enabled</value>
|
<value>Habilitado</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceEnable_Description">
|
<data name="Options_WebinterfaceEnable_Description">
|
||||||
<value>Enables the webinterface that can be accessed with a browser.</value>
|
<value>Habilita la interfaz web a la que se puede acceder con un navegador.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceAutoStart_Name">
|
<data name="Options_WebinterfaceAutoStart_Name">
|
||||||
<value>Start automatically</value>
|
<value>Iniciar automáticamente</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceAutoStart_Description">
|
<data name="Options_WebinterfaceAutoStart_Description">
|
||||||
<value>Webinterface will start alongside the plugin automatically</value>
|
<value>La interfaz web comenzará junto al plugin automáticamente</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_OverrideStyle_Name">
|
<data name="Options_OverrideStyle_Name">
|
||||||
<value>Sobrescribir estilo</value>
|
<value>Sobrescribir estilo</value>
|
||||||
@@ -569,22 +569,22 @@
|
|||||||
<value>Estilos</value>
|
<value>Estilos</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_ChatTabForwardKeybind_Name">
|
<data name="Options_ChatTabForwardKeybind_Name">
|
||||||
<value>Cycle chat tab forwards keybind</value>
|
<value>Ciclo de la pestaña de chat hacia adelante</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_ChatTabBackwardKeybind_Name">
|
<data name="Options_ChatTabBackwardKeybind_Name">
|
||||||
<value>Cycle chat tab backwards keybind</value>
|
<value>Ciclo de la pestaña de chat hacia atrás</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_CurrentPassword">
|
<data name="Webinterface_CurrentPassword">
|
||||||
<value>Authcode:</value>
|
<value>Código de autor:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_PasswordReset_Tooltip">
|
<data name="Webinterface_PasswordReset_Tooltip">
|
||||||
<value>Reset your password and invalidate all session tokens.</value>
|
<value>Restablecer su contraseña e invalidar todos los tokens de sesión.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Controls">
|
<data name="Webinterface_Controls">
|
||||||
<value>Control Panel:</value>
|
<value>Panel de control:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Controls_Active">
|
<data name="Webinterface_Controls_Active">
|
||||||
<value>Active:</value>
|
<value>Activo:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Controls_Url">
|
<data name="Webinterface_Controls_Url">
|
||||||
<value>URL:</value>
|
<value>URL:</value>
|
||||||
@@ -995,7 +995,7 @@
|
|||||||
<value>Mensaje copiado al portapapeles</value>
|
<value>Mensaje copiado al portapapeles</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PartyInvite_NoId">
|
<data name="PartyInvite_NoId">
|
||||||
<value>Unable to find ID for this message, please try another one.</value>
|
<value>No se puede encontrar el ID de este mensaje, por favor prueba con otro.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Context_CopyLink" xml:space="preserve">
|
<data name="Context_CopyLink" xml:space="preserve">
|
||||||
<value>Copiar enlace al portapapeles</value>
|
<value>Copiar enlace al portapapeles</value>
|
||||||
@@ -1088,10 +1088,10 @@
|
|||||||
<value>Limita la cantidad de líneas de registro que se pueden mostrar en la ventana de chat. Esto puede mejorar ligeramente el rendimiento.</value>
|
<value>Limita la cantidad de líneas de registro que se pueden mostrar en la ventana de chat. Esto puede mejorar ligeramente el rendimiento.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
||||||
<value>Log line limit for the webinterface</value>
|
<value>Límite de líneas de registro para la interfaz web</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
||||||
<value>Limits the amount of log lines to show in the webinterface. This will improve loading performance.</value>
|
<value>Limita la cantidad de líneas de registro a mostrar en la interfaz web. Esto mejorará el rendimiento de la carga.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoadMessages_Error" xml:space="preserve">
|
<data name="LoadMessages_Error" xml:space="preserve">
|
||||||
<value>Ha ocurrido un error al cargar el historial del chat. Por favor comprueba los registros del plugin para más informacion para reportar este problema.</value>
|
<value>Ha ocurrido un error al cargar el historial del chat. Por favor comprueba los registros del plugin para más informacion para reportar este problema.</value>
|
||||||
@@ -1319,57 +1319,57 @@
|
|||||||
<value>Se produjo un error al enviar este mensaje privado</value>
|
<value>Se produjo un error al enviar este mensaje privado</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Stop_Success" xml:space="preserve">
|
<data name="Webinterface_Stop_Success" xml:space="preserve">
|
||||||
<value>Webinterface was stopped.</value>
|
<value>Interfaz web detenida.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Stop_Failed" xml:space="preserve">
|
<data name="Webinterface_Stop_Failed" xml:space="preserve">
|
||||||
<value>Webinterface failed to stop. Check /xllog for more information.</value>
|
<value>La interfaz web no se ha detenido. Revisa /xllog para más información.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Button_Stop" xml:space="preserve">
|
<data name="Webinterface_Button_Stop" xml:space="preserve">
|
||||||
<value>Stop</value>
|
<value>Detener</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Button_Start" xml:space="preserve">
|
<data name="Webinterface_Button_Start" xml:space="preserve">
|
||||||
<value>Start</value>
|
<value>Iniciar</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Start_Success" xml:space="preserve">
|
<data name="Webinterface_Start_Success" xml:space="preserve">
|
||||||
<value>Webinterface was started.</value>
|
<value>Interfaz web iniciada.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Start_Failed" xml:space="preserve">
|
<data name="Webinterface_Start_Failed" xml:space="preserve">
|
||||||
<value>Webinterface failed to start. Check /xllog for more information.</value>
|
<value>La interfaz web no pudo iniciarse. Revisa /xllog para más información.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Option_Port_Name" xml:space="preserve">
|
<data name="Webinterface_Option_Port_Name" xml:space="preserve">
|
||||||
<value>Port</value>
|
<value>Puerto</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_Option_Port_Description" xml:space="preserve">
|
<data name="Webinterface_Option_Port_Description" xml:space="preserve">
|
||||||
<value>The port this webinterface will be running on.</value>
|
<value>Puerto en el que se ejecutará esta interfaz web.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Warning_Header" xml:space="preserve">
|
<data name="Options_Webinterface_Warning_Header" xml:space="preserve">
|
||||||
<value>After checking 'Enabled' and clicking 'Start' this will load up Chat2's built-in web interface, which will allow devices on your network to access in-game chat. This feature may be used to allow a phone or another computer to see Chat2 activity, switch channels, and send messages as though you were typing in FFXIV itself.</value>
|
<value>Después de marcar 'Activado' y hacer clic en 'Iniciar', se cargará la interfaz web integrada de Chat2, que permitirá a los dispositivos de tu red acceder al chat en el juego. Esta función se puede utilizar para permitir que un teléfono u otro equipo vea la actividad de Chat2, cambie de canal, y envíe mensajes como si estuvieras escribiendo en FFXIV.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Warning_Reason" xml:space="preserve">
|
<data name="Options_Webinterface_Warning_Reason" xml:space="preserve">
|
||||||
<value>For reasons of account security, this feature is not intended for use outside of your local network, you have been warned!</value>
|
<value>Por razones de seguridad de la cuenta, esta característica no está pensada para su uso fuera de su red local, ¡usted ha sido advertido!</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Warning_DoNot" xml:space="preserve">
|
<data name="Options_Webinterface_Warning_DoNot" xml:space="preserve">
|
||||||
<value>Do Not:</value>
|
<value>No:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_DoNot_Port" xml:space="preserve">
|
<data name="Options_Webinterface_DoNot_Port" xml:space="preserve">
|
||||||
<value>- Forward the port used (9000)</value>
|
<value>Redirijas el puerto usado (9000)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_DoNot_Share" xml:space="preserve">
|
<data name="Options_Webinterface_DoNot_Share" xml:space="preserve">
|
||||||
<value>- Share your authentication code with anyone else</value>
|
<value>Compartas tu código con nadie más</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_DoNot_Multibox" xml:space="preserve">
|
<data name="Options_Webinterface_DoNot_Multibox" xml:space="preserve">
|
||||||
<value>- Expect multi-boxing to work with this (only first client works)</value>
|
<value>Esperes que el multi-Boeing funcione con esto (solo el primer cliente funciona).</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Warning_Support" xml:space="preserve">
|
<data name="Options_Webinterface_Warning_Support" xml:space="preserve">
|
||||||
<value>No support will be provided if any of the 'Do Not' clauses aren't respected and adhered to appropriately.</value>
|
<value>No se proporcionará ningún soporte a las cláusulas de "NO" que no sean respetadas y adheridas apropiadamente.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Hostname_Fail" xml:space="preserve">
|
<data name="Options_Webinterface_Hostname_Fail" xml:space="preserve">
|
||||||
<value>Unable to resolve hostname.</value>
|
<value>Incapaz de resolver nombre del host.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_Webinterface_Note" xml:space="preserve">
|
<data name="Options_Webinterface_Note" xml:space="preserve">
|
||||||
<value>Note: This will require at least a semi-modern browser in order to function correctly.</value>
|
<value>Nota: Esto requerirá al menos un navegador semi moderno para funcionar correctamente</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Webinterface_UsageNotice" xml:space="preserve">
|
<data name="Webinterface_UsageNotice" xml:space="preserve">
|
||||||
<value>Usage Notice</value>
|
<value>Aviso de Uso</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1088,10 +1088,10 @@
|
|||||||
<value>Limite le nombre de lignes à afficher dans la fenêtre de chat. Cela peut légèrement améliorer les performances.</value>
|
<value>Limite le nombre de lignes à afficher dans la fenêtre de chat. Cela peut légèrement améliorer les performances.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
||||||
<value>Log line limit for the webinterface</value>
|
<value>Nombre de lignes maximum de l'interface web</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
||||||
<value>Limits the amount of log lines to show in the webinterface. This will improve loading performance.</value>
|
<value>Limite le nombre de lignes à afficher dans l'interface web. Cela améliore la performance des chargements.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoadMessages_Error" xml:space="preserve">
|
<data name="LoadMessages_Error" xml:space="preserve">
|
||||||
<value>Une erreur s'est produite lors du chargement de l'historique de la conversation. Veuillez consulter les logs du plugin pour plus d'informations pour signaler ce problème.</value>
|
<value>Une erreur s'est produite lors du chargement de l'historique de la conversation. Veuillez consulter les logs du plugin pour plus d'informations pour signaler ce problème.</value>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1088,10 +1088,10 @@
|
|||||||
<value>Limiteer het maximum aantal regels die worden getoont in het chatvester.</value>
|
<value>Limiteer het maximum aantal regels die worden getoont in het chatvester.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
||||||
<value>Log line limit for the webinterface</value>
|
<value>Regel limiet voor de webinterface</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
||||||
<value>Limits the amount of log lines to show in the webinterface. This will improve loading performance.</value>
|
<value>Beperkt het aantal regels om weer te geven in de webinterface. Dit zal de laadprestaties verbeteren.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoadMessages_Error" xml:space="preserve">
|
<data name="LoadMessages_Error" xml:space="preserve">
|
||||||
<value>Er is een fout opgetreden tijdens het laden van de chatgeschiedenis. Bekijk de plugin logs voor meer informatie om dit probleem te rapporteren.</value>
|
<value>Er is een fout opgetreden tijdens het laden van de chatgeschiedenis. Bekijk de plugin logs voor meer informatie om dit probleem te rapporteren.</value>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1088,10 +1088,10 @@
|
|||||||
<value>限制在聊天窗口中显示的日志行数。这可能会稍微提高性能。</value>
|
<value>限制在聊天窗口中显示的日志行数。这可能会稍微提高性能。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Name" xml:space="preserve">
|
||||||
<value>Log line limit for the webinterface</value>
|
<value>网页界面日志行数限制</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
<data name="Options_WebinterfaceMaxLinesToSend_Description" xml:space="preserve">
|
||||||
<value>Limits the amount of log lines to show in the webinterface. This will improve loading performance.</value>
|
<value>限制在网页界面中显示的日志行数。可提高加载性能。</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LoadMessages_Error" xml:space="preserve">
|
<data name="LoadMessages_Error" xml:space="preserve">
|
||||||
<value>加载聊天记录时发生错误。请查看插件日志以获取更多信息以报告此问题。</value>
|
<value>加载聊天记录时发生错误。请查看插件日志以获取更多信息以报告此问题。</value>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ using Lumina.Text.ReadOnly;
|
|||||||
using Pidgin;
|
using Pidgin;
|
||||||
using static Pidgin.Parser;
|
using static Pidgin.Parser;
|
||||||
using static Pidgin.Parser<char>;
|
using static Pidgin.Parser<char>;
|
||||||
using TextPayload = Lumina.Text.Payloads.TextPayload;
|
|
||||||
|
|
||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
@@ -27,71 +26,28 @@ internal static class AutoTranslate
|
|||||||
.AtLeastOnceUntil(Lookahead(Char('[').IgnoreResult().Or(End)))
|
.AtLeastOnceUntil(Lookahead(Char('[').IgnoreResult().Or(End)))
|
||||||
.Select(string.Concat)
|
.Select(string.Concat)
|
||||||
.Labelled("sheetName");
|
.Labelled("sheetName");
|
||||||
var numPair = Map(
|
var numPair = Map(ISelectorPart (first, second) =>
|
||||||
(first, second) => (ISelectorPart) new IndexRange(
|
new IndexRange(uint.Parse(string.Concat(first)), uint.Parse(string.Concat(second))),
|
||||||
uint.Parse(string.Concat(first)),
|
|
||||||
uint.Parse(string.Concat(second))
|
|
||||||
),
|
|
||||||
Digit.AtLeastOnce().Before(Char('-')),
|
Digit.AtLeastOnce().Before(Char('-')),
|
||||||
Digit.AtLeastOnce()
|
Digit.AtLeastOnce())
|
||||||
)
|
|
||||||
.Labelled("numPair");
|
.Labelled("numPair");
|
||||||
var singleRow = Digit
|
var singleRow = Digit
|
||||||
.AtLeastOnce()
|
.AtLeastOnce()
|
||||||
.Select(string.Concat)
|
.Select(string.Concat)
|
||||||
.Select(num => (ISelectorPart) new SingleRow(uint.Parse(num)));
|
.Select(ISelectorPart (num) => new SingleRow(uint.Parse(num)));
|
||||||
var column = String("col-")
|
var column = String("col-")
|
||||||
.Then(Digit.AtLeastOnce())
|
.Then(Digit.AtLeastOnce())
|
||||||
.Select(string.Concat)
|
.Select(string.Concat)
|
||||||
.Select(num => (ISelectorPart) new ColumnSpecifier(uint.Parse(num)));
|
.Select(ISelectorPart (num) => new ColumnSpecifier(uint.Parse(num)));
|
||||||
var noun = String("noun")
|
var noun = String("noun")
|
||||||
.Select(_ => (ISelectorPart) new NounMarker());
|
.Select(ISelectorPart (_) => new NounMarker());
|
||||||
var selectorItems = OneOf(
|
var selectorItems = OneOf(Try(numPair), singleRow, column, noun)
|
||||||
Try(numPair),
|
|
||||||
singleRow,
|
|
||||||
column,
|
|
||||||
noun
|
|
||||||
)
|
|
||||||
.Separated(Char(','))
|
.Separated(Char(','))
|
||||||
.Labelled("selectorItems");
|
.Labelled("selectorItems");
|
||||||
var selector = selectorItems
|
var selector = selectorItems
|
||||||
.Between(Char('['), Char(']'))
|
.Between(Char('['), Char(']'))
|
||||||
.Labelled("selector");
|
.Labelled("selector");
|
||||||
return Map(
|
return Map((name, sel) => (name, sel), sheetName, selector.Optional());
|
||||||
(name, sel) => (name, sel),
|
|
||||||
sheetName,
|
|
||||||
selector.Optional()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string TextValue(this Lumina.Text.SeString str)
|
|
||||||
{
|
|
||||||
var payloads = str.Payloads
|
|
||||||
.Select(p => {
|
|
||||||
if (p is TextPayload text) {
|
|
||||||
return p.Data[0] == 0x03
|
|
||||||
? text.RawString[1..]
|
|
||||||
: text.RawString;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.Data.Length <= 1) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.Data[1] == 0x1F) {
|
|
||||||
return "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p.Data.Length > 2 && p.Data[1] == 0x20) {
|
|
||||||
var value = p.Data.Length > 4
|
|
||||||
? p.Data[3] - 1
|
|
||||||
: p.Data[2];
|
|
||||||
return ((char) (48 + value)).ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
});
|
|
||||||
return string.Join("", payloads);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -131,7 +87,7 @@ internal static class AutoTranslate
|
|||||||
var sheet = Plugin.DataManager.Excel.GetSheet<WorkingRawRow>(name: sheetName);
|
var sheet = Plugin.DataManager.Excel.GetSheet<WorkingRawRow>(name: sheetName);
|
||||||
|
|
||||||
var columns = new List<int>();
|
var columns = new List<int>();
|
||||||
var rows = new List<Range>();
|
var rows = new List<Range>();
|
||||||
if (selector.HasValue)
|
if (selector.HasValue)
|
||||||
{
|
{
|
||||||
columns.Clear();
|
columns.Clear();
|
||||||
@@ -179,21 +135,17 @@ internal static class AutoTranslate
|
|||||||
// See above.
|
// See above.
|
||||||
for (var i = range.Start.Value; i < range.End.Value; i++)
|
for (var i = range.Start.Value; i < range.End.Value; i++)
|
||||||
{
|
{
|
||||||
if (!sheet.TryGetRow((uint)i, out var rowParser)) continue;
|
if (!sheet.TryGetRow((uint)i, out var rowParser))
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach (var col in columns)
|
foreach (var col in columns)
|
||||||
{
|
{
|
||||||
var rawName = rowParser.RawRow.ReadStringColumn(col)!;
|
var rawName = rowParser.RawRow.ReadStringColumn(col);
|
||||||
var name = rawName.ToDalamudString();
|
var name = rawName.ToDalamudString();
|
||||||
var text = name.TextValue;
|
var text = name.TextValue;
|
||||||
if (text.Length > 0)
|
if (text.Length > 0)
|
||||||
{
|
{
|
||||||
list.Add(new AutoTranslateEntry(
|
list.Add(new AutoTranslateEntry(row.Group, (uint)i, text, name));
|
||||||
row.Group,
|
|
||||||
(uint)i,
|
|
||||||
text,
|
|
||||||
name
|
|
||||||
));
|
|
||||||
|
|
||||||
if (shouldAdd)
|
if (shouldAdd)
|
||||||
ValidEntries.Add((row.Group, (uint)i));
|
ValidEntries.Add((row.Group, (uint)i));
|
||||||
@@ -205,12 +157,7 @@ internal static class AutoTranslate
|
|||||||
else if (lookup is not "@")
|
else if (lookup is not "@")
|
||||||
{
|
{
|
||||||
var text = row.Text.ToDalamudString();
|
var text = row.Text.ToDalamudString();
|
||||||
list.Add(new AutoTranslateEntry(
|
list.Add(new AutoTranslateEntry(row.Group, row.RowId, text.TextValue, text));
|
||||||
row.Group,
|
|
||||||
row.RowId,
|
|
||||||
text.TextValue,
|
|
||||||
text
|
|
||||||
));
|
|
||||||
|
|
||||||
if (shouldAdd)
|
if (shouldAdd)
|
||||||
ValidEntries.Add((row.Group, row.RowId));
|
ValidEntries.Add((row.Group, row.RowId));
|
||||||
@@ -271,33 +218,30 @@ internal static class AutoTranslate
|
|||||||
var start = -1;
|
var start = -1;
|
||||||
for (var i = 0; i < bytes.Length; i++)
|
for (var i = 0; i < bytes.Length; i++)
|
||||||
{
|
{
|
||||||
if (start != -1) {
|
if (start != -1)
|
||||||
if (bytes[i] == '>')
|
{
|
||||||
{
|
if (bytes[i] != '>')
|
||||||
var tag = Encoding.UTF8.GetString(bytes[start..(i + 1)]);
|
|
||||||
var parts = tag[4..^1].Split(',', 2);
|
|
||||||
if (parts.Length == 2 && uint.TryParse(parts[0], out var group) && uint.TryParse(parts[1], out var key))
|
|
||||||
{
|
|
||||||
var payload = ValidEntries.Contains((group, key))
|
|
||||||
? new AutoTranslatePayload(group, key).Encode()
|
|
||||||
: [];
|
|
||||||
|
|
||||||
var oldBytes = bytes.ToArray();
|
|
||||||
var lengthDiff = payload.Length - (i - start);
|
|
||||||
bytes = new byte[oldBytes.Length + lengthDiff];
|
|
||||||
Array.Copy(oldBytes, bytes, start);
|
|
||||||
Array.Copy(payload, 0, bytes, start, payload.Length);
|
|
||||||
Array.Copy(oldBytes, i + 1, bytes, start + payload.Length, oldBytes.Length - (i + 1));
|
|
||||||
|
|
||||||
i += lengthDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
var tag = Encoding.UTF8.GetString(bytes[start..(i + 1)]);
|
||||||
|
var parts = tag[4..^1].Split(',', 2);
|
||||||
|
if (parts.Length == 2 && uint.TryParse(parts[0], out var group) && uint.TryParse(parts[1], out var key))
|
||||||
|
{
|
||||||
|
var payload = ValidEntries.Contains((group, key))
|
||||||
|
? new AutoTranslatePayload(group, key).Encode()
|
||||||
|
: [];
|
||||||
|
|
||||||
|
var oldBytes = bytes.ToArray();
|
||||||
|
var lengthDiff = payload.Length - (i - start);
|
||||||
|
bytes = new byte[oldBytes.Length + lengthDiff];
|
||||||
|
Array.Copy(oldBytes, bytes, start);
|
||||||
|
Array.Copy(payload, 0, bytes, start, payload.Length);
|
||||||
|
Array.Copy(oldBytes, i + 1, bytes, start + payload.Length, oldBytes.Length - (i + 1));
|
||||||
|
|
||||||
|
i += lengthDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i + search.Length < bytes.Length && memcmp(bytes[i..], search, (nuint) search.Length) == 0)
|
if (i + search.Length < bytes.Length && memcmp(bytes[i..], search, (nuint) search.Length) == 0)
|
||||||
@@ -313,7 +257,7 @@ public readonly struct WorkingRawRow(RawRow row) : IExcelRow<WorkingRawRow>
|
|||||||
public RawRow RawRow => row;
|
public RawRow RawRow => row;
|
||||||
|
|
||||||
static WorkingRawRow IExcelRow<WorkingRawRow>.Create(ExcelPage page, uint offset, uint row) =>
|
static WorkingRawRow IExcelRow<WorkingRawRow>.Create(ExcelPage page, uint offset, uint row) =>
|
||||||
new(new(page, offset, row));
|
new(new RawRow(page, offset, row));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal interface ISelectorPart { }
|
internal interface ISelectorPart { }
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ using System.Numerics;
|
|||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
internal static class ColourUtil {
|
internal static class ColourUtil {
|
||||||
internal static (byte r, byte g, byte b, byte a) RgbaToComponents(uint rgba) {
|
internal static (byte r, byte g, byte b, byte a) RgbaToComponents(uint rgba)
|
||||||
|
{
|
||||||
var r = (byte) ((rgba & 0xFF000000) >> 24);
|
var r = (byte) ((rgba & 0xFF000000) >> 24);
|
||||||
var g = (byte) ((rgba & 0xFF0000) >> 16);
|
var g = (byte) ((rgba & 0xFF0000) >> 16);
|
||||||
var b = (byte) ((rgba & 0xFF00) >> 8);
|
var b = (byte) ((rgba & 0xFF00) >> 8);
|
||||||
@@ -14,12 +15,14 @@ internal static class ColourUtil {
|
|||||||
|
|
||||||
internal static uint RgbaToAbgr(uint rgba) => BinaryPrimitives.ReverseEndianness(rgba);
|
internal static uint RgbaToAbgr(uint rgba) => BinaryPrimitives.ReverseEndianness(rgba);
|
||||||
|
|
||||||
internal static Vector3 RgbaToVector3(uint rgba) {
|
internal static Vector3 RgbaToVector3(uint rgba)
|
||||||
|
{
|
||||||
var (r, g, b, _) = RgbaToComponents(rgba);
|
var (r, g, b, _) = RgbaToComponents(rgba);
|
||||||
return new Vector3((float) r / 255, (float) g / 255, (float) b / 255);
|
return new Vector3((float) r / 255, (float) g / 255, (float) b / 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static uint Vector3ToRgba(Vector3 col) {
|
internal static uint Vector3ToRgba(Vector3 col)
|
||||||
|
{
|
||||||
return ComponentsToRgba(
|
return ComponentsToRgba(
|
||||||
(byte) Math.Round(col.X * 255),
|
(byte) Math.Round(col.X * 255),
|
||||||
(byte) Math.Round(col.Y * 255),
|
(byte) Math.Round(col.Y * 255),
|
||||||
@@ -27,7 +30,8 @@ internal static class ColourUtil {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static uint Vector4ToAbgr(Vector4 col) {
|
internal static uint Vector4ToAbgr(Vector4 col)
|
||||||
|
{
|
||||||
return RgbaToAbgr(ComponentsToRgba(
|
return RgbaToAbgr(ComponentsToRgba(
|
||||||
(byte) Math.Round(col.X * 255),
|
(byte) Math.Round(col.X * 255),
|
||||||
(byte) Math.Round(col.Y * 255),
|
(byte) Math.Round(col.Y * 255),
|
||||||
|
|||||||
@@ -24,17 +24,14 @@ public class ColorPayload
|
|||||||
payload.Enabled = false;
|
payload.Enabled = false;
|
||||||
return payload;
|
return payload;
|
||||||
case 0xE9:
|
case 0xE9:
|
||||||
{
|
|
||||||
var param = stream.ReadByte();
|
var param = stream.ReadByte();
|
||||||
var value = (uint) GlobalParametersCache.GetValue(param - 2);
|
var globalValue = (uint) GlobalParametersCache.GetValue(param - 2);
|
||||||
payload.Enabled = true;
|
payload.Enabled = true;
|
||||||
payload.UnshiftedColor = value;
|
payload.UnshiftedColor = globalValue;
|
||||||
payload.Color = ColourUtil.ArgbToRgba(value);
|
payload.Color = ColourUtil.ArgbToRgba(globalValue);
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
}
|
|
||||||
case >= 0xF0 and <= 0xFE:
|
case >= 0xF0 and <= 0xFE:
|
||||||
{
|
|
||||||
// From: https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Text/Expressions/IntegerExpression.cs#L119-L128
|
// From: https://github.com/NotAdam/Lumina/blob/master/src/Lumina/Text/Expressions/IntegerExpression.cs#L119-L128
|
||||||
uint ShiftAndThrowIfZero(int v, int shift)
|
uint ShiftAndThrowIfZero(int v, int shift)
|
||||||
{
|
{
|
||||||
@@ -47,21 +44,20 @@ public class ColorPayload
|
|||||||
}
|
}
|
||||||
|
|
||||||
typeByte += 1;
|
typeByte += 1;
|
||||||
var value = 0u;
|
var argbValue = 0u;
|
||||||
if ((typeByte & 8) != 0)
|
if ((typeByte & 8) != 0)
|
||||||
value |= ShiftAndThrowIfZero(stream.ReadByte(), 24);
|
argbValue |= ShiftAndThrowIfZero(stream.ReadByte(), 24);
|
||||||
else
|
else
|
||||||
value |= 0xff000000u;
|
argbValue |= 0xff000000u;
|
||||||
|
|
||||||
if( (typeByte & 4) != 0 ) value |= ShiftAndThrowIfZero( stream.ReadByte(), 16 );
|
if( (typeByte & 4) != 0 ) argbValue |= ShiftAndThrowIfZero( stream.ReadByte(), 16 );
|
||||||
if( (typeByte & 2) != 0 ) value |= ShiftAndThrowIfZero( stream.ReadByte(), 8 );
|
if( (typeByte & 2) != 0 ) argbValue |= ShiftAndThrowIfZero( stream.ReadByte(), 8 );
|
||||||
if( (typeByte & 1) != 0 ) value |= ShiftAndThrowIfZero( stream.ReadByte(), 0 );
|
if( (typeByte & 1) != 0 ) argbValue |= ShiftAndThrowIfZero( stream.ReadByte(), 0 );
|
||||||
|
|
||||||
payload.Enabled = true;
|
payload.Enabled = true;
|
||||||
payload.Color = ColourUtil.ArgbToRgba(value);
|
payload.Color = ColourUtil.ArgbToRgba(argbValue);
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public static class GlobalParametersCache
|
|||||||
{
|
{
|
||||||
if (index < 0 || index >= Cache.Length)
|
if (index < 0 || index >= Cache.Length)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Cache[index];
|
return Cache[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,9 +32,9 @@ public static class GlobalParametersCache
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ref var gp = ref rtm->TextModule.MacroDecoder.GlobalParameters;
|
ref var gp = ref rtm->TextModule.MacroDecoder.GlobalParameters;
|
||||||
|
|
||||||
if (Cache.Length != (int)gp.MySize)
|
if (Cache.Length != (int)gp.MySize)
|
||||||
Cache = new int[gp.MySize];
|
Cache = new int[gp.MySize];
|
||||||
|
|
||||||
for (ulong i = 0; i < gp.MySize; i++)
|
for (ulong i = 0; i < gp.MySize; i++)
|
||||||
{
|
{
|
||||||
var p = gp[(long)i];
|
var p = gp[(long)i];
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ public readonly unsafe ref struct GfdFileView
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
internal static class IconUtil {
|
internal static class IconUtil
|
||||||
|
{
|
||||||
private static byte[]? GfdFile;
|
private static byte[]? GfdFile;
|
||||||
public static unsafe GfdFileView GfdFileView
|
public static unsafe GfdFileView GfdFileView
|
||||||
{
|
{
|
||||||
|
|||||||
+38
-29
@@ -186,15 +186,16 @@ internal static class ImGuiUtil
|
|||||||
Plugin.FontManager.FontAwesome.Push();
|
Plugin.FontManager.FontAwesome.Push();
|
||||||
var size = new Vector2(0, 0);
|
var size = new Vector2(0, 0);
|
||||||
if (width > 0)
|
if (width > 0)
|
||||||
{
|
size.X = width - 2 * ImGui.GetStyle().CellPadding.X;
|
||||||
var style = ImGui.GetStyle();
|
|
||||||
size.X = width - 2 * style.CellPadding.X;
|
|
||||||
}
|
|
||||||
var ret = ImGui.Button(label, size);
|
var ret = ImGui.Button(label, size);
|
||||||
Plugin.FontManager.FontAwesome.Pop();
|
Plugin.FontManager.FontAwesome.Pop();
|
||||||
|
|
||||||
if (tooltip != null && ImGui.IsItemHovered())
|
if (tooltip != null && ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip(tooltip);
|
{
|
||||||
|
using var startedTooltip = ImRaii.Tooltip();
|
||||||
|
ImGuiHelpers.SafeTextWrapped(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -224,11 +225,8 @@ internal static class ImGuiUtil
|
|||||||
var style = StyleModel.GetConfiguredStyle() ?? StyleModel.GetFromCurrent();
|
var style = StyleModel.GetConfiguredStyle() ?? StyleModel.GetFromCurrent();
|
||||||
var dalamudOrange = style.BuiltInColors?.DalamudOrange;
|
var dalamudOrange = style.BuiltInColors?.DalamudOrange;
|
||||||
|
|
||||||
var push = dalamudOrange != null;
|
|
||||||
var color = dalamudOrange ?? Vector4.Zero;
|
|
||||||
|
|
||||||
using (TextWrapPos(wrap))
|
using (TextWrapPos(wrap))
|
||||||
using (ImRaii.PushColor(ImGuiCol.Text, color, push))
|
using (ImRaii.PushColor(ImGuiCol.Text, dalamudOrange ?? Vector4.Zero, dalamudOrange != null))
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(text);
|
ImGui.TextUnformatted(text);
|
||||||
}
|
}
|
||||||
@@ -305,18 +303,17 @@ internal static class ImGuiUtil
|
|||||||
if (combo)
|
if (combo)
|
||||||
{
|
{
|
||||||
foreach (var size in FontManager.AxisFontSizeList)
|
foreach (var size in FontManager.AxisFontSizeList)
|
||||||
if (ImGui.Selectable($"{size:###.##}pt", currentSize == size))
|
if (ImGui.Selectable($"{size:###.##}pt", currentSize.Equals(size)))
|
||||||
currentSize = size;
|
currentSize = size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Button(string id, FontAwesomeIcon icon, bool disabled)
|
public static bool Button(string id, FontAwesomeIcon icon, bool disabled)
|
||||||
{
|
{
|
||||||
var clicked = false;
|
|
||||||
using (ImRaii.Disabled(disabled))
|
using (ImRaii.Disabled(disabled))
|
||||||
clicked = ImGuiComponents.IconButton(id, icon);
|
{
|
||||||
|
return ImGuiComponents.IconButton(id, icon);
|
||||||
return clicked;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool CtrlShiftButton(string label, string tooltip = "")
|
internal static bool CtrlShiftButton(string label, string tooltip = "")
|
||||||
@@ -328,7 +325,10 @@ internal static class ImGuiUtil
|
|||||||
ret = ImGui.Button(label) && ctrlShiftHeld;
|
ret = ImGui.Button(label) && ctrlShiftHeld;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
ImGui.SetTooltip(tooltip);
|
{
|
||||||
|
using var startedTooltip = ImRaii.Tooltip();
|
||||||
|
ImGuiHelpers.SafeTextWrapped(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -345,15 +345,19 @@ internal static class ImGuiUtil
|
|||||||
var ret = ImGui.Button(label) && ctrlShiftHeld;
|
var ret = ImGui.Button(label) && ctrlShiftHeld;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||||
ImGui.SetTooltip(tooltip);
|
{
|
||||||
|
using var startedTooltip = ImRaii.Tooltip();
|
||||||
|
ImGuiHelpers.SafeTextWrapped(tooltip);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool KeybindInput(string id, ref ConfigKeyBind? keybind)
|
internal static void KeybindInput(string id, ref ConfigKeyBind? keybind)
|
||||||
{
|
{
|
||||||
var idUint = ImGui.GetID(id);
|
var idUint = ImGui.GetID(id);
|
||||||
|
|
||||||
using var pushedId = ImRaii.PushId(id);
|
using var pushedId = ImRaii.PushId(id);
|
||||||
if (ImGui.GetStateStorage().GetBool(idUint))
|
if (ImGui.GetStateStorage().GetBool(idUint))
|
||||||
{
|
{
|
||||||
@@ -387,7 +391,7 @@ internal static class ImGuiUtil
|
|||||||
{
|
{
|
||||||
keybind = null;
|
keybind = null;
|
||||||
ImGui.GetStateStorage().SetBool(idUint, false);
|
ImGui.GetStateStorage().SetBool(idUint, false);
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var vk in Enum.GetValues(typeof(VirtualKey)).Cast<VirtualKey>())
|
foreach (var vk in Enum.GetValues(typeof(VirtualKey)).Cast<VirtualKey>())
|
||||||
@@ -404,7 +408,7 @@ internal static class ImGuiUtil
|
|||||||
Key = vk
|
Key = vk
|
||||||
};
|
};
|
||||||
ImGui.GetStateStorage().SetBool(idUint, false);
|
ImGui.GetStateStorage().SetBool(idUint, false);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -415,8 +419,6 @@ internal static class ImGuiUtil
|
|||||||
if (ImGui.Button(text, new Vector2(-1, 0)))
|
if (ImGui.Button(text, new Vector2(-1, 0)))
|
||||||
ImGui.GetStateStorage().SetBool(idUint, true);
|
ImGui.GetStateStorage().SetBool(idUint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawArrows(ref int selected, int min, int max, float spacing, int id = 0)
|
public static void DrawArrows(ref int selected, int min, int max, float spacing, int id = 0)
|
||||||
@@ -428,13 +430,15 @@ internal static class ImGuiUtil
|
|||||||
ImGui.SameLine(0, spacing);
|
ImGui.SameLine(0, spacing);
|
||||||
using (ImRaii.Disabled(isMin))
|
using (ImRaii.Disabled(isMin))
|
||||||
{
|
{
|
||||||
if (IconButton(FontAwesomeIcon.ArrowLeft, id.ToString())) selected--;
|
if (IconButton(FontAwesomeIcon.ArrowLeft, id.ToString()))
|
||||||
|
selected--;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine(0, spacing);
|
ImGui.SameLine(0, spacing);
|
||||||
using (ImRaii.Disabled(isMax))
|
using (ImRaii.Disabled(isMax))
|
||||||
{
|
{
|
||||||
if (IconButton(FontAwesomeIcon.ArrowRight, id+1.ToString())) selected++;
|
if (IconButton(FontAwesomeIcon.ArrowRight, id+1.ToString()))
|
||||||
|
selected++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,7 +451,8 @@ internal static class ImGuiUtil
|
|||||||
|
|
||||||
internal static bool TryToImGui(this VirtualKey key, out ImGuiKey result)
|
internal static bool TryToImGui(this VirtualKey key, out ImGuiKey result)
|
||||||
{
|
{
|
||||||
result = key switch {
|
result = key switch
|
||||||
|
{
|
||||||
VirtualKey.NO_KEY => ImGuiKey.None,
|
VirtualKey.NO_KEY => ImGuiKey.None,
|
||||||
VirtualKey.BACK => ImGuiKey.Backspace,
|
VirtualKey.BACK => ImGuiKey.Backspace,
|
||||||
VirtualKey.TAB => ImGuiKey.Tab,
|
VirtualKey.TAB => ImGuiKey.Tab,
|
||||||
@@ -561,13 +566,12 @@ internal static class ImGuiUtil
|
|||||||
return result != 0 || key == VirtualKey.NO_KEY;
|
return result != 0 || key == VirtualKey.NO_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct EndUnconditionally(Action endAction, bool success) : ImRaii.IEndObject
|
public struct EndUnconditionally(Action endAction, bool success) : ImRaii.IEndObject
|
||||||
{
|
{
|
||||||
private Action EndAction { get; } = endAction;
|
|
||||||
|
|
||||||
public bool Success { get; } = success;
|
public bool Success { get; } = success;
|
||||||
|
|
||||||
public bool Disposed { get; private set; } = false;
|
private bool Disposed { get; set; } = false;
|
||||||
|
private Action EndAction { get; } = endAction;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@@ -594,10 +598,15 @@ internal static class ImGuiUtil
|
|||||||
return new EndUnconditionally(ImGui.PopTextWrapPos, true);
|
return new EndUnconditionally(ImGui.PopTextWrapPos, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ImRaii.IEndObject Menu(string label)
|
||||||
|
{
|
||||||
|
return new EndUnconditionally(ImGui.EndMenu, ImGui.BeginMenu(label));
|
||||||
|
}
|
||||||
|
|
||||||
public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes)
|
public static void ChannelSelector(string headerText, Dictionary<ChatType, ChatSource> chatCodes)
|
||||||
{
|
{
|
||||||
using var channelNode = ImRaii.TreeNode(headerText);
|
using var channelNode = ImRaii.TreeNode(headerText);
|
||||||
if (!channelNode)
|
if (!channelNode.Success)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (header, types) in ChatTypeExt.SortOrder)
|
foreach (var (header, types) in ChatTypeExt.SortOrder)
|
||||||
|
|||||||
+16
-13
@@ -1,23 +1,26 @@
|
|||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
internal class Lender<T> {
|
internal class Lender<T>
|
||||||
private readonly Func<T> _ctor;
|
{
|
||||||
private readonly List<T> _items = new();
|
private readonly Func<T> Ctor;
|
||||||
private int _counter;
|
private readonly List<T> Items = [];
|
||||||
|
private int Counter;
|
||||||
|
|
||||||
internal Lender(Func<T> ctor) {
|
internal Lender(Func<T> ctor)
|
||||||
_ctor = ctor;
|
{
|
||||||
|
Ctor = ctor;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ResetCounter() {
|
internal void ResetCounter()
|
||||||
_counter = 0;
|
{
|
||||||
|
Counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal T Borrow() {
|
internal T Borrow()
|
||||||
if (_items.Count <= _counter) {
|
{
|
||||||
_items.Add(_ctor());
|
if (Items.Count <= Counter)
|
||||||
}
|
Items.Add(Ctor());
|
||||||
|
|
||||||
return _items[_counter++];
|
return Items[Counter++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-20
@@ -2,38 +2,46 @@ using Dalamud.Game.Text.SeStringHandling;
|
|||||||
|
|
||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
internal class PartyFinderPayload : Payload {
|
internal class PartyFinderPayload : Payload
|
||||||
|
{
|
||||||
public override PayloadType Type => (PayloadType) 0x50;
|
public override PayloadType Type => (PayloadType) 0x50;
|
||||||
|
|
||||||
internal uint Id { get; }
|
internal uint Id { get; }
|
||||||
|
|
||||||
internal PartyFinderPayload(uint id) {
|
internal PartyFinderPayload(uint id)
|
||||||
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] EncodeImpl() {
|
protected override byte[] EncodeImpl()
|
||||||
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DecodeImpl(BinaryReader reader, long endOfStream) {
|
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
|
||||||
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AchievementPayload : Payload {
|
internal class AchievementPayload : Payload
|
||||||
|
{
|
||||||
public override PayloadType Type => (PayloadType) 0x51;
|
public override PayloadType Type => (PayloadType) 0x51;
|
||||||
|
|
||||||
internal uint Id { get; }
|
internal uint Id { get; }
|
||||||
|
|
||||||
internal AchievementPayload(uint id) {
|
internal AchievementPayload(uint id)
|
||||||
|
{
|
||||||
Id = id;
|
Id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override byte[] EncodeImpl() {
|
protected override byte[] EncodeImpl()
|
||||||
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DecodeImpl(BinaryReader reader, long endOfStream) {
|
protected override void DecodeImpl(BinaryReader reader, long endOfStream)
|
||||||
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +53,8 @@ internal class UriPayload(Uri uri) : Payload
|
|||||||
|
|
||||||
public Uri Uri { get; } = uri;
|
public Uri Uri { get; } = uri;
|
||||||
|
|
||||||
|
private const string DefaultScheme = "https";
|
||||||
private static readonly string[] ExpectedSchemes = ["http", "https"];
|
private static readonly string[] ExpectedSchemes = ["http", "https"];
|
||||||
private static readonly string DefaultScheme = "https";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a URIPayload from a raw URI string. If the URI does not have a
|
/// Create a URIPayload from a raw URI string. If the URI does not have a
|
||||||
@@ -59,18 +67,12 @@ internal class UriPayload(Uri uri) : Payload
|
|||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(rawURI);
|
ArgumentNullException.ThrowIfNull(rawURI);
|
||||||
|
|
||||||
// Check for expected scheme ://, if not add https://
|
// Check for an expected scheme '://', if not add 'https://'
|
||||||
foreach (var scheme in ExpectedSchemes)
|
if (ExpectedSchemes.Any(scheme => rawURI.StartsWith($"{scheme}://")))
|
||||||
{
|
return new UriPayload(new Uri(rawURI));
|
||||||
if (rawURI.StartsWith($"{scheme}://"))
|
|
||||||
{
|
|
||||||
return new UriPayload(new Uri(rawURI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rawURI.Contains("://"))
|
if (rawURI.Contains("://"))
|
||||||
{
|
|
||||||
throw new UriFormatException($"Unsupported scheme in URL: {rawURI}");
|
throw new UriFormatException($"Unsupported scheme in URL: {rawURI}");
|
||||||
}
|
|
||||||
|
|
||||||
return new UriPayload(new Uri($"{DefaultScheme}://{rawURI}"));
|
return new UriPayload(new Uri($"{DefaultScheme}://{rawURI}"));
|
||||||
}
|
}
|
||||||
@@ -90,7 +92,7 @@ internal class EmotePayload : Payload
|
|||||||
{
|
{
|
||||||
public override PayloadType Type => (PayloadType) 0x53;
|
public override PayloadType Type => (PayloadType) 0x53;
|
||||||
|
|
||||||
public string Code;
|
public string Code = string.Empty;
|
||||||
|
|
||||||
public static EmotePayload ResolveEmote(string code)
|
public static EmotePayload ResolveEmote(string code)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
|
||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
@@ -58,7 +59,6 @@ public static class SearchSelector
|
|||||||
|
|
||||||
public static bool SelectorPopup(string id, out string selected, SelectorPopupOptions? options = null, bool close = false)
|
public static bool SelectorPopup(string id, out string selected, SelectorPopupOptions? options = null, bool close = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
options ??= new SelectorPopupOptions();
|
options ??= new SelectorPopupOptions();
|
||||||
var sheet = options.FilteredSheet;
|
var sheet = options.FilteredSheet;
|
||||||
selected = string.Empty;
|
selected = string.Empty;
|
||||||
@@ -67,12 +67,15 @@ public static class SearchSelector
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGui.SetNextWindowSize(options.Size ?? new Vector2(0, 250 * ImGuiHelpers.GlobalScale));
|
ImGui.SetNextWindowSize(options.Size ?? new Vector2(0, 250 * ImGuiHelpers.GlobalScale));
|
||||||
if (!ImGui.BeginPopupContextItem(id, options.PopupFlags))
|
using var popup = ImRaii.ContextPopupItem(id, options.PopupFlags);
|
||||||
|
if (!popup.Success)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SearchInput(id, sheet, options.SearchPredicate ?? ((row, s) => options.FormatRow(row).Contains(s, StringComparison.CurrentCultureIgnoreCase)));
|
SearchInput(id, sheet, options.SearchPredicate ?? ((row, s) => options.FormatRow(row).Contains(s, StringComparison.CurrentCultureIgnoreCase)));
|
||||||
|
|
||||||
ImGui.BeginChild("SearchList", Vector2.Zero, true);
|
using var child = ImRaii.Child("SearchList", Vector2.Zero, true);
|
||||||
|
if (!child.Success)
|
||||||
|
return false;
|
||||||
|
|
||||||
var ret = false;
|
var ret = false;
|
||||||
var drawSelectable = options.DrawSelectable ?? ((row, selected) => ImGui.Selectable(options.FormatRow(row), selected));
|
var drawSelectable = options.DrawSelectable ?? ((row, selected) => ImGui.Selectable(options.FormatRow(row), selected));
|
||||||
@@ -81,11 +84,12 @@ public static class SearchSelector
|
|||||||
foreach (var i in clipper.Rows)
|
foreach (var i in clipper.Rows)
|
||||||
{
|
{
|
||||||
var searched = FilteredSearchSheet[i];
|
var searched = FilteredSearchSheet[i];
|
||||||
ImGui.PushID(id);
|
using var pushedId = ImRaii.PushId(id);
|
||||||
if (!drawSelectable(searched, options.IsSelected(searched))) continue;
|
if (!drawSelectable(searched, options.IsSelected(searched)))
|
||||||
|
continue;
|
||||||
|
|
||||||
selected = searched;
|
selected = searched;
|
||||||
ret = true;
|
ret = true;
|
||||||
ImGui.PopID();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +97,6 @@ public static class SearchSelector
|
|||||||
if (ret && options.CloseOnSelection)
|
if (ret && options.CloseOnSelection)
|
||||||
ImGui.CloseCurrentPopup();
|
ImGui.CloseCurrentPopup();
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
ImGui.EndPopup();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ using System.Text;
|
|||||||
|
|
||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
internal static class StringUtil {
|
internal static class StringUtil
|
||||||
internal static byte[] ToTerminatedBytes(this string s) {
|
{
|
||||||
|
internal static byte[] ToTerminatedBytes(this string s)
|
||||||
|
{
|
||||||
var utf8 = Encoding.UTF8;
|
var utf8 = Encoding.UTF8;
|
||||||
var bytes = new byte[utf8.GetByteCount(s) + 1];
|
var bytes = new byte[utf8.GetByteCount(s) + 1];
|
||||||
utf8.GetBytes(s, 0, s.Length, bytes, 0);
|
utf8.GetBytes(s, 0, s.Length, bytes, 0);
|
||||||
@@ -12,7 +14,8 @@ 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];
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ using ChatTwo.Resources;
|
|||||||
|
|
||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
internal static class TabsUtil {
|
internal static class TabsUtil
|
||||||
|
{
|
||||||
internal static Dictionary<ChatType, ChatSource> AllChannels()
|
internal static Dictionary<ChatType, ChatSource> AllChannels()
|
||||||
{
|
{
|
||||||
var channels = new Dictionary<ChatType, ChatSource>();
|
var channels = new Dictionary<ChatType, ChatSource>();
|
||||||
@@ -12,9 +13,11 @@ internal static class TabsUtil {
|
|||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Tab VanillaGeneral => new() {
|
internal static Tab VanillaGeneral => new()
|
||||||
|
{
|
||||||
Name = Language.Tabs_Presets_General,
|
Name = Language.Tabs_Presets_General,
|
||||||
ChatCodes = new Dictionary<ChatType, ChatSource> {
|
ChatCodes = new Dictionary<ChatType, ChatSource>
|
||||||
|
{
|
||||||
// Special
|
// Special
|
||||||
[ChatType.Debug] = ChatSourceExt.All,
|
[ChatType.Debug] = ChatSourceExt.All,
|
||||||
[ChatType.Urgent] = ChatSourceExt.All,
|
[ChatType.Urgent] = ChatSourceExt.All,
|
||||||
@@ -75,11 +78,10 @@ internal static class TabsUtil {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static Tab VanillaEvent => new() {
|
internal static Tab VanillaEvent => new()
|
||||||
|
{
|
||||||
Name = Language.Tabs_Presets_Event,
|
Name = Language.Tabs_Presets_Event,
|
||||||
ChatCodes = new Dictionary<ChatType, ChatSource> {
|
ChatCodes = new Dictionary<ChatType, ChatSource> { [ChatType.NpcDialogue] = ChatSourceExt.All, },
|
||||||
[ChatType.NpcDialogue] = ChatSourceExt.All,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static Dictionary<ChatType, ChatSource> MostlyPlayer => new()
|
internal static Dictionary<ChatType, ChatSource> MostlyPlayer => new()
|
||||||
|
|||||||
+15
-15
@@ -36,21 +36,21 @@ public static class Tokenizer
|
|||||||
|
|
||||||
static PrecedenceBasedRegexTokenizer()
|
static PrecedenceBasedRegexTokenizer()
|
||||||
{
|
{
|
||||||
TokenDefinitions = new List<TokenDefinition>
|
TokenDefinitions =
|
||||||
{
|
[
|
||||||
new(TokenType.CloseParenthesis, "\\)", 1),
|
new TokenDefinition(TokenType.CloseParenthesis, "\\)", 1),
|
||||||
new(TokenType.Comma, ",", 1),
|
new TokenDefinition(TokenType.Comma, ",", 1),
|
||||||
new(TokenType.Dot, "\\.", 1),
|
new TokenDefinition(TokenType.Dot, "\\.", 1),
|
||||||
new(TokenType.QuestionMark, "\\?", 1),
|
new TokenDefinition(TokenType.QuestionMark, "\\?", 1),
|
||||||
new(TokenType.ExclamationMark, "!", 1),
|
new TokenDefinition(TokenType.ExclamationMark, "!", 1),
|
||||||
new(TokenType.Semicolon, ";", 1),
|
new TokenDefinition(TokenType.Semicolon, ";", 1),
|
||||||
new(TokenType.Whitespace, "\\s", 1),
|
new TokenDefinition(TokenType.Whitespace, "\\s", 1),
|
||||||
new(TokenType.Equals, "=", 1),
|
new TokenDefinition(TokenType.Equals, "=", 1),
|
||||||
new(TokenType.OpenParenthesis, "\\(", 1),
|
new TokenDefinition(TokenType.OpenParenthesis, "\\(", 1),
|
||||||
new(TokenType.UrlString, URLRegex, 1),
|
new TokenDefinition(TokenType.UrlString, URLRegex, 1),
|
||||||
new(TokenType.StringValue, "\\p{IsBasicLatin}", 2),
|
new TokenDefinition(TokenType.StringValue, "\\p{IsBasicLatin}", 2),
|
||||||
new(TokenType.Leftover, ".", 3)
|
new TokenDefinition(TokenType.Leftover, ".", 3)
|
||||||
};
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Token> Tokenize(string lqlText)
|
public static IEnumerable<Token> Tokenize(string lqlText)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace ChatTwo.Util;
|
namespace ChatTwo.Util;
|
||||||
|
|
||||||
public class WebinterfaceUtil
|
public static class WebinterfaceUtil
|
||||||
{
|
{
|
||||||
private static readonly Random Rng = new();
|
private static readonly Random Rng = new();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user