46 lines
2.5 KiB
C#
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 abstract Task<ResponseType> RootAnswer(SocketUserMessage message, CancellationToken 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();
|
|
}
|
|
} |