Browse Source

Add documentation for Preconditions, Aliases, Command Structure

Resolves #223
tags/1.0-rc
Christopher F 8 years ago
parent
commit
4e636f732d
6 changed files with 125 additions and 2 deletions
  1. +74
    -2
      docs/guides/commands.md
  2. +15
    -0
      docs/guides/samples/groups.cs
  3. +2
    -0
      docs/guides/samples/module.cs
  4. +11
    -0
      docs/guides/samples/require_context.cs
  5. +16
    -0
      docs/guides/samples/require_owner.cs
  6. +7
    -0
      docs/guides/samples/require_permission.cs

+ 74
- 2
docs/guides/commands.md View File

@@ -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)] [!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


Modules serve as a host for commands you create. 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. 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 ## Dependency Injection


The Commands Service includes a very basic implementation of Dependency Injection that allows you to have completely custom constructors, within certain limitations. 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)] [!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. 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)`. Next, satisfy the `TypeReader` class by overriding `Task<TypeReaderResult> Read(IMessage context, string input)`.


>[!NOTE] >[!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. Inside this task, add whatever logic you need to parse the input string.




+ 15
- 0
docs/guides/samples/groups.cs View 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) { }
}

+ 2
- 0
docs/guides/samples/module.cs View File

@@ -31,7 +31,9 @@ public class Sample
// ~sample userinfo Khionu#8708 --> Khionu#8708 // ~sample userinfo Khionu#8708 --> Khionu#8708
// ~sample userinfo Khionu --> Khionu#8708 // ~sample userinfo Khionu --> Khionu#8708
// ~sample userinfo 96642168176807936 --> 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.")] [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, public async Task UserInfo(IMessage msg,
[Description("The (optional) user to get info for")] IUser user = null) [Description("The (optional) user to get info for")] IUser user = null)
{ {


+ 11
- 0
docs/guides/samples/require_context.cs View 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
- 0
docs/guides/samples/require_owner.cs View 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
- 0
docs/guides/samples/require_permission.cs View File

@@ -0,0 +1,7 @@
[Module]
public class AdminModule
{
[Command("ban")]
[RequirePermission(GuildPermission.BanMembers)]
public async Task Ban(IMessage msg) { }
}

Loading…
Cancel
Save