fix: avoid switching to non-existent linkshell idx

Prevents switching channels to a non-existent linkshell index (for both
regular linkshells and cross-world linkshells). ExtraChat linkshells are
already validated separately.

Prevents ChatLogWindow Draw failures from causing ChatTwo to grab input
focus each frame if the exception occurs during an Activate event.
This commit is contained in:
Dean Sheather
2024-07-21 01:51:03 +10:00
parent f6bbd55ed1
commit 70a60b83e5
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);