- More ImRaii

- Cleanup
- Spanish, French, Dutch, Chinese loc update
This commit is contained in:
Infi
2024-11-21 11:58:22 +01:00
parent 1a1995759a
commit 3cfe65d2d4
23 changed files with 283 additions and 332 deletions
+1 -1
View File
@@ -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
View File
@@ -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;
+1 -5
View File
@@ -103,13 +103,9 @@ 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)
{ {
+2 -5
View File
@@ -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)
{ {
+37 -47
View File
@@ -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,10 +106,11 @@ 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)
var cursor = ImGui.GetCursorPos(); return;
var cursor = ImGui.GetCursorPos();
foreach (var id in registered) foreach (var id in registered)
{ {
try try
@@ -123,17 +125,14 @@ public sealed class PayloadHandler {
if (cursor == ImGui.GetCursorPos()) if (cursor == ImGui.GetCursorPos())
{ {
ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled]); using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int)ImGuiCol.TextDisabled]);
ImGui.Text("No integrations available"); ImGui.Text("No integrations available");
ImGui.PopStyleColor();
}
ImGui.EndMenu();
} }
} }
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);
try
{
ImGui.TextUnformatted(message.Code.Type.Name()); 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,12 +245,13 @@ 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)
{
using var menu = ImGuiUtil.Menu(Language.Context_InviteToParty);
if (menu.Success)
{ {
if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld)) if (ImGui.Selectable(Language.Context_InviteToParty_SameWorld))
GameFunctions.Party.InviteSameWorld(player.PlayerName, (ushort) world.RowId, chunk.Message?.ContentId ?? 0); 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
View File
@@ -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;
} }
+39 -39
View File
@@ -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>&lt;Ninguno&gt;</value> <value>&lt;Ninguno&gt;</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>
+2 -2
View File
@@ -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>
+2 -2
View File
@@ -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>
+2 -2
View File
@@ -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>
+18 -74
View File
@@ -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>
@@ -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,9 +218,11 @@ 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] != '>')
continue;
var tag = Encoding.UTF8.GetString(bytes[start..(i + 1)]); var tag = Encoding.UTF8.GetString(bytes[start..(i + 1)]);
var parts = tag[4..^1].Split(',', 2); 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)) if (parts.Length == 2 && uint.TryParse(parts[0], out var group) && uint.TryParse(parts[1], out var key))
@@ -294,11 +243,6 @@ internal static class AutoTranslate
start = -1; start = -1;
} }
else
{
continue;
}
}
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)
start = i; start = i;
@@ -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 { }
+8 -4
View File
@@ -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),
+10 -14
View File
@@ -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;
} }
+2 -1
View File
@@ -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];
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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++];
} }
} }
+21 -19
View File
@@ -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}://")))
{
if (rawURI.StartsWith($"{scheme}://"))
{
return new UriPayload(new Uri(rawURI)); 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)
{ {
+10 -8
View File
@@ -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;
} }
} }
+6 -3
View File
@@ -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];
+9 -7
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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();