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)]

## 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
- 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 --> 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
- 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