Add a way to lookup all bot commands in the bot assembly without using the commandService provided by discord.net
This commit is contained in:
parent
ae1b28ff77
commit
4f4e16d674
3 changed files with 106 additions and 0 deletions
11
src/Core/BotCommandLookup/CommandInfo.cs
Normal file
11
src/Core/BotCommandLookup/CommandInfo.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Geekbot.Core.BotCommandLookup;
|
||||
|
||||
public struct CommandInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Dictionary<string, ParameterInfo> Parameters { get; set; }
|
||||
public List<string> Aliases { get; set; }
|
||||
public string Summary { get; set; }
|
||||
}
|
87
src/Core/BotCommandLookup/CommandLookup.cs
Normal file
87
src/Core/BotCommandLookup/CommandLookup.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Discord.Commands;
|
||||
|
||||
namespace Geekbot.Core.BotCommandLookup;
|
||||
|
||||
public class CommandLookup
|
||||
{
|
||||
private readonly Assembly _assembly;
|
||||
|
||||
public CommandLookup(Assembly assembly)
|
||||
{
|
||||
_assembly = assembly;
|
||||
}
|
||||
|
||||
public List<CommandInfo> GetCommands()
|
||||
{
|
||||
var commands = SearchCommands(_assembly);
|
||||
var result = new List<CommandInfo>();
|
||||
commands.ForEach(x => GetCommandDefinition(ref result, x));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<TypeInfo> SearchCommands(Assembly assembly)
|
||||
{
|
||||
bool IsLoadableModule(TypeInfo info) => info.DeclaredMethods.Any(x => x.GetCustomAttribute<CommandAttribute>() != null || x.GetCustomAttribute<GroupAttribute>() != null);
|
||||
return assembly
|
||||
.DefinedTypes
|
||||
.Where(typeInfo => typeInfo.IsPublic || typeInfo.IsNestedPublic)
|
||||
.Where(IsLoadableModule)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private void GetCommandDefinition(ref List<CommandInfo> commandInfos, TypeInfo commandType)
|
||||
{
|
||||
var methods = commandType
|
||||
.GetMethods()
|
||||
.Where(x => x.GetCustomAttribute<CommandAttribute>() != null)
|
||||
.ToList();
|
||||
|
||||
var commandGroup = (commandType.GetCustomAttributes().FirstOrDefault(attr => attr is GroupAttribute) as GroupAttribute)?.Prefix;
|
||||
|
||||
foreach (var command in methods)
|
||||
{
|
||||
var commandInfo = new CommandInfo()
|
||||
{
|
||||
Parameters = new Dictionary<string, ParameterInfo>(),
|
||||
};
|
||||
|
||||
foreach (var attr in command.GetCustomAttributes())
|
||||
{
|
||||
|
||||
switch (attr)
|
||||
{
|
||||
case SummaryAttribute name:
|
||||
commandInfo.Summary = name.Text;
|
||||
break;
|
||||
case CommandAttribute name:
|
||||
commandInfo.Name = string.IsNullOrEmpty(commandGroup) ? name.Text : $"{commandGroup} {name.Text}";
|
||||
break;
|
||||
case AliasAttribute name:
|
||||
commandInfo.Aliases = name.Aliases.ToList() ?? new List<string>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var param in command.GetParameters())
|
||||
{
|
||||
var paramName = param.Name ?? string.Empty;
|
||||
var paramInfo = new ParameterInfo()
|
||||
{
|
||||
Summary = param.GetCustomAttribute<SummaryAttribute>()?.Text ?? string.Empty,
|
||||
Type = param.ParameterType.Name,
|
||||
DefaultValue = param.DefaultValue?.ToString() ?? string.Empty
|
||||
};
|
||||
commandInfo.Parameters.Add(paramName, paramInfo);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(commandInfo.Name))
|
||||
{
|
||||
commandInfos.Add(commandInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
8
src/Core/BotCommandLookup/ParameterInfo.cs
Normal file
8
src/Core/BotCommandLookup/ParameterInfo.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Geekbot.Core.BotCommandLookup;
|
||||
|
||||
public struct ParameterInfo
|
||||
{
|
||||
public string Summary { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string DefaultValue { get; set; }
|
||||
}
|
Loading…
Reference in a new issue