From d9c1ca4bcee82178d3aa06a63e6cdf4095104c7a Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 1 Oct 2021 11:40:30 -0400 Subject: [PATCH] Fix potential issue with chat message mapping and processing --- .../Components/Chat/ChatManager.cs | 85 ++++++++++++------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs index fcc2a2c71c..3e2851e5c4 100644 --- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs +++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs @@ -593,41 +593,66 @@ namespace Tgstation.Server.Host.Components.Chat } // map the channel if it's private and we haven't seen it + KeyValuePair? mappedChannel; + long providerId; lock (providers) { - var providerId = providers.Where(x => x.Value == provider).Select(x => x.Key).First(); - var enumerable = mappedChannels.Where(x => x.Value.ProviderId == providerId && x.Value.ProviderChannelId == message.User.Channel.RealId); - if (message.User.Channel.IsPrivateChannel) - lock (mappedChannels) - if (!enumerable.Any()) + providerId = providers + .Where(x => x.Value == provider) + .Select(x => x.Key) + .First(); + mappedChannel = mappedChannels + .Where(x => x.Value.ProviderId == providerId && x.Value.ProviderChannelId == message.User.Channel.RealId) + .FirstOrDefault(); + } + + if (message.User.Channel.IsPrivateChannel) + lock (mappedChannels) + if (!mappedChannel.HasValue) + { + ulong newId; + lock (synchronizationLock) + newId = channelIdCounter++; + logger.LogTrace( + "Mapping private channel {0}:{1} as {2}", + message.User.Channel.ConnectionName, + message.User.FriendlyName, + newId); + mappedChannels.Add(newId, new ChannelMapping { - ulong newId; - lock (synchronizationLock) - newId = channelIdCounter++; - logger.LogTrace( - "Mapping private channel {0}:{1} as {2}", - message.User.Channel.ConnectionName, - message.User.FriendlyName, - newId); - mappedChannels.Add(newId, new ChannelMapping - { - IsWatchdogChannel = false, - ProviderChannelId = message.User.Channel.RealId, - ProviderId = providerId, - Channel = message.User.Channel, - }); - message.User.Channel.RealId = newId; - } - else - message.User.Channel.RealId = enumerable.First().Key; - else + IsWatchdogChannel = false, + ProviderChannelId = message.User.Channel.RealId, + ProviderId = providerId, + Channel = message.User.Channel, + }); + message.User.Channel.RealId = newId; + } + else + message.User.Channel.RealId = mappedChannel.Value.Key; + else + { + if (!mappedChannel.HasValue) { - // need to add tag and isAdminChannel - var mapping = enumerable.First().Value; - message.User.Channel.Id = mapping.Channel.Id; - message.User.Channel.Tag = mapping.Channel.Tag; - message.User.Channel.IsAdminChannel = mapping.Channel.IsAdminChannel; + logger.LogError( + "Error mapping message: Provider ID: {providerId}, Channel Real ID: {realId}", + providerId, + message.User.Channel.RealId); + await SendMessage( + "Processing error, check logs!", + new List + { + message.User.Channel.RealId, + }, + cancellationToken) + .ConfigureAwait(false); + return; } + + var mapping = mappedChannel.Value.Value; + + message.User.Channel.Id = mapping.Channel.Id; + message.User.Channel.Tag = mapping.Channel.Tag; + message.User.Channel.IsAdminChannel = mapping.Channel.IsAdminChannel; } var splits = new List(message.Content.Trim().Split(' '));