Cleanup, ordering and added host variable to client script
This commit is contained in:
8
MinecraftDiscordBot/Commands/CommandHandlerAttribute.cs
Normal file
8
MinecraftDiscordBot/Commands/CommandHandlerAttribute.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace MinecraftDiscordBot.Commands;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
|
||||
public sealed class CommandHandlerAttribute : Attribute {
|
||||
public CommandHandlerAttribute(string commandName) => CommandName = commandName;
|
||||
public string CommandName { get; }
|
||||
public string? HelpText { get; init; }
|
||||
}
|
46
MinecraftDiscordBot/Commands/CommandRouter.cs
Normal file
46
MinecraftDiscordBot/Commands/CommandRouter.cs
Normal file
@ -0,0 +1,46 @@
|
||||
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();
|
||||
}
|
||||
}
|
11
MinecraftDiscordBot/Commands/ICommandHandler.cs
Normal file
11
MinecraftDiscordBot/Commands/ICommandHandler.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Discord.WebSocket;
|
||||
|
||||
namespace MinecraftDiscordBot.Commands;
|
||||
|
||||
public interface ICommandHandler {
|
||||
Task HandleCommand(SocketUserMessage message, string[] parameters, CancellationToken ct);
|
||||
}
|
||||
|
||||
public interface ICommandHandler<T> {
|
||||
Task<T> HandleCommand(SocketUserMessage message, string[] parameters, CancellationToken ct);
|
||||
}
|
Reference in New Issue
Block a user