diff --git a/HellionChat/GameFunctions/Chat.cs b/HellionChat/GameFunctions/Chat.cs index b4a0396..4d75d99 100755 --- a/HellionChat/GameFunctions/Chat.cs +++ b/HellionChat/GameFunctions/Chat.cs @@ -423,16 +423,24 @@ internal sealed unsafe class Chat : IDisposable ); } - // Check if channel is valid (non-linkshell or existing linkshell) - internal static bool ValidAnyLinkshell(InputChannel channel) + // --------------------------------------------------------------- + // Cherry-picked from ChatTwo upstream f35b7d3 (Infiziert90, 2026-05-12) + // - Renamed ValidAnyLinkshell -> IsChannelOrExistingLinkshell. The + // name now states intent: returns true for any non-linkshell + // channel, or a linkshell index that actually exists. + // --------------------------------------------------------------- + internal static bool IsChannelOrExistingLinkshell(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; + + if (channel.IsLinkshell()) + return ValidLinkshell(idx); + + if (channel.IsCrossLinkshell()) + return ValidCrossLinkshell(idx); + return false; } @@ -531,12 +539,17 @@ internal sealed unsafe class Chat : IDisposable if (idx == uint.MaxValue) idx = 0; - if (!ValidAnyLinkshell(channel)) - return; + // --------------------------------------------------------------- + // Cherry-picked from ChatTwo upstream f35b7d3 (Infiziert90, 2026-05-12) + // - Wrap ChangeChatChannel in the validity check instead of + // early-returning. The previous early return skipped Dtor and + // leaked the native Utf8String allocated a few lines above. + // --------------------------------------------------------------- + if (IsChannelOrExistingLinkshell(channel)) + RaptureShellModule + .Instance() + ->ChangeChatChannel(tellTarget != null ? 17 : (int)channel, idx, target, true); - RaptureShellModule - .Instance() - ->ChangeChatChannel(tellTarget != null ? 17 : (int)channel, idx, target, true); target->Dtor(true); } diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index 9bb1f79..0f43eda 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -272,7 +272,10 @@ public sealed class ChatLogWindow : Window } } - if (targetChannel == null || !GameFunctions.Chat.ValidAnyLinkshell(targetChannel.Value)) + if ( + targetChannel == null + || !GameFunctions.Chat.IsChannelOrExistingLinkshell(targetChannel.Value) + ) { Plugin.Log.Warning( $"Channel was set to an invalid value '{targetChannel}', ignoring"