mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 00:22:40 +01:00
Fix chat manager issues hopefully
This commit is contained in:
@@ -190,9 +190,16 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
throw new ArgumentNullException(nameof(newChannels));
|
||||
|
||||
logger.LogTrace("ChangeChannels {0}...", connectionId);
|
||||
var provider = await RemoveProvider(connectionId, false, cancellationToken).ConfigureAwait(false);
|
||||
var provider = await RemoveProviderChannels(connectionId, false, cancellationToken).ConfigureAwait(false);
|
||||
if (provider == null)
|
||||
return;
|
||||
|
||||
if (!provider.Connected)
|
||||
{
|
||||
logger.LogDebug("Cannot map channels, provider {providerId} disconnected!", connectionId);
|
||||
return;
|
||||
}
|
||||
|
||||
var results = await provider.MapChannels(newChannels, cancellationToken).ConfigureAwait(false);
|
||||
lock (activeChatBots)
|
||||
{
|
||||
@@ -260,29 +267,14 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
throw new ArgumentNullException(nameof(newSettings));
|
||||
|
||||
logger.LogTrace("ChangeSettings...");
|
||||
IProvider provider;
|
||||
|
||||
async Task DisconnectProvider(IProvider p)
|
||||
{
|
||||
try
|
||||
{
|
||||
await p.Disconnect(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await p.DisposeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
Task disconnectTask;
|
||||
IProvider provider = null;
|
||||
lock (providers)
|
||||
{
|
||||
// raw settings changes forces a rebuild of the provider
|
||||
if (providers.TryGetValue(newSettings.Id.Value, out provider))
|
||||
{
|
||||
providers.Remove(newSettings.Id.Value);
|
||||
disconnectTask = DisconnectProvider(provider);
|
||||
}
|
||||
if (providers.ContainsKey(newSettings.Id.Value))
|
||||
disconnectTask = DeleteConnection(newSettings.Id.Value, cancellationToken);
|
||||
else
|
||||
disconnectTask = Task.CompletedTask;
|
||||
if (newSettings.Enabled.Value)
|
||||
@@ -430,7 +422,6 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
builtinCommands.Add(tgsCommand.Name.ToUpperInvariant(), tgsCommand);
|
||||
var initialChatBots = activeChatBots.ToList();
|
||||
await Task.WhenAll(initialChatBots.Select(x => ChangeSettings(x, cancellationToken))).ConfigureAwait(false);
|
||||
await Task.WhenAll(initialChatBots.Select(x => ChangeChannels(x.Id.Value, x.Channels, cancellationToken))).ConfigureAwait(false);
|
||||
initialProviderConnectionsTask = InitialConnection();
|
||||
chatHandler = MonitorMessages(handlerCts.Token);
|
||||
}
|
||||
@@ -441,7 +432,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
handlerCts.Cancel();
|
||||
if (chatHandler != null)
|
||||
await chatHandler.ConfigureAwait(false);
|
||||
await Task.WhenAll(providers.Select(x => x.Value).Select(x => x.Disconnect(cancellationToken))).ConfigureAwait(false);
|
||||
await Task.WhenAll(providers.Select(x => x.Key).Select(x => DeleteConnection(x, cancellationToken))).ConfigureAwait(false);
|
||||
await messageSendTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -480,7 +471,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <inheritdoc />
|
||||
public async Task DeleteConnection(long connectionId, CancellationToken cancellationToken)
|
||||
{
|
||||
var provider = await RemoveProvider(connectionId, true, cancellationToken).ConfigureAwait(false);
|
||||
var provider = await RemoveProviderChannels(connectionId, true, cancellationToken).ConfigureAwait(false);
|
||||
if (provider != null)
|
||||
try
|
||||
{
|
||||
@@ -510,23 +501,28 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a <see cref="IProvider"/> from <see cref="providers"/> and <see cref="mappedChannels"/> optionally updating the <see cref="trackingContexts"/> as well.
|
||||
/// Remove a <see cref="IProvider"/> from <see cref="mappedChannels"/> optionally removing the provider itself from <see cref="providers"/> and updating the <see cref="trackingContexts"/> as well.
|
||||
/// </summary>
|
||||
/// <param name="connectionId">The <see cref="Api.Models.EntityId.Id"/> of the <see cref="IProvider"/> to delete.</param>
|
||||
/// <param name="updateTrackings">If <see cref="trackingContexts"/> should be update.</param>
|
||||
/// <param name="removeProvider">If the provider should be removed from <see cref="providers"/> and <see cref="trackingContexts"/> should be update.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IProvider"/> being removed if it exists, <see langword="null"/> otherwise.</returns>
|
||||
async Task<IProvider> RemoveProvider(long connectionId, bool updateTrackings, CancellationToken cancellationToken)
|
||||
async Task<IProvider> RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("RemoveProvider {0}...", connectionId);
|
||||
logger.LogTrace("RemoveProviderChannels {0}...", connectionId);
|
||||
IProvider provider;
|
||||
lock (providers)
|
||||
{
|
||||
if (!providers.TryGetValue(connectionId, out provider))
|
||||
{
|
||||
logger.LogTrace("Aborted, no such provider!");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (removeProvider)
|
||||
providers.Remove(connectionId);
|
||||
}
|
||||
|
||||
Task trackingContextsUpdateTask;
|
||||
lock (mappedChannels)
|
||||
{
|
||||
@@ -535,7 +531,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
|
||||
var newMappedChannels = mappedChannels.Select(y => y.Value.Channel).ToList();
|
||||
|
||||
if (updateTrackings)
|
||||
if (removeProvider)
|
||||
lock (trackingContexts)
|
||||
trackingContextsUpdateTask = Task.WhenAll(trackingContexts.Select(x => x.UpdateChannels(newMappedChannels, cancellationToken)));
|
||||
else
|
||||
@@ -607,6 +603,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
.First();
|
||||
mappedChannel = mappedChannels
|
||||
.Where(x => x.Value.ProviderId == providerId && x.Value.ProviderChannelId == providerChannelId)
|
||||
.Select(x => (KeyValuePair<ulong, ChannelMapping>?)x)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
@@ -652,12 +649,11 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
return;
|
||||
}
|
||||
|
||||
var mappingNonNullableKvp = mappedChannel.Value;
|
||||
var mapping = mappingNonNullableKvp.Value;
|
||||
var mappingChannelRepresentation = mappedChannel.Value.Value.Channel;
|
||||
|
||||
message.User.Channel.Id = mapping.Channel.Id;
|
||||
message.User.Channel.Tag = mapping.Channel.Tag;
|
||||
message.User.Channel.IsAdminChannel = mapping.Channel.IsAdminChannel;
|
||||
message.User.Channel.Id = mappingChannelRepresentation.Id;
|
||||
message.User.Channel.Tag = mappingChannelRepresentation.Tag;
|
||||
message.User.Channel.IsAdminChannel = mappingChannelRepresentation.IsAdminChannel;
|
||||
}
|
||||
|
||||
var splits = new List<string>(message.Content.Trim().Split(' '));
|
||||
|
||||
@@ -93,6 +93,11 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
/// </summary>
|
||||
Snowflake currentUserId;
|
||||
|
||||
/// <summary>
|
||||
/// The bot's username at the time of connection.
|
||||
/// </summary>
|
||||
string initialUserName;
|
||||
|
||||
/// <summary>
|
||||
/// Normalize a discord mention string.
|
||||
/// </summary>
|
||||
@@ -194,20 +199,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
if (channels == null)
|
||||
throw new ArgumentNullException(nameof(channels));
|
||||
|
||||
if (!Connected)
|
||||
{
|
||||
Logger.LogWarning("Cannot map channels, provider disconnected!");
|
||||
return Array.Empty<ChannelRepresentation>();
|
||||
}
|
||||
|
||||
var usersClient = serviceProvider.GetRequiredService<IDiscordRestUserAPI>();
|
||||
var currentUserResponse = await usersClient.GetCurrentUserAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!currentUserResponse.IsSuccess)
|
||||
{
|
||||
Logger.LogWarning("Error retrieving current Discord user: {0}", currentUserResponse.Error.Message);
|
||||
return Array.Empty<ChannelRepresentation>();
|
||||
}
|
||||
bool remapRequired = false;
|
||||
|
||||
async Task<ChannelRepresentation> GetModelChannelFromDBChannel(Api.Models.ChatChannel channelFromDB)
|
||||
{
|
||||
@@ -215,14 +207,12 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
throw new InvalidOperationException("ChatChannel missing DiscordChannelId!");
|
||||
|
||||
var channelId = channelFromDB.DiscordChannelId.Value;
|
||||
ulong discordChannelId;
|
||||
string connectionName;
|
||||
string friendlyName;
|
||||
if (channelId == 0)
|
||||
{
|
||||
connectionName = currentUserResponse.Entity.Username;
|
||||
connectionName = initialUserName;
|
||||
friendlyName = "(Unmapped accessible channels)";
|
||||
discordChannelId = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -231,6 +221,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
if (!discordChannelResponse.IsSuccess)
|
||||
{
|
||||
Logger.LogWarning("Error retrieving discord channel {0}: {1}", channelId, discordChannelResponse.Error.Message);
|
||||
remapRequired = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -240,7 +231,6 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
return null;
|
||||
}
|
||||
|
||||
discordChannelId = discordChannelResponse.Entity.ID.Value;
|
||||
friendlyName = discordChannelResponse.Entity.Name.Value;
|
||||
|
||||
var guildsClient = serviceProvider.GetRequiredService<IDiscordRestGuildAPI>();
|
||||
@@ -254,6 +244,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
"Error retrieving discord guild {0}: {1}",
|
||||
discordChannelResponse.Entity.GuildID.Value,
|
||||
discordChannelResponse.Error.Message);
|
||||
remapRequired = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -262,7 +253,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
|
||||
var channelModel = new ChannelRepresentation
|
||||
{
|
||||
RealId = discordChannelId,
|
||||
RealId = channelId,
|
||||
IsAdminChannel = channelFromDB.IsAdminChannel == true,
|
||||
ConnectionName = connectionName,
|
||||
FriendlyName = friendlyName,
|
||||
@@ -276,13 +267,13 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
|
||||
var tasks = channels
|
||||
.Select(x => GetModelChannelFromDBChannel(x))
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
|
||||
var enumerator = tasks
|
||||
.Select(x => x.Result)
|
||||
.Where(x => x != null)
|
||||
.ToList();
|
||||
|
||||
lock (mappedChannels)
|
||||
@@ -291,6 +282,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
mappedChannels.AddRange(enumerator.Select(x => x.RealId));
|
||||
}
|
||||
|
||||
if (remapRequired)
|
||||
EnqueueMessage(null);
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
|
||||
@@ -634,6 +628,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
}
|
||||
|
||||
currentUserId = currentUserResult.Entity.ID;
|
||||
initialUserName = currentUserResult.Entity.Username;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -183,6 +183,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
|
||||
/// <param name="message">The <see cref="Message"/> to queue.</param>
|
||||
protected void EnqueueMessage(Message message)
|
||||
{
|
||||
if (message == null)
|
||||
Logger.LogTrace("Requesting channel remap...");
|
||||
|
||||
lock (messageQueue)
|
||||
{
|
||||
messageQueue.Enqueue(message);
|
||||
|
||||
Reference in New Issue
Block a user