An asynchronous platform-independent .NET Standard 2.0 and .NET Core 2.1-2.2 command framework that can be used with any input source, whether that be Discord messages, IRC, or a terminal.
Inspired by Discord.Net.Commands and DSharpPlus.CommandsNext.
Stable Qmmands builds can be pulled from NuGet.
For nightly builds add https://www.myget.org/F/quahu/api/v3/index.json (the nightly feed) to your project's package sources.
- Advanced parameter parsing support (including custom type parsers, optional parameters, and remainder support)
- Support for returning custom
CommandResultimplementations for advanced post-execution handling - Command module discovery via assembly crawling for valid types
- Support for adding custom modules and commands at runtime with builders or types
- Built-in (optional) command cooldown system with support for custom cooldown types
There's currently no official documentation for Qmmands other than the community projects below and the bundled XML docstrings. For support you should hop in my Discord guild:
- Kiritsu's Discord bot: FoxBot (DSharpPlus)
- GreemDev's Discord bot: Volte (DSharpPlus)
- TheCasino's Discord bot: Espeon (Discord.Net)
- BlowaXD's Nostale Server Emulator: SaltyEmu
CommandHandler.cs
privatereadonlyCommandService_service=newCommandService();// Imagine this being a message callback, whether it be from an IRC bot,// a Discord bot, or any other chat based service.privateasyncTaskMessageReceivedAsync(Messagemessage){if(!CommandUtilities.HasPrefix(message.Content,'!',outstringoutput))return;IResultresult=await_service.ExecuteAsync(output,newCustomCommandContext(message));if(resultisFailedResultfailedResult)awaitmessage.Channel.SendMessageAsync(failedResult.Reason);}CustomCommandContext.cs
publicsealedclassCustomCommandContext:CommandContext{publicMessageMessage{get;}publicChannelChannel=>Message.Channel;publicCustomCommandContext(Messagemessage)=>Message=message;}CommandModule.cs
publicsealedclassCommandModule:ModuleBase<CustomCommandContext>{// Dependency Injection via a constructor or public settable properties.// CommandService and IServiceProvider self-inject into modules,// properties and other types are requested from the provided IServiceProviderpublicCommandServiceService{get;set;}// Invoked with: !help// Responds with: `help` - Lists available commands.// `sum` - Sums two given numbers.// `echo` - Echoes given text.[Command("help","commands")][Description("Lists available commands.")]publicTaskHelpAsync()=>Context.Channel.SendMessageAsync(string.Join('\n',Service.GetAllCommands().Select(x =>$"`{x.Name}` - {x.Description}")));// Invoked with: !sum 3 5// Responds with: 3 + 5 = 8[Command("sum")][Description("Sums two given numbers.")]publicTaskSumAsync(intfirstNumber,intsecondNumber)=>Context.Channel.SendMessageAsync($"{firstNumber} + {secondNumber} = {firstNumber+secondNumber}");// Invoked with: !echo Hello, world.// Responds with: Hello, world.[Command("echo")][Description("Echoes given text.")]publicTaskEchoAsync([Remainder]stringtext)=>Context.Channel.SendMessageAsync(text);}