mcdiscordbot/MinecraftDiscordBot/Commands/CommandRouter.cs
Michael Chen 9fd50ee01e
server:
Fixed cli help texts
Added administrator options for critical methods
Added result state for client and server specific errors
Redirect root to help text
Fixed fingerprint error, fingerprint must be case sensitive
Re-Added online messages
Added typing trigger for discord bot messages
client:
fixed chunkString for empty results preemtive
wrap error objects for server messages
both:
added raw lua RS Bridge command entry
2022-01-17 15:25:03 +01:00

46 lines
2.5 KiB
C#

using Discord.WebSocket;
using MinecraftDiscordBot.Services;
using System.Reflection;
using System.Text;
namespace MinecraftDiscordBot.Commands;
public abstract class CommandRouter : ICommandHandler<ResponseType> {
public record struct HandlerStruct(HandleCommandDelegate<ResponseType> Delegate, CommandHandlerAttribute Attribute);
private readonly Dictionary<string, HandlerStruct> _handlers = new();
public abstract string HelpTextPrefix { get; }
public CommandRouter() {
foreach (var method in GetType().GetMethods())
if (GetHandlerAttribute(method) is CommandHandlerAttribute attribute)
try {
_handlers.Add(attribute.CommandName, new(method.CreateDelegate<HandleCommandDelegate<ResponseType>>(this), attribute));
} catch (Exception) {
Program.LogWarning("CommandRouter", $"Could not add delegate for method {attribute.CommandName} in function {method.ReturnType} {method.Name}(...)!");
throw;
}
}
[CommandHandler("help", HelpText = "Show this help information!")]
public virtual Task<ResponseType> GetHelpText(SocketUserMessage message, string[] parameters, CancellationToken ct)
=> Task.FromResult(ResponseType.AsString(GenerateHelp()));
private static CommandHandlerAttribute? GetHandlerAttribute(MethodInfo method)
=> method.GetCustomAttributes(typeof(CommandHandlerAttribute), true).OfType<CommandHandlerAttribute>().FirstOrDefault();
public virtual Task<ResponseType> RootAnswer(SocketUserMessage message, CancellationToken ct) => GetHelpText(message, Array.Empty<string>(), ct);
public abstract Task<ResponseType> FallbackHandler(SocketUserMessage message, string method, string[] parameters, CancellationToken ct);
public Task<ResponseType> HandleCommand(SocketUserMessage message, string[] parameters, CancellationToken ct)
=> parameters is { Length: 0 }
? RootAnswer(message, ct)
: _handlers.TryGetValue(parameters[0], out var handler)
? handler.Delegate(message, parameters[1..], ct)
: FallbackHandler(message, parameters[0], parameters[1..], ct);
private string GenerateHelp() {
var sb = new StringBuilder();
sb.Append("Command usage:");
foreach (var (name, handler) in _handlers) {
sb.Append($"\n{HelpTextPrefix}{name}");
if (handler.Attribute.HelpText is string help)
sb.Append($": {help}");
}
return sb.ToString();
}
}