using Discord; using Discord.WebSocket; using System.Reflection; namespace MinecraftDiscordBot; public abstract class CommandRouter : ICommandHandler { private readonly Dictionary> _handlers = new(); public CommandRouter() { foreach (var method in GetType().GetMethods()) if (GetHandlerAttribute(method) is CommandHandlerAttribute handler) try { _handlers.Add(handler.CommandName, method.CreateDelegate>(this)); } catch (Exception) { Program.LogWarning("CommandRouter", $"Could not add delegate for method {handler.CommandName} in function {method.ReturnType} {method.Name}(...)!"); throw; } } private static CommandHandlerAttribute? GetHandlerAttribute(MethodInfo method) => method.GetCustomAttributes(typeof(CommandHandlerAttribute), true).OfType().FirstOrDefault(); public abstract Task RootAnswer(SocketUserMessage message, CancellationToken ct); public abstract Task FallbackHandler(SocketUserMessage message, string method, string[] parameters, CancellationToken ct); public Task HandleCommand(SocketUserMessage message, string[] parameters, CancellationToken ct) => parameters is { Length: 0 } ? RootAnswer(message, ct) : _handlers.TryGetValue(parameters[0], out var handler) ? handler(message, parameters[1..], ct) : FallbackHandler(message, parameters[0], parameters[1..], ct); }