Add documentation for Preconditions, Aliases, Command Structure
Resolves #223
This commit is contained in:
@@ -10,6 +10,23 @@ Included below is a very bare-bones Command Handler. You can extend your Command
|
||||
|
||||
[!code-csharp[Barebones Command Handler](samples/command_handler.cs)]
|
||||
|
||||
## Commands
|
||||
|
||||
In 1.0, Commands are no longer implemented at runtime with a builder pattern.
|
||||
While a builder pattern may be provided later, commands are created primarily with
|
||||
attributes.
|
||||
|
||||
### Basic Structure
|
||||
|
||||
All commands belong to a Module. (See the below section for creating modules.)
|
||||
|
||||
All commands in a module must be defined as an `Task`, with at least one argument,
|
||||
being the @Discord.IMessage representing the context of the command.
|
||||
|
||||
To add parameters to your command, add additional arguments to the `Task` of the command.
|
||||
You are _not_ required to accept all arguments as `String`, they will be automatically parsed
|
||||
into the type you specify for the arument. See the Example Module for an example of command parameters.
|
||||
|
||||
## Modules
|
||||
|
||||
Modules serve as a host for commands you create.
|
||||
@@ -38,6 +55,12 @@ When automatically loading modules, you are limited in your constructor. Using a
|
||||
|
||||
Alternatively, you can use an @Discord.Commands.IDependencyMap, as shown below.
|
||||
|
||||
### Command Groups
|
||||
|
||||
Command groups function similarly to Modules, but they must be contained inside a module. Simply create a **public** class inside a module, and flag it with the @Discord.Commands.GroupAttribute
|
||||
|
||||
[!code-csharp[Groups Sample](samples/groups.cs)]
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
The Commands Service includes a very basic implementation of Dependency Injection that allows you to have completely custom constructors, within certain limitations.
|
||||
@@ -61,7 +84,56 @@ In the constructor of your module, any parameters will be filled in by the @Disc
|
||||
|
||||
[!code-csharp[DependencyMap in Modules](samples/dependency_module.cs)]
|
||||
|
||||
## Type Readers
|
||||
# Preconditions
|
||||
|
||||
Preconditions serve as a permissions system for your commands. Keep in mind, however, that they are
|
||||
not limited to _just_ permissions, and can be as complex as you want them to be.
|
||||
|
||||
>[!NOTE]
|
||||
>Preconditions can be applied to Modules, Groups, or Commands.
|
||||
|
||||
## Bundled Preconditions
|
||||
|
||||
@Discord.Commands ships with two built-in preconditions, @Discord.Commands.RequireContextAttribute
|
||||
and @Discord.Commands.RequirePermissionAttribute.
|
||||
|
||||
### RequireContext
|
||||
|
||||
@Discord.Commands.RequireContextAttribute is a precondition that requires your command to be
|
||||
executed in the specified context.
|
||||
|
||||
You may require three different types of context:
|
||||
* Guild
|
||||
* DM
|
||||
* Group
|
||||
|
||||
Since these are `Flags`, you may OR them together.
|
||||
|
||||
[!code-csharp[RequireContext](samples/require_context.cs)]
|
||||
|
||||
### RequirePermission
|
||||
|
||||
@Discord.Commands.RequirePermissionAttribute is a precondition that allows you to quickly
|
||||
specfiy that a user must poesess a permission to execute a command.
|
||||
|
||||
You may require either a @Discord.GuildPermission or @Discord.ChannelPermission
|
||||
|
||||
[!code-csharp[RequireContext](samples/require_permission.cs)]
|
||||
|
||||
## Custom Preconditions
|
||||
|
||||
To write your own preconditions, create a new class that inherits from @Discord.Commands.PreconditionAttribute
|
||||
|
||||
In order for your precondition to function, you will need to override `CheckPermissions`,
|
||||
which is a `Task<PreconditionResult>`.
|
||||
Your IDE should provide an option to fill this in for you.
|
||||
|
||||
Return `PreconditionResult.FromSuccess()` if the context met the required parameters, otherwise
|
||||
return `PreconditionResult.FromError()`, optionally including an error message.
|
||||
|
||||
[!code-csharp[Custom Precondition](samples/require_owner.cs)]
|
||||
|
||||
# Type Readers
|
||||
|
||||
Type Readers allow you to parse different types of arguments in your commands.
|
||||
|
||||
@@ -86,7 +158,7 @@ To create a TypeReader, create a new class that imports @Discord and @Discord.Co
|
||||
Next, satisfy the `TypeReader` class by overriding `Task<TypeReaderResult> Read(IMessage context, string input)`.
|
||||
|
||||
>[!NOTE]
|
||||
>In many cases, Visual Stuido can fill this in for you, using the "Implement Abstract Class" IntelliSense hint.
|
||||
>In many cases, Visual Studio can fill this in for you, using the "Implement Abstract Class" IntelliSense hint.
|
||||
|
||||
Inside this task, add whatever logic you need to parse the input string.
|
||||
|
||||
|
||||
15
docs/guides/samples/groups.cs
Normal file
15
docs/guides/samples/groups.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
[Module("admin")]
|
||||
public class AdminModule
|
||||
{
|
||||
[Group("mod")]
|
||||
public class ModerationGroup
|
||||
{
|
||||
// ~admin mod ban foxbot#0282
|
||||
[Command("ban")]
|
||||
public async Task Ban(IMessage msg, IGuildUser user) { }
|
||||
}
|
||||
|
||||
// ~admin clean 100
|
||||
[Command("clean")]
|
||||
public async Task Clean(IMessage msg, int count = 100) { }
|
||||
}
|
||||
@@ -31,7 +31,9 @@ public class Sample
|
||||
// ~sample userinfo Khionu#8708 --> Khionu#8708
|
||||
// ~sample userinfo Khionu --> Khionu#8708
|
||||
// ~sample userinfo 96642168176807936 --> Khionu#8708
|
||||
// ~sample whois 96642168176807936 --> Khionu#8708
|
||||
[Command("userinfo"), Description("Returns info about the current user, or the user parameter, if one passed.")]
|
||||
[Alias("user", "whois")]
|
||||
public async Task UserInfo(IMessage msg,
|
||||
[Description("The (optional) user to get info for")] IUser user = null)
|
||||
{
|
||||
|
||||
11
docs/guides/samples/require_context.cs
Normal file
11
docs/guides/samples/require_context.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
[Module]
|
||||
public class InfoModule
|
||||
{
|
||||
// Constrain this command to Guilds
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Whois(IMessage msg, IGuildUser user) { }
|
||||
|
||||
// Constrain this command to either Guilds or DMs
|
||||
[RequireContext(ContextType.Guild | ContextType.DM)]
|
||||
public async Task Info(IMessage msg) { }
|
||||
}
|
||||
16
docs/guides/samples/require_owner.cs
Normal file
16
docs/guides/samples/require_owner.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
// Defining the Precondition
|
||||
|
||||
// Specify that this precondition can target a Class (Module/Group) or Method (Command)
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
// Inherit from PreconditionAttribute
|
||||
public class RequireOwnerAttribute : PreconditionAttribute
|
||||
{
|
||||
public readonly ulong OwnerId = 66078337084162048;
|
||||
|
||||
// Override the CheckPermissions method
|
||||
public override Task<PreconditionResult> CheckPermissions(IMessage context, Command executingCommand, object moduleInstance)
|
||||
{
|
||||
// If the author of the message is '66078337084162048', return success; otherwise fail.
|
||||
return Task.FromResult(context.Author.Id == OwnerId ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("You must be the owner of the bot."));
|
||||
}
|
||||
}
|
||||
7
docs/guides/samples/require_permission.cs
Normal file
7
docs/guides/samples/require_permission.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
[Module]
|
||||
public class AdminModule
|
||||
{
|
||||
[Command("ban")]
|
||||
[RequirePermission(GuildPermission.BanMembers)]
|
||||
public async Task Ban(IMessage msg) { }
|
||||
}
|
||||
Reference in New Issue
Block a user