mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-24 21:46:52 +01:00
Disallow custom chat commands while the server is rebooting
Also a bunch of cleanups in `ChatManager.ProcessMessage`
This commit is contained in:
@@ -154,7 +154,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
|
||||
synchronizationLock = new object();
|
||||
|
||||
builtinCommands = new Dictionary<string, ICommand>();
|
||||
builtinCommands = new Dictionary<string, ICommand>(StringComparer.OrdinalIgnoreCase);
|
||||
providers = new Dictionary<long, IProvider>();
|
||||
mappedChannels = new Dictionary<ulong, ChannelMapping>();
|
||||
trackingContexts = new List<IChatTrackingContext>();
|
||||
@@ -713,6 +713,18 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
return;
|
||||
}
|
||||
|
||||
ValueTask TextReply(string reply) => SendMessage(
|
||||
new List<ulong>
|
||||
{
|
||||
message.User.Channel.RealId,
|
||||
},
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = reply,
|
||||
},
|
||||
cancellationToken);
|
||||
|
||||
if (message.User.Channel.IsPrivateChannel)
|
||||
lock (mappedChannels)
|
||||
if (!mappedChannel.HasValue)
|
||||
@@ -753,17 +765,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
logger.LogTrace("message: {messageJson}", JsonConvert.SerializeObject(message));
|
||||
lock (mappedChannels)
|
||||
logger.LogTrace("mappedChannels: {mappedChannelsJson}", JsonConvert.SerializeObject(mappedChannels));
|
||||
await SendMessage(
|
||||
new List<ulong>
|
||||
{
|
||||
message.User.Channel.RealId,
|
||||
},
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = "TGS: Processing error, check logs!",
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply("TGS: Processing error, check logs!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -805,41 +807,29 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
if (splits.Count == 0)
|
||||
{
|
||||
// just a mention
|
||||
await SendMessage(
|
||||
new List<ulong>
|
||||
{
|
||||
message.User.Channel.RealId,
|
||||
},
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = "Hi!",
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply("Hi!");
|
||||
return;
|
||||
}
|
||||
|
||||
var command = splits[0].ToUpperInvariant();
|
||||
var command = splits[0];
|
||||
splits.RemoveAt(0);
|
||||
var arguments = String.Join(" ", splits);
|
||||
|
||||
ICommand GetCommand(string commandName)
|
||||
Tuple<ICommand, IChatTrackingContext> GetCommand()
|
||||
{
|
||||
if (!builtinCommands.TryGetValue(commandName, out var handler))
|
||||
{
|
||||
handler = trackingContexts
|
||||
.Where(x => x.CustomCommands != null)
|
||||
.SelectMany(x => x.CustomCommands)
|
||||
.Where(x => x.Name.ToUpperInvariant() == commandName)
|
||||
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)))
|
||||
.Where(tuple => tuple.Item1.Name.Equals(command, StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
return handler;
|
||||
return Tuple.Create<ICommand, IChatTrackingContext>(handler, null);
|
||||
}
|
||||
|
||||
const string UnknownCommandMessage = "Unknown command! Type '?' or 'help' for available commands.";
|
||||
const string UnknownCommandMessage = "TGS: Unknown command! Type '?' or 'help' for available commands.";
|
||||
|
||||
if (command == "HELP" || command == "?")
|
||||
if (command.Equals("help", StringComparison.OrdinalIgnoreCase) || command == "?")
|
||||
{
|
||||
string helpText;
|
||||
if (splits.Count == 0)
|
||||
@@ -847,56 +837,40 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
var allCommands = builtinCommands.Select(x => x.Value).ToList();
|
||||
allCommands.AddRange(
|
||||
trackingContexts
|
||||
.Where(x => x.CustomCommands != null)
|
||||
.SelectMany(
|
||||
x => x.CustomCommands));
|
||||
helpText = String.Format(CultureInfo.InvariantCulture, "Available commands (Type '?' or 'help' and then a command name for more details): {0}", String.Join(", ", allCommands.Select(x => x.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var helpHandler = GetCommand(splits[0].ToUpperInvariant());
|
||||
var (helpHandler, _) = GetCommand();
|
||||
if (helpHandler != default)
|
||||
helpText = String.Format(CultureInfo.InvariantCulture, "{0}: {1}{2}", helpHandler.Name, helpHandler.HelpText, helpHandler.AdminOnly ? " - May only be used in admin channels" : String.Empty);
|
||||
else
|
||||
helpText = UnknownCommandMessage;
|
||||
}
|
||||
|
||||
await SendMessage(
|
||||
new List<ulong> { message.User.Channel.RealId },
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = helpText,
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply(helpText);
|
||||
return;
|
||||
}
|
||||
|
||||
var commandHandler = GetCommand(command);
|
||||
var (commandHandler, trackingContext) = GetCommand();
|
||||
|
||||
if (commandHandler == default)
|
||||
{
|
||||
await SendMessage(
|
||||
new List<ulong> { message.User.Channel.RealId },
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = UnknownCommandMessage,
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply(UnknownCommandMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (trackingContext?.Active == false)
|
||||
{
|
||||
await TextReply("TGS: The server is rebooting, please try again later");
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandHandler.AdminOnly && !message.User.Channel.IsAdminChannel)
|
||||
{
|
||||
await SendMessage(
|
||||
new List<ulong> { message.User.Channel.RealId },
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = "Use this command in an admin channel!",
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply("TGS: Use this command in an admin channel!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -912,14 +886,7 @@ namespace Tgstation.Server.Host.Components.Chat
|
||||
{
|
||||
// error bc custom commands should reply about why it failed
|
||||
logger.LogError(e, "Error processing chat command");
|
||||
await SendMessage(
|
||||
new List<ulong> { message.User.Channel.RealId },
|
||||
message,
|
||||
new MessageContent
|
||||
{
|
||||
Text = "TGS: Internal error processing command! Check server logs!",
|
||||
},
|
||||
cancellationToken);
|
||||
await TextReply("TGS: Internal error processing command! Check server logs!");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -119,11 +119,6 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
/// </summary>
|
||||
void ResetRebootState();
|
||||
|
||||
/// <summary>
|
||||
/// Enables the reading of custom chat commands from the <see cref="ISessionController"/>.
|
||||
/// </summary>
|
||||
void EnableCustomChatCommands();
|
||||
|
||||
/// <summary>
|
||||
/// Replace the <see cref="IDmbProvider"/> in use with a given <paramref name="newProvider"/>, disposing the old one.
|
||||
/// </summary>
|
||||
|
||||
@@ -401,9 +401,6 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void EnableCustomChatCommands() => chatTrackingContext.Active = DMApiAvailable;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValueTask Release()
|
||||
{
|
||||
@@ -751,6 +748,7 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
break;
|
||||
case BridgeCommandType.Kill:
|
||||
Logger.LogInformation("Bridge requested process termination!");
|
||||
chatTrackingContext.Active = false;
|
||||
TerminationWasRequested = true;
|
||||
process.Terminate();
|
||||
break;
|
||||
@@ -839,15 +837,17 @@ namespace Tgstation.Server.Host.Components.Session
|
||||
|
||||
// Load custom commands
|
||||
chatTrackingContext.CustomCommands = parameters.CustomCommands;
|
||||
chatTrackingContext.Active = true;
|
||||
Interlocked.Exchange(ref startupTcs, new TaskCompletionSource()).SetResult();
|
||||
break;
|
||||
case BridgeCommandType.Reboot:
|
||||
Interlocked.Increment(ref rebootBridgeRequestsProcessing);
|
||||
try
|
||||
{
|
||||
chatTrackingContext.Active = false;
|
||||
|
||||
if (ClosePortOnReboot)
|
||||
{
|
||||
chatTrackingContext.Active = false;
|
||||
response.NewPort = 0;
|
||||
portClosedForReboot = true;
|
||||
}
|
||||
|
||||
@@ -256,8 +256,6 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
await SessionStartupPersist(cancellationToken);
|
||||
|
||||
await CheckLaunchResult(Server, "Server", cancellationToken);
|
||||
|
||||
Server.EnableCustomChatCommands();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user