Cleanup, ordering and added host variable to client script

This commit is contained in:
Michael Chen
2022-01-16 22:29:50 +01:00
parent 612435eb09
commit fd3e6fdcc8
17 changed files with 237 additions and 206 deletions

View 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; }
}

View 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();
}
}

View 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);
}