mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-23 13:07:07 +01:00
Nullify ChatManager
This commit is contained in:
@@ -21,8 +21,6 @@ using Tgstation.Server.Host.Components.Interop;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Utils;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
/// <inheritdoc cref="IChatManager" />
|
||||
@@ -103,17 +101,17 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <summary>
|
||||
/// The <see cref="ICustomCommandHandler"/> for the <see cref="ChangeChannels(long, IEnumerable{Models.ChatChannel}, CancellationToken)"/>.
|
||||
/// </summary>
|
||||
ICustomCommandHandler customCommandHandler;
|
||||
ICustomCommandHandler? customCommandHandler;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Task"/> that monitors incoming chat messages.
|
||||
/// </summary>
|
||||
Task chatHandler;
|
||||
Task? chatHandler;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Task"/> that represents the <see cref="IProvider"/>s initial connection.
|
||||
/// </summary>
|
||||
Task initialProviderConnectionsTask;
|
||||
Task? initialProviderConnectionsTask;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Task"/> that represents all sent messages.
|
||||
@@ -256,7 +254,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
lock (mappedChannels)
|
||||
{
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(connectionId, out IProvider verify) || verify != provider) // aborted again
|
||||
if (!providers.TryGetValue(connectionId, out var verify) || verify != provider) // aborted again
|
||||
return;
|
||||
foreach (var newMapping in newMappings)
|
||||
{
|
||||
@@ -270,7 +268,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
// we only want to update contexts if everything at startup has connected once already
|
||||
// otherwise we could send an incomplete channel set to the DMAPI, which will then spout all its queued messages into it instead of all relevant chatbots
|
||||
// The watchdog can call this if it needs to after starting up
|
||||
if (initialProviderConnectionsTask.IsCompleted)
|
||||
if (initialProviderConnectionsTask!.IsCompleted)
|
||||
await UpdateTrackingContexts(cancellationToken);
|
||||
}
|
||||
finally
|
||||
@@ -288,23 +286,25 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
logger.LogTrace("ChangeSettings...");
|
||||
|
||||
Task disconnectTask;
|
||||
IProvider provider = null;
|
||||
IProvider? provider = null;
|
||||
var newSettingsId = Models.ModelExtensions.Require(newSettings, x => x.Id);
|
||||
var newSettingsEnabled = Models.ModelExtensions.Require(newSettings, x => x.Enabled);
|
||||
lock (providers)
|
||||
{
|
||||
// raw settings changes forces a rebuild of the provider
|
||||
if (providers.ContainsKey(newSettings.Id.Value))
|
||||
disconnectTask = DeleteConnection(newSettings.Id.Value, cancellationToken);
|
||||
if (providers.ContainsKey(newSettingsId))
|
||||
disconnectTask = DeleteConnection(newSettingsId, cancellationToken);
|
||||
else
|
||||
disconnectTask = Task.CompletedTask;
|
||||
if (newSettings.Enabled.Value)
|
||||
if (newSettingsEnabled)
|
||||
{
|
||||
provider = providerFactory.CreateProvider(newSettings);
|
||||
providers.Add(newSettings.Id.Value, provider);
|
||||
providers.Add(newSettingsId, provider);
|
||||
}
|
||||
}
|
||||
|
||||
lock (mappedChannels)
|
||||
foreach (var oldMappedChannelId in mappedChannels.Where(x => x.Value.ProviderId == newSettings.Id).Select(x => x.Key).ToList())
|
||||
foreach (var oldMappedChannelId in mappedChannels.Where(x => x.Value.ProviderId == newSettingsId).Select(x => x.Key).ToList())
|
||||
mappedChannels.Remove(oldMappedChannelId);
|
||||
|
||||
await disconnectTask;
|
||||
@@ -318,8 +318,8 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
var reconnectionUpdateTask = provider?.SetReconnectInterval(
|
||||
newSettings.ReconnectionInterval.Value,
|
||||
newSettings.Enabled.Value)
|
||||
Models.ModelExtensions.Require(newSettings, x => x.ReconnectionInterval),
|
||||
newSettingsEnabled)
|
||||
?? Task.CompletedTask;
|
||||
lock (activeChatBots)
|
||||
{
|
||||
@@ -358,7 +358,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
|
||||
message = String.Format(CultureInfo.InvariantCulture, "WD: {0}", message);
|
||||
|
||||
if (!initialProviderConnectionsTask.IsCompleted)
|
||||
if (!initialProviderConnectionsTask!.IsCompleted)
|
||||
logger.LogTrace("Waiting for initial provider connections before sending watchdog message...");
|
||||
|
||||
// Reimplementing QueueMessage
|
||||
@@ -397,11 +397,11 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
wdChannels.Select(
|
||||
async x =>
|
||||
{
|
||||
ChannelMapping channelMapping;
|
||||
ChannelMapping? channelMapping;
|
||||
lock (mappedChannels)
|
||||
if (!mappedChannels.TryGetValue(x, out channelMapping))
|
||||
return;
|
||||
IProvider provider;
|
||||
IProvider? provider;
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(channelMapping.ProviderId, out provider))
|
||||
return;
|
||||
@@ -432,7 +432,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
AddMessageTask(task);
|
||||
|
||||
Task callbackTask;
|
||||
Func<bool, Task> finalUpdateAction = null;
|
||||
Func<bool, Task>? finalUpdateAction = null;
|
||||
async Task CallbackTask(string errorMessage, string dreamMakerOutput)
|
||||
{
|
||||
await task;
|
||||
@@ -458,7 +458,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
return;
|
||||
}
|
||||
|
||||
AddMessageTask(finalUpdateAction(active));
|
||||
AddMessageTask(finalUpdateAction!(active));
|
||||
}
|
||||
|
||||
return (errorMessage, dreamMakerOutput) =>
|
||||
@@ -496,7 +496,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
if (customCommandHandler == null)
|
||||
throw new InvalidOperationException("RegisterCommandHandler() hasn't been called!");
|
||||
|
||||
IChatTrackingContext context = null;
|
||||
IChatTrackingContext context = null!;
|
||||
lock (mappedChannels)
|
||||
context = new ChatTrackingContext(
|
||||
customCommandHandler,
|
||||
@@ -525,7 +525,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
await channelSink.UpdateChannels(channels, cancellationToken);
|
||||
}
|
||||
|
||||
var waitingForInitialConnection = !initialProviderConnectionsTask.IsCompleted;
|
||||
var waitingForInitialConnection = !initialProviderConnectionsTask!.IsCompleted;
|
||||
if (waitingForInitialConnection)
|
||||
{
|
||||
logger.LogTrace("Waiting for initial chat bot connections before updating tracking contexts...");
|
||||
@@ -563,7 +563,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
? semaphore
|
||||
: null)
|
||||
using (hasSemaphore
|
||||
? await SemaphoreSlimContext.Lock(semaphore, cancellationToken)
|
||||
? await SemaphoreSlimContext.Lock(semaphore!, cancellationToken)
|
||||
: null)
|
||||
{
|
||||
var provider = await RemoveProviderChannels(connectionId, true, cancellationToken);
|
||||
@@ -590,7 +590,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask HandleRestart(Version updateVersion, bool handlerMayDelayShutdownWithExtremelyLongRunningTasks, CancellationToken cancellationToken)
|
||||
public ValueTask HandleRestart(Version? updateVersion, bool handlerMayDelayShutdownWithExtremelyLongRunningTasks, CancellationToken cancellationToken)
|
||||
{
|
||||
var message = updateVersion == null
|
||||
? $"TGS: {(handlerMayDelayShutdownWithExtremelyLongRunningTasks ? "Graceful shutdown" : "Going down")}..."
|
||||
@@ -619,10 +619,10 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <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="ValueTask{TResult}"/> resulting in the <see cref="IProvider"/> being removed if it exists, <see langword="null"/> otherwise.</returns>
|
||||
async ValueTask<IProvider> RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken)
|
||||
async ValueTask<IProvider?> RemoveProviderChannels(long connectionId, bool removeProvider, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("RemoveProviderChannels {connectionId}...", connectionId);
|
||||
IProvider provider;
|
||||
IProvider? provider;
|
||||
lock (providers)
|
||||
{
|
||||
if (!providers.TryGetValue(connectionId, out provider))
|
||||
@@ -664,7 +664,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
async ValueTask RemapProvider(IProvider provider, CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("Remapping channels for provider reconnection...");
|
||||
IEnumerable<Models.ChatChannel> channelsToMap;
|
||||
IEnumerable<Models.ChatChannel>? channelsToMap;
|
||||
long providerId;
|
||||
lock (providers)
|
||||
providerId = providers.Where(x => x.Value == provider).Select(x => x.Key).First();
|
||||
@@ -685,7 +685,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask"/> representing the running operation.</returns>
|
||||
#pragma warning disable CA1502
|
||||
async ValueTask ProcessMessage(IProvider provider, Message message, bool recursed, CancellationToken cancellationToken)
|
||||
async ValueTask ProcessMessage(IProvider provider, Message? message, bool recursed, CancellationToken cancellationToken)
|
||||
#pragma warning restore CA1502
|
||||
{
|
||||
if (!provider.Connected)
|
||||
@@ -843,16 +843,16 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
splits.RemoveAt(0);
|
||||
var arguments = String.Join(" ", splits);
|
||||
|
||||
Tuple<ICommand, IChatTrackingContext> GetCommand()
|
||||
Tuple<ICommand, IChatTrackingContext?>? GetCommand()
|
||||
{
|
||||
if (!builtinCommands.TryGetValue(command, out var handler))
|
||||
return trackingContexts
|
||||
.Where(trackingContext => trackingContext.Active)
|
||||
.SelectMany(trackingContext => trackingContext.CustomCommands.Select(customCommand => Tuple.Create<ICommand, IChatTrackingContext>(customCommand, trackingContext)))
|
||||
.SelectMany(trackingContext => trackingContext.CustomCommands.Select(customCommand => Tuple.Create<ICommand, IChatTrackingContext?>(customCommand, trackingContext)))
|
||||
.Where(tuple => tuple.Item1.Name.Equals(command, StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
|
||||
return Tuple.Create<ICommand, IChatTrackingContext>(handler, null);
|
||||
return Tuple.Create<ICommand, IChatTrackingContext?>(handler, null);
|
||||
}
|
||||
|
||||
const string UnknownCommandMessage = "TGS: Unknown command! Type '?' or 'help' for available commands.";
|
||||
@@ -935,11 +935,11 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
async Task MonitorMessages(CancellationToken cancellationToken)
|
||||
{
|
||||
logger.LogTrace("Starting processing loop...");
|
||||
var messageTasks = new Dictionary<IProvider, Task<Message>>();
|
||||
var messageTasks = new Dictionary<IProvider, Task<Message?>>();
|
||||
ValueTask activeProcessingTask = ValueTask.CompletedTask;
|
||||
try
|
||||
{
|
||||
Task updatedTask = null;
|
||||
Task? updatedTask = null;
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (updatedTask?.IsCompleted != false)
|
||||
@@ -1025,7 +1025,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
/// <param name="message">The <see cref="MessageContent"/> to send.</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
|
||||
ValueTask SendMessage(IEnumerable<ulong> channelIds, Message replyTo, MessageContent message, CancellationToken cancellationToken)
|
||||
ValueTask SendMessage(IEnumerable<ulong> channelIds, Message? replyTo, MessageContent message, CancellationToken cancellationToken)
|
||||
{
|
||||
var channelIdsList = channelIds.ToList();
|
||||
|
||||
@@ -1041,11 +1041,11 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
return ValueTaskExtensions.WhenAll(
|
||||
channelIdsList.Select(x =>
|
||||
{
|
||||
ChannelMapping channelMapping;
|
||||
ChannelMapping? channelMapping;
|
||||
lock (mappedChannels)
|
||||
if (!mappedChannels.TryGetValue(x, out channelMapping))
|
||||
return ValueTask.CompletedTask;
|
||||
IProvider provider;
|
||||
IProvider? provider;
|
||||
lock (providers)
|
||||
if (!providers.TryGetValue(channelMapping.ProviderId, out provider))
|
||||
return ValueTask.CompletedTask;
|
||||
@@ -1102,7 +1102,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
var cancellationToken = handlerCts.Token;
|
||||
if (waitForConnections)
|
||||
await initialProviderConnectionsTask.WaitAsync(cancellationToken);
|
||||
await initialProviderConnectionsTask!.WaitAsync(cancellationToken);
|
||||
|
||||
await SendMessage(
|
||||
channelIdsFactory(),
|
||||
|
||||
Reference in New Issue
Block a user