From d315a9d3146384735877c8137435c22125efd2d2 Mon Sep 17 00:00:00 2001 From: Hsu Still <341464@gmail.com> Date: Wed, 27 Sep 2017 04:35:21 +0800 Subject: [PATCH] Update line breaks to comply with docs standard --- docs/guides/commands/commands.md | 312 +++++++++++++++++++------------ 1 file changed, 197 insertions(+), 115 deletions(-) diff --git a/docs/guides/commands/commands.md b/docs/guides/commands/commands.md index 0ac21c2a2..20bba6631 100644 --- a/docs/guides/commands/commands.md +++ b/docs/guides/commands/commands.md @@ -1,209 +1,285 @@ -# The Command Service +# The Command Service >[!WARNING] ->This article is out of date and has not been rewritten yet. -Information is not guaranteed to be accurate. +>This article is out of date and has not been rewritten yet. +Information is not guaranteed to be accurate. -[Discord.Commands](xref:Discord.Commands) provides an Attribute-based command parser. +[Discord.Commands](xref:Discord.Commands) provides an Attribute-based +command parser. -## Setup +## Setup -To use Commands, you must create a [Commands Service] and a Command Handler. +To use Commands, you must create a [Commands Service] and a Command +Handler. -Included below is a very barebone Command Handler. You can extend your Command Handler as much as you like; however, the below is the bare minimum. +Included below is a very barebone Command Handler. You can extend your +Command Handler as much as you like; however, the below is the bare +minimum. -The `CommandService` will optionally accept a [CommandServiceConfig], which _does_ set a few default values for you. It is recommended to look over the properties in [CommandServiceConfig] and their default values. +The `CommandService` will optionally accept a [CommandServiceConfig], +which _does_ set a few default values for you. It is recommended to +look over the properties in [CommandServiceConfig] and their default +values. -[!code-csharp[Command Handler](samples/command_handler.cs)] +[!code-csharp[Command Handler](samples/command_handler.cs)] -[Command Service]: xref:Discord.Commands.CommandService -[CommandServiceConfig]: xref:Discord.Commands.CommandServiceConfig +[Command Service]: xref:Discord.Commands.CommandService +[CommandServiceConfig]: xref:Discord.Commands.CommandServiceConfig -## With Attributes +## With Attributes -In 1.0, Commands can be defined ahead of time with attributes, or at runtime with builders. +In 1.0, Commands can be defined ahead of time with attributes, or at +runtime with builders. -For most bots, ahead-of-time Commands should be all you need, and this is the recommended method of defining Commands. +For most bots, ahead-of-time Commands should be all you need, and this +is the recommended method of defining Commands. -### Modules +### Modules -The first step to creating Commands is to create a _module_. +The first step to creating Commands is to create a _module_. -A Module is an organizational pattern that allows you to write your Commands in different classes and have them automatically loaded. +A Module is an organizational pattern that allows you to write your +Commands in different classes and have them automatically loaded. -Discord.NET's implementation of Modules is influenced heavily from ASP.NET Core's Controller pattern. This means that the lifetime of a module instance is only as long as the Command is being invoked. +Discord.NET's implementation of Modules is influenced heavily from +ASP.NET Core's Controller pattern. This means that the lifetime of a +module instance is only as long as the Command is being invoked. -**Avoid using long-running code** in your modules wherever possible. You should **not** be implementing very much logic into your modules; you should outsource to a service for that. +**Avoid using long-running code** in your modules wherever possible. +You should **not** be implementing very much logic into your modules; +you should outsource to a service for that. -If you are unfamiliar with Inversion of Control, it is recommended to read the MSDN article on [IoC] and [Dependency Injection]. +If you are unfamiliar with Inversion of Control, it is recommended to +read the MSDN article on [IoC] and [Dependency Injection]. -To begin, create a new class somewhere in your project and inherit the class from [ModuleBase]. This class **must** be `public`. +To begin, create a new class somewhere in your project and inherit the +class from [ModuleBase]. This class **must** be `public`. ->[!NOTE] ->[ModuleBase] is an _abstract_ class, meaning that you may extend it ->or override it as you see fit. Your module may inherit from any ->extension of ModuleBase. +>[!NOTE] +>[ModuleBase] is an _abstract_ class, meaning that you may extend it +>or override it as you see fit. Your module may inherit from any +>extension of ModuleBase. -By now, your module should look like this: -[!code-csharp[Empty Module](samples/empty-module.cs)] +By now, your module should look like this: +[!code-csharp[Empty Module](samples/empty-module.cs)] -[IoC]: https://msdn.microsoft.com/en-us/library/ff921087.aspx -[Dependency Injection]: https://msdn.microsoft.com/en-us/library/ff921152.aspx -[ModuleBase]: xref:Discord.Commands.ModuleBase`1 +[IoC]: https://msdn.microsoft.com/en-us/library/ff921087.aspx +[Dependency Injection]: https://msdn.microsoft.com/en-us/library/ff921152.aspx +[ModuleBase]: xref:Discord.Commands.ModuleBase`1 -### Adding Commands +### Adding Commands -The next step to creating Commands is actually creating the Commands. +The next step to creating Commands is actually creating the Commands. -To create a Command, add a method to your module of type `Task`. Typically, you will want to mark this method as `async`, although it is not required. +To create a Command, add a method to your module of type `Task`. +Typically, you will want to mark this method as `async`, although it +is not required. -Adding parameters to a Command is done by adding parameters to the parent Task. +Adding parameters to a Command is done by adding parameters to the +parent Task. -For example, to take an integer as an argument from the user, add `int arg`; to take a user as an argument from the user, add `IUser user`. In 1.0, a Command can accept nearly any type of argument; a full list of types that are parsed by default can be found in the below section on _Type Readers_. +For example, to take an integer as an argument from the user, add `int +arg`; to take a user as an argument from the user, add `IUser user`. +In 1.0, a Command can accept nearly any type of argument; a full list +of types that are parsed by default can be found in the below section +on _Type Readers_. -Parameters, by default, are always required. To make a parameter optional, give it a default value. To accept a comma-separated list, set the parameter to `params Type[]`. +Parameters, by default, are always required. To make a parameter +optional, give it a default value. To accept a comma-separated list, +set the parameter to `params Type[]`. -Should a parameter include spaces, it **must** be wrapped in quotes. For example, for a Command with a parameter `string food`, you would execute it with `!favoritefood "Key Lime Pie"`. +Should a parameter include spaces, it **must** be wrapped in quotes. +For example, for a Command with a parameter `string food`, you would +execute it with `!favoritefood "Key Lime Pie"`. -If you would like a parameter to parse until the end of a Command, flag the parameter with the [RemainderAttribute]. This will allow a user to invoke a Command without wrapping a parameter in quotes. +If you would like a parameter to parse until the end of a Command, +flag the parameter with the [RemainderAttribute]. This will allow a +user to invoke a Command without wrapping a parameter in quotes. -Finally, flag your Command with the [CommandAttribute] (you must specify a name for this Command, except for when it is part of a Module Group - see below). +Finally, flag your Command with the [CommandAttribute] (you must +specify a name for this Command, except for when it is part of a +Module Group - see below). -[RemainderAttribute]: xref:Discord.Commands.RemainderAttribute -[CommandAttribute]: xref:Discord.Commands.CommandAttribute +[RemainderAttribute]: xref:Discord.Commands.RemainderAttribute +[CommandAttribute]: xref:Discord.Commands.CommandAttribute -### Command Overloads +### Command Overloads -You may add overloads to your Commands, and the Command parser will automatically pick up on it. +You may add overloads to your Commands, and the Command parser will +automatically pick up on it. -If for whatever reason, you have two Commands which are ambiguous to each other, you may use the @Discord.Commands.PriorityAttribute to specify which should be tested before the other. +If for whatever reason, you have two Commands which are ambiguous to +each other, you may use the @Discord.Commands.PriorityAttribute to +specify which should be tested before the other. -The `Priority` attributes are sorted in ascending order; the higher priority will be called first. +The `Priority` attributes are sorted in ascending order; the higher +priority will be called first. -### Command Context +### Command Context -Every Command can access the execution context through the [Context] property on [ModuleBase]. `ICommandContext` allows you to access the message, channel, guild, and user that the Command was invoked from, as well as the underlying Discord client that the Command was invoked from. +Every Command can access the execution context through the [Context] +property on [ModuleBase]. `ICommandContext` allows you to access the +message, channel, guild, and user that the Command was invoked from, +as well as the underlying Discord client that the Command was invoked +from. -Different types of Contexts may be specified using the generic variant of [ModuleBase]. When using a [SocketCommandContext], for example, the properties on this context will already be Socket entities, so you will not need to cast them. +Different types of Contexts may be specified using the generic variant +of [ModuleBase]. When using a [SocketCommandContext], for example, the +properties on this context will already be Socket entities, so you +will not need to cast them. -To reply to messages, you may also invoke [ReplyAsync], instead of accessing the channel through the [Context] and sending a message. +To reply to messages, you may also invoke [ReplyAsync], instead of +accessing the channel through the [Context] and sending a message. [Context]: xref:Discord.Commands.ModuleBase`1#Discord_Commands_ModuleBase_1_Context -[SocketCommandContext]: xref:Discord.Commands.SocketCommandContext +[SocketCommandContext]: xref:Discord.Commands.SocketCommandContext ->![WARNING] ->Contexts should **NOT** be mixed! You cannot have one module that ->uses CommandContext and another that uses SocketCommandContext. +>![WARNING] +>Contexts should **NOT** be mixed! You cannot have one module that +>uses CommandContext and another that uses SocketCommandContext. -### Example Module +### Example Module -At this point, your module should look comparable to this example: -[!code-csharp[Example Module](samples/module.cs)] +At this point, your module should look comparable to this example: +[!code-csharp[Example Module](samples/module.cs)] -#### Loading Modules Automatically +#### Loading Modules Automatically -The Command Service can automatically discover all classes in an Assembly that inherits [ModuleBase] and load them. +The Command Service can automatically discover all classes in an +Assembly that inherits [ModuleBase] and load them. -To opt a module out of auto-loading, flag it with [DontAutoLoadAttribute]. +To opt a module out of auto-loading, flag it with +[DontAutoLoadAttribute]. -Invoke [CommandService.AddModulesAsync] to discover modules and install them. +Invoke [CommandService.AddModulesAsync] to discover modules and +install them. -[DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute -[CommandService.AddModulesAsync]: xref:Discord_Commands_CommandService#Discord_Commands_CommandService_AddModulesAsync_Assembly_ +[DontAutoLoadAttribute]: xref:Discord.Commands.DontAutoLoadAttribute +[CommandService.AddModulesAsync]: xref:Discord_Commands_CommandService#Discord_Commands_CommandService_AddModulesAsync_Assembly_ -#### Loading Modules Manually +#### Loading Modules Manually -To manually load a module, invoke [CommandService.AddModuleAsync], by passing in the generic type of your module and optionally, a dependency map. +To manually load a module, invoke [CommandService.AddModuleAsync], by +passing in the generic type of your module and optionally, a +dependency map. [CommandService.AddModuleAsync]: xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddModuleAsync__1 -### Module Constructors +### Module Constructors -Modules are constructed using Dependency Injection. Any parameters that are placed in the Module's constructor must be injected into an @System.IServiceProvider first. Alternatively, you may accept an `IServiceProvider` as an argument and extract services yourself. +Modules are constructed using Dependency Injection. Any parameters +that are placed in the Module's constructor must be injected into an +@System.IServiceProvider first. Alternatively, you may accept an +`IServiceProvider` as an argument and extract services yourself. -### Module Properties +### Module Properties -Modules with `public` settable properties will have the dependencies injected after the construction of the Module. +Modules with `public` settable properties will have the dependencies +injected after the construction of the Module. -### Module Groups +### Module Groups -Module Groups allow you to create a module where Commands are prefixed. To create a group, flag a module with the @Discord.Commands.GroupAttribute. +Module Groups allow you to create a module where Commands are +prefixed. To create a group, flag a module with the +@Discord.Commands.GroupAttribute. -Module groups also allow you to create **nameless Commands**, where the [CommandAttribute] is configured with no name. In this case, the Command will inherit the name of the group it belongs to. +Module groups also allow you to create **nameless Commands**, where +the [CommandAttribute] is configured with no name. In this case, the +Command will inherit the name of the group it belongs to. -### Submodules +### Submodules -Submodules are Modules that reside within another one. Typically, submodules are used to create nested groups (although not required to create nested groups). +Submodules are Modules that reside within another one. Typically, +submodules are used to create nested groups (although not required to +create nested groups). -[!code-csharp[Groups and Submodules](samples/groups.cs)] +[!code-csharp[Groups and Submodules](samples/groups.cs)] -## With Builders +## With Builders -**TODO** +**TODO** -## Dependency Injection +## Dependency Injection -The Command Service is bundled with a very barebone Dependency Injection service for your convenience. It is recommended that you use DI when writing your modules. +The Command Service is bundled with a very barebone Dependency +Injection service for your convenience. It is recommended that you use +DI when writing your modules. -### Setup +### Setup -First, you need to create an @System.IServiceProvider; you may create your own one if you wish. +First, you need to create an @System.IServiceProvider; you may create +your own one if you wish. -Next, add the dependencies that your modules will use to the map. +Next, add the dependencies that your modules will use to the map. -Finally, pass the map into the `LoadAssembly` method. Your modules will be automatically loaded with this dependency map. +Finally, pass the map into the `LoadAssembly` method. Your modules +will be automatically loaded with this dependency map. [!code-csharp[IServiceProvider Setup](samples/dependency_map_setup.cs)] -### Usage in Modules +### Usage in Modules -In the constructor of your Module, any parameters will be filled in by the @System.IServiceProvider that you've passed into `LoadAssembly`. +In the constructor of your Module, any parameters will be filled in by +the @System.IServiceProvider that you've passed into `LoadAssembly`. -Any publicly settable properties will also be filled in the same manner. +Any publicly settable properties will also be filled in the same +manner. ->[!NOTE] -> Annotating a property with the [DontInject] attribute will prevent it from being injected. +>[!NOTE] +> Annotating a property with the [DontInject] attribute will +prevent it from being injected. ->[!NOTE] ->If you accept `CommandService` or `IServiceProvider` as a parameter in your constructor, or as an injectable property, these entries will be filled by the `CommandService` that the Module is loaded from, and the `ServiceProvider` that is passed into it respectively. +>[!NOTE] +>If you accept `CommandService` or `IServiceProvider` as a parameter +in your constructor, or as an injectable property, these entries will +be filled by the `CommandService` that the Module is loaded from, and +the `ServiceProvider` that is passed into it respectively. -[!code-csharp[ServiceProvider in Modules](samples/dependency_module.cs)] +[!code-csharp[ServiceProvider in Modules](samples/dependency_module.cs)] -# Preconditions +# Preconditions -Precondition 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. +Precondition 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. +>[!NOTE] +>Preconditions can be applied to Modules, Groups, or Commands. -## Bundled Preconditions +## Bundled Preconditions -Commands ship with four bundled preconditions; you may view their usages on their respective API pages. +Commands ship with four bundled preconditions; you may view their +usages on their respective API pages. - @Discord.Commands.RequireContextAttribute - @Discord.Commands.RequireOwnerAttribute - @Discord.Commands.RequireBotPermissionAttribute - @Discord.Commands.RequireUserPermissionAttribute -## Custom Preconditions +## Custom Preconditions -To write your own precondition, create a new class that inherits from @Discord.Commands.PreconditionAttribute. +To write your own precondition, create a new class that inherits from +@Discord.Commands.PreconditionAttribute. -In order for your precondition to function, you will need to override the [CheckPermissions] method. +In order for your precondition to function, you will need to override +the [CheckPermissions] method. -Your IDE should provide an option to fill this in for you. +Your IDE should provide an option to fill this in for you. -Return [PreconditionResult.FromSuccess] if the context meets the required parameters, otherwise return [PreconditionResult.FromError] and optionally include an error message. +Return [PreconditionResult.FromSuccess] if the context meets the +required parameters, otherwise return [PreconditionResult.FromError] +and optionally include an error message. -[!code-csharp[Custom Precondition](samples/require_owner.cs)] +[!code-csharp[Custom Precondition](samples/require_owner.cs)] [CheckPermissions]: xref:Discord.Commands.PreconditionAttribute#Discord_Commands_PreconditionAttribute_CheckPermissions_Discord_Commands_CommandContext_Discord_Commands_CommandInfo_Discord_Commands_IDependencyMap_ [PreconditionResult.FromSuccess]: xref:Discord.Commands.PreconditionResult#Discord_Commands_PreconditionResult_FromSuccess [PreconditionResult.FromError]: xref:Discord.Commands.PreconditionResult#Discord_Commands_PreconditionResult_FromError_System_String_ -# Type Readers +# 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. By default, the following Types are supported arguments: @@ -221,29 +297,35 @@ By default, the following Types are supported arguments: - IUser/IGuildUser/IGroupUser - IRole -### Creating a Type Readers +### Creating a Type Readers -To create a `TypeReader`, create a new class that imports @Discord and @Discord.Commands and ensure the class inherits from @Discord.Commands.TypeReader. +To create a `TypeReader`, create a new class that imports @Discord and +@Discord.Commands and ensure the class inherits from +@Discord.Commands.TypeReader. -Next, satisfy the `TypeReader` class by overriding the [Read] method. +Next, satisfy the `TypeReader` class by overriding the [Read] method. >[!NOTE] ->In many cases, Visual Studio can fill this in for you using the +>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. -Finally, return a `TypeReaderResult`. If you were able to successfully -parse the input, return `TypeReaderResult.FromSuccess(parsedInput)`, otherwise, return `TypeReaderResult.FromError` and optionally include an error message. +Finally, return a `TypeReaderResult`. If you were able to successfully +parse the input, return `TypeReaderResult.FromSuccess(parsedInput)`, +otherwise, return `TypeReaderResult.FromError` and optionally include +an error message. [Read]: xref:Discord.Commands.TypeReader#Discord_Commands_TypeReader_Read_Discord_Commands_CommandContext_System_String_ -#### Sample +#### Sample -[!code-csharp[TypeReaders](samples/typereader.cs)] +[!code-csharp[TypeReaders](samples/typereader.cs)] -### Installing TypeReaders +### Installing TypeReaders -TypeReaders are not automatically discovered by the Command Service and must be explicitly added. +TypeReaders are not automatically discovered by the Command Service +and must be explicitly added. To install a TypeReader, invoke [CommandService.AddTypeReader](xref:Discord.Commands.CommandService#Discord_Commands_CommandService_AddTypeReader__1_Discord_Commands_TypeReader_).