| @@ -11,6 +11,22 @@ using Discord.Logging; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| /// <summary> | |||||
| /// Provides a framework for building Discord commands. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// <para> | |||||
| /// The service provides a framework for building Discord commands both dynamically via runtime builders or | |||||
| /// statically via compile-time modules. To create a command module at compile-time, see | |||||
| /// <see cref="ModuleBase" /> (most common); otherwise, see <see cref="ModuleBuilder" />. | |||||
| /// </para> | |||||
| /// <para> | |||||
| /// This service also provides several events for monitoring command usages; such as | |||||
| /// <see cref="Discord.Commands.CommandService.Log" /> for any command-related log events, and | |||||
| /// <see cref="Discord.Commands.CommandService.CommandExecuted" /> for information about commands that have | |||||
| /// been successfully executed. | |||||
| /// </para> | |||||
| /// </remarks> | |||||
| public class CommandService | public class CommandService | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| @@ -20,8 +36,19 @@ namespace Discord.Commands | |||||
| internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); | internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); | ||||
| /// <summary> | /// <summary> | ||||
| /// Occurs when a command is successfully executed without any runtime error. | |||||
| /// Occurs when a command is successfully executed without any error. | |||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | |||||
| /// <para> | |||||
| /// This event is fired when a command has been successfully executed without any of the following errors: | |||||
| /// </para> | |||||
| /// <para>* Parsing error</para> | |||||
| /// <para>* Precondition error</para> | |||||
| /// <para>* Runtime exception</para> | |||||
| /// <para> | |||||
| /// Should the command encounter any of the aforementioned error, this event will not be raised. | |||||
| /// </para> | |||||
| /// </remarks> | |||||
| public event Func<CommandInfo, ICommandContext, IResult, Task> CommandExecuted { add { _commandExecutedEvent.Add(value); } remove { _commandExecutedEvent.Remove(value); } } | public event Func<CommandInfo, ICommandContext, IResult, Task> CommandExecuted { add { _commandExecutedEvent.Add(value); } remove { _commandExecutedEvent.Remove(value); } } | ||||
| internal readonly AsyncEvent<Func<CommandInfo, ICommandContext, IResult, Task>> _commandExecutedEvent = new AsyncEvent<Func<CommandInfo, ICommandContext, IResult, Task>>(); | internal readonly AsyncEvent<Func<CommandInfo, ICommandContext, IResult, Task>> _commandExecutedEvent = new AsyncEvent<Func<CommandInfo, ICommandContext, IResult, Task>>(); | ||||
| @@ -132,8 +159,14 @@ namespace Discord.Commands | |||||
| /// <summary> | /// <summary> | ||||
| /// Add a command module from a <see cref="Type" /> . | /// Add a command module from a <see cref="Type" /> . | ||||
| /// </summary> | /// </summary> | ||||
| /// <example> | |||||
| /// <para>The following example registers the module <c>MyModule</c> to <c>commandService</c>.</para> | |||||
| /// <code language="cs"> | |||||
| /// await commandService.AddModuleAsync<MyModule>(serviceProvider); | |||||
| /// </code> | |||||
| /// </example> | |||||
| /// <typeparam name="T">The type of module.</typeparam> | /// <typeparam name="T">The type of module.</typeparam> | ||||
| /// <param name="services">The <see cref="IServiceProvider" /> for your dependency injection solution if using one; otherwise, pass <c>null</c> .</param> | |||||
| /// <param name="services">The <see cref="IServiceProvider"/> for your dependency injection solution if using one; otherwise, pass <c>null</c>.</param> | |||||
| /// <exception cref="ArgumentException">This module has already been added.</exception> | /// <exception cref="ArgumentException">This module has already been added.</exception> | ||||
| /// <exception cref="InvalidOperationException"> | /// <exception cref="InvalidOperationException"> | ||||
| /// The <see cref="ModuleInfo"/> fails to be built; an invalid type may have been provided. | /// The <see cref="ModuleInfo"/> fails to be built; an invalid type may have been provided. | ||||
| @@ -145,7 +178,7 @@ namespace Discord.Commands | |||||
| public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services); | public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services); | ||||
| /// <summary> | /// <summary> | ||||
| /// Adds a command module from a <see cref="Type" /> . | |||||
| /// Adds a command module from a <see cref="Type" />. | |||||
| /// </summary> | /// </summary> | ||||
| /// <param name="type">The type of module.</param> | /// <param name="type">The type of module.</param> | ||||
| /// <param name="services">The <see cref="IServiceProvider" /> for your dependency injection solution if using one; otherwise, pass <c>null</c> .</param> | /// <param name="services">The <see cref="IServiceProvider" /> for your dependency injection solution if using one; otherwise, pass <c>null</c> .</param> | ||||
| @@ -3,13 +3,19 @@ using System; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Extension methods for <see cref="IUserMessage"/> that related to commands. | |||||
| /// Provides extension methods for <see cref="IUserMessage" /> that relates to commands. | |||||
| /// </summary> | /// </summary> | ||||
| public static class MessageExtensions | public static class MessageExtensions | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Gets whether the message starts with the provided character. | /// Gets whether the message starts with the provided character. | ||||
| /// </summary> | /// </summary> | ||||
| /// <param name="msg">The message to check against.</param> | |||||
| /// <param name="c">The char prefix.</param> | |||||
| /// <param name="argPos">References where the command starts.</param> | |||||
| /// <returns> | |||||
| /// <c>true</c> if the message begins with the char <paramref name="c"/>; otherwise <c>false</c>. | |||||
| /// </returns> | |||||
| public static bool HasCharPrefix(this IUserMessage msg, char c, ref int argPos) | public static bool HasCharPrefix(this IUserMessage msg, char c, ref int argPos) | ||||
| { | { | ||||
| var text = msg.Content; | var text = msg.Content; | ||||
| @@ -11,18 +11,54 @@ namespace Discord.Commands | |||||
| /// </summary> | /// </summary> | ||||
| public class ModuleInfo | public class ModuleInfo | ||||
| { | { | ||||
| /// <summary> | |||||
| /// Gets the command service associated with this module. | |||||
| /// </summary> | |||||
| public CommandService Service { get; } | public CommandService Service { get; } | ||||
| /// <summary> | |||||
| /// Gets the name of this module. | |||||
| /// </summary> | |||||
| public string Name { get; } | public string Name { get; } | ||||
| /// <summary> | |||||
| /// Gets the summary of this module. | |||||
| /// </summary> | |||||
| public string Summary { get; } | public string Summary { get; } | ||||
| /// <summary> | |||||
| /// Gets the remarks of this module. | |||||
| /// </summary> | |||||
| public string Remarks { get; } | public string Remarks { get; } | ||||
| /// <summary> | |||||
| /// Gets the group name (main prefix) of this module. | |||||
| /// </summary> | |||||
| public string Group { get; } | public string Group { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of aliases associated with this module. | |||||
| /// </summary> | |||||
| public IReadOnlyList<string> Aliases { get; } | public IReadOnlyList<string> Aliases { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of commands associated with this module. | |||||
| /// </summary> | |||||
| public IReadOnlyList<CommandInfo> Commands { get; } | public IReadOnlyList<CommandInfo> Commands { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of preconditions that apply to this module. | |||||
| /// </summary> | |||||
| public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of attributes that apply to this module. | |||||
| /// </summary> | |||||
| public IReadOnlyList<Attribute> Attributes { get; } | public IReadOnlyList<Attribute> Attributes { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of submodules associated with tihs module. | |||||
| /// </summary> | |||||
| public IReadOnlyList<ModuleInfo> Submodules { get; } | public IReadOnlyList<ModuleInfo> Submodules { get; } | ||||
| /// <summary> | |||||
| /// Gets the parent module of this submodule if applicable. | |||||
| /// </summary> | |||||
| public ModuleInfo Parent { get; } | public ModuleInfo Parent { get; } | ||||
| /// <summary> | |||||
| /// Gets a value that indicates whether this module is a submodule or not. | |||||
| /// </summary> | |||||
| public bool IsSubmodule => Parent != null; | public bool IsSubmodule => Parent != null; | ||||
| internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, ModuleInfo parent = null) | internal ModuleInfo(ModuleBuilder builder, CommandService service, IServiceProvider services, ModuleInfo parent = null) | ||||
| @@ -15,16 +15,43 @@ namespace Discord.Commands | |||||
| { | { | ||||
| private readonly TypeReader _reader; | private readonly TypeReader _reader; | ||||
| /// <summary> | |||||
| /// Gets the command that associates with this parameter. | |||||
| /// </summary> | |||||
| public CommandInfo Command { get; } | public CommandInfo Command { get; } | ||||
| /// <summary> | |||||
| /// Gets the name of this parameter. | |||||
| /// </summary> | |||||
| public string Name { get; } | public string Name { get; } | ||||
| /// <summary> | |||||
| /// Gets the summary of this parameter. | |||||
| /// </summary> | |||||
| public string Summary { get; } | public string Summary { get; } | ||||
| /// <summary> | |||||
| /// Gets a value that indicates whether this parameter is optional or not. | |||||
| /// </summary> | |||||
| public bool IsOptional { get; } | public bool IsOptional { get; } | ||||
| /// <summary> | |||||
| /// Gets a value that indicates whether this parameter is a remainder parameter or not. | |||||
| /// </summary> | |||||
| public bool IsRemainder { get; } | public bool IsRemainder { get; } | ||||
| public bool IsMultiple { get; } | public bool IsMultiple { get; } | ||||
| /// <summary> | |||||
| /// Gets the type of the parameter. | |||||
| /// </summary> | |||||
| public Type Type { get; } | public Type Type { get; } | ||||
| /// <summary> | |||||
| /// Gets the default value for this optional parameter if applicable. | |||||
| /// </summary> | |||||
| public object DefaultValue { get; } | public object DefaultValue { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of precondition that apply to this parameter. | |||||
| /// </summary> | |||||
| public IReadOnlyList<ParameterPreconditionAttribute> Preconditions { get; } | public IReadOnlyList<ParameterPreconditionAttribute> Preconditions { get; } | ||||
| /// <summary> | |||||
| /// Gets a read-only list of attributes that apply to this parameter. | |||||
| /// </summary> | |||||
| public IReadOnlyList<Attribute> Attributes { get; } | public IReadOnlyList<Attribute> Attributes { get; } | ||||
| internal ParameterInfo(ParameterBuilder builder, CommandInfo command, CommandService service) | internal ParameterInfo(ParameterBuilder builder, CommandInfo command, CommandService service) | ||||
| @@ -6,6 +6,9 @@ namespace Discord.Commands | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public struct ExecuteResult : IResult | public struct ExecuteResult : IResult | ||||
| { | { | ||||
| /// <summary> | |||||
| /// Gets the exception that may have occurred during the command execution. | |||||
| /// </summary> | |||||
| public Exception Exception { get; } | public Exception Exception { get; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -1,7 +1,7 @@ | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Provides extension methods for <see cref="IMessage"/>. | |||||
| /// Provides extension methods for <see cref="IMessage" />. | |||||
| /// </summary> | /// </summary> | ||||
| public static class MessageExtensions | public static class MessageExtensions | ||||
| { | { | ||||
| @@ -361,6 +361,12 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| /// <example> | |||||
| /// The following example sets the status of the current user to Do Not Disturb. | |||||
| /// <code language="cs"> | |||||
| /// await client.SetStatusAsync(UserStatus.DoNotDisturb); | |||||
| /// </code> | |||||
| /// </example> | |||||
| public override async Task SetStatusAsync(UserStatus status) | public override async Task SetStatusAsync(UserStatus status) | ||||
| { | { | ||||
| Status = status; | Status = status; | ||||
| @@ -371,6 +377,20 @@ namespace Discord.WebSocket | |||||
| await SendStatusAsync().ConfigureAwait(false); | await SendStatusAsync().ConfigureAwait(false); | ||||
| } | } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| /// <example> | |||||
| /// <para> | |||||
| /// The following example sets the activity of the current user to the specified game name. | |||||
| /// <code language="cs"> | |||||
| /// await client.SetGameAsync("A Strange Game"); | |||||
| /// </code> | |||||
| /// </para> | |||||
| /// <para> | |||||
| /// The following example sets the activity of the current user to a streaming status. | |||||
| /// <code language="cs"> | |||||
| /// await client.SetGameAsync("Great Stream 10/10", "https://twitch.tv/MyAmazingStream1337", ActivityType.Streaming); | |||||
| /// </code> | |||||
| /// </para> | |||||
| /// </example> | |||||
| public override async Task SetGameAsync(string name, string streamUrl = null, ActivityType type = ActivityType.Playing) | public override async Task SetGameAsync(string name, string streamUrl = null, ActivityType type = ActivityType.Playing) | ||||
| { | { | ||||
| if (!string.IsNullOrEmpty(streamUrl)) | if (!string.IsNullOrEmpty(streamUrl)) | ||||
| @@ -7,7 +7,7 @@ using Model = Discord.API.User; | |||||
| namespace Discord.WebSocket | namespace Discord.WebSocket | ||||
| { | { | ||||
| /// <summary> | /// <summary> | ||||
| /// Represents the logged-in WebSocker-based user. | |||||
| /// Represents the logged-in WebSocket-based user. | |||||
| /// </summary> | /// </summary> | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class SocketSelfUser : SocketUser, ISelfUser | public class SocketSelfUser : SocketUser, ISelfUser | ||||