Merge pull request #94

fix: avoid switching to non-existent linkshell idx
This commit is contained in:
Infi
2024-07-20 18:00:58 +02:00
committed by GitHub
3 changed files with 59 additions and 4 deletions
+32
View File
@@ -312,6 +312,36 @@ internal sealed unsafe class Chat : IDisposable
// EurekaContextMenuTellHook!.Original(a1, playerName, worldName, worldId, accountId, contentId, reason);
// }
/// <summary>
/// Returns true if the channel is any non-linkshell channel, or if the
/// linkshell actually exists.
/// </summary>
internal static bool ValidAnyLinkshell(InputChannel channel)
{
var idx = channel.LinkshellIndex();
if (idx == uint.MaxValue || channel.IsExtraChatLinkshell())
return true;
if (channel.IsLinkshell() && ValidLinkshell(idx))
return true;
if (channel.IsCrossLinkshell() && ValidCrossLinkshell(idx))
return true;
return false;
}
internal static bool ValidLinkshell(uint idx)
{
if (idx > 7)
return false;
return InfoProxyLinkshell.Instance()->LinkShells[(int) idx].Id != 0;
}
internal static bool ValidCrossLinkshell(uint idx)
{
if (idx > 7)
return false;
return InfoProxyCrossWorldLinkshell.Instance()->CrossWorldLinkshells[(int) idx].Name.Length > 0;
}
internal static void SetChannel(InputChannel channel, string? tellTarget = null)
{
// ExtraChat linkshells aren't supported in game so we never want to
@@ -326,6 +356,8 @@ internal sealed unsafe class Chat : IDisposable
var idx = channel.LinkshellIndex();
if (idx == uint.MaxValue)
idx = 0;
if (!ValidAnyLinkshell(channel))
return;
RaptureShellModule.Instance()->ChangeChatChannel((int) channel, idx, target, true);
target->Dtor(true);
+1
View File
@@ -8,6 +8,7 @@ using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI;
using ImGuiNET;
using ModifierFlag = ChatTwo.GameFunctions.Types.ModifierFlag;
using ModifierFlag = ChatTwo.GameFunctions.Types.ModifierFlag;
+23 -1
View File
@@ -172,6 +172,9 @@ public sealed class ChatLogWindow : Window
if (info.Channel != null)
{
if (!GameFunctions.Chat.ValidAnyLinkshell(info.Channel.Value))
return;
var prevTemp = TempChannel;
if (info.Permanent)
SetChannel(info.Channel.Value);
@@ -206,11 +209,21 @@ public sealed class ChatLogWindow : Window
if (info.Channel is InputChannel.Linkshell1 && info.Rotate != RotateMode.None)
{
var idx = GameFunctions.Chat.RotateLinkshellHistory(mode);
if (idx < 0 || !GameFunctions.Chat.ValidLinkshell((uint)idx))
{
TempChannel = 0;
return;
}
TempChannel = info.Channel.Value + (uint) idx;
}
else if (info.Channel is InputChannel.CrossLinkshell1 && info.Rotate != RotateMode.None)
{
var idx = GameFunctions.Chat.RotateCrossLinkshellHistory(mode);
if (idx < 0 || !GameFunctions.Chat.ValidCrossLinkshell((uint)idx))
{
TempChannel = 0;
return;
}
TempChannel = info.Channel.Value + (uint) idx;
}
}
@@ -479,12 +492,21 @@ public sealed class ChatLogWindow : Window
}
public override void Draw()
{
try
{
DrawChatLog();
AddPopOutsToDraw();
DrawAutoComplete();
}
catch (Exception e)
{
Plugin.Log.Error($"Error drawing Chat Log window: {e}");
// Prevent recurring draw failures from constantly trying to grab
// input focus, which breaks every other ImGui window.
Activate = false;
}
}
private static bool IsChatMode => Plugin.Config.PreviewPosition is PreviewPosition.Inside or PreviewPosition.Tooltip;
private unsafe void DrawChatLog()