@@ -6,7 +6,7 @@ namespace Discord.Commands | |||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |||
public class AliasAttribute : Attribute | |||
{ | |||
/// <summary> The aliases which have been defined for the command. </summary> | |||
/// <summary> Gets the aliases which have been defined for the command. </summary> | |||
public string[] Aliases { get; } | |||
/// <summary> Creates a new <see cref="AliasAttribute"/> with the given aliases. </summary> | |||
@@ -7,11 +7,11 @@ namespace Discord.Commands | |||
public class CommandAttribute : Attribute | |||
{ | |||
/// <summary> | |||
/// Gets the text that has been set to be recognized as a command. | |||
/// Gets the text that has been set to be recognized as a command. | |||
/// </summary> | |||
public string Text { get; } | |||
/// <summary> | |||
/// Specifies the <see cref="RunMode"/> of the command. This affects how the command is executed. | |||
/// Specifies the <see cref="RunMode" /> of the command. This affects how the command is executed. | |||
/// </summary> | |||
public RunMode RunMode { get; set; } = RunMode.Default; | |||
@@ -1,10 +1,12 @@ | |||
using System; | |||
namespace Discord.Commands { | |||
/// <summary> Prevents the marked property from being injected into a module. </summary> | |||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] | |||
public class DontInjectAttribute : Attribute { | |||
} | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> | |||
/// Prevents the marked property from being injected into a module. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] | |||
public class DontInjectAttribute : Attribute | |||
{ | |||
} | |||
} |
@@ -3,11 +3,15 @@ using System; | |||
namespace Discord.Commands | |||
{ | |||
// Override public name of command/module | |||
/// <summary> Marks the public name of a command, module, or parameter. </summary> | |||
/// <summary> | |||
/// Marks the public name of a command, module, or parameter. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] | |||
public class NameAttribute : Attribute | |||
{ | |||
/// <summary> Gets the name of the command. </summary> | |||
/// <summary> | |||
/// Gets the name of the command. | |||
/// </summary> | |||
public string Text { get; } | |||
/// <summary> Marks the public name of a command, module, or parameter with the provided name. </summary> | |||
@@ -3,7 +3,9 @@ using System.Threading.Tasks; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Requires the parameter to pass the specified precondition before execution can begin. </summary> | |||
/// <summary> | |||
/// Requires the parameter to pass the specified precondition before execution can begin. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)] | |||
public abstract class ParameterPreconditionAttribute : Attribute | |||
{ | |||
@@ -7,12 +7,15 @@ namespace Discord.Commands | |||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] | |||
public abstract class PreconditionAttribute : Attribute | |||
{ | |||
/// <summary> Specify a group that this precondition belongs to. </summary> | |||
/// <summary> | |||
/// Specify a group that this precondition belongs to. | |||
/// </summary> | |||
/// <remarks> | |||
/// <see cref="Preconditions"/> of the same group require only one | |||
/// of the preconditions to pass in order to be successful (A || B). | |||
/// Specifying <see cref="Group"/> = <see langword="null"/> | |||
/// or not at all will require *all* preconditions to pass, just like normal (A && B). | |||
/// <para> | |||
/// <see cref="Preconditions" /> of the same group require only one of the preconditions to pass in | |||
/// order to be successful (A || B). Specifying <see cref="Group" /> = <see langword="null" /> or not | |||
/// at all will require *all* preconditions to pass, just like normal (A && B). | |||
/// </para> | |||
/// </remarks> | |||
public string Group { get; set; } = null; | |||
@@ -2,14 +2,20 @@ using System; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Sets priority of commands. </summary> | |||
/// <summary> | |||
/// Sets priority of commands. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] | |||
public class PriorityAttribute : Attribute | |||
{ | |||
/// <summary> Gets the priority which has been set for the command. </summary> | |||
/// <summary> | |||
/// Gets the priority which has been set for the command. | |||
/// </summary> | |||
public int Priority { get; } | |||
/// <summary> Creates a new <see cref="PriorityAttribute"/> with the given priority. </summary> | |||
/// <summary> | |||
/// Creates a new <see cref="PriorityAttribute" /> with the given priority. | |||
/// </summary> | |||
public PriorityAttribute(int priority) | |||
{ | |||
Priority = priority; | |||
@@ -2,7 +2,9 @@ using System; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Marks the input to not be parsed by the parser. </summary> | |||
/// <summary> | |||
/// Marks the input to not be parsed by the parser. | |||
/// </summary> | |||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] | |||
public class RemainderAttribute : Attribute | |||
{ | |||
@@ -1,6 +1,6 @@ | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> The type of error the command throws. </summary> | |||
/// <summary> Defines the type of error a command can throw. </summary> | |||
public enum CommandError | |||
{ | |||
//Search | |||
@@ -2,14 +2,24 @@ using System; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Thrown when a command fails to execute. </summary> | |||
/// <summary> | |||
/// Describes an exception that occurred during a command execution. | |||
/// </summary> | |||
public class CommandException : Exception | |||
{ | |||
/// <summary> The command that caused the exception. </summary> | |||
/// <summary> Gets the command that caused the exception. </summary> | |||
public CommandInfo Command { get; } | |||
/// <summary> The command context of the exception. </summary> | |||
/// <summary> Gets the command context of the exception. </summary> | |||
public ICommandContext Context { get; } | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="CommandException" /> class using a | |||
/// <paramref name="command"/> information, a <paramref name="command"/> context, and the exception that | |||
/// interrupted the execution. | |||
/// </summary> | |||
/// <param name="command">The command information.</param> | |||
/// <param name="context">The context of the command.</param> | |||
/// <param name="ex">The exception that interrupted the command execution.</param> | |||
public CommandException(CommandInfo command, ICommandContext context, Exception ex) | |||
: base($"Error occurred executing {command.GetLogText(context)}.", ex) | |||
{ | |||
@@ -18,7 +18,7 @@ namespace Discord.Commands | |||
internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); | |||
/// <summary> | |||
/// Fired when a command is successfully executed. | |||
/// Fired when a command is successfully executed without any runtime error. | |||
/// </summary> | |||
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>>(); | |||
@@ -38,17 +38,17 @@ namespace Discord.Commands | |||
internal readonly LogManager _logManager; | |||
/// <summary> | |||
/// Represents all modules loaded within <see cref="CommandService"/>. | |||
/// Represents all modules loaded within <see cref="CommandService" /> . | |||
/// </summary> | |||
public IEnumerable<ModuleInfo> Modules => _moduleDefs.Select(x => x); | |||
/// <summary> | |||
/// Represents all commands loaded within <see cref="CommandService"/>. | |||
/// Represents all commands loaded within <see cref="CommandService" /> . | |||
/// </summary> | |||
public IEnumerable<CommandInfo> Commands => _moduleDefs.SelectMany(x => x.Commands); | |||
/// <summary> | |||
/// Represents all <see cref="TypeReader"/> loaded within <see cref="CommandService"/>. | |||
/// Represents all <see cref="TypeReader" /> loaded within <see cref="CommandService" /> . | |||
/// </summary> | |||
public ILookup<Type, TypeReader> TypeReaders => _typeReaders.SelectMany(x => x.Value.Select(y => new { y.Key, y.Value })).ToLookup(x => x.Key, x => x.Value); | |||
@@ -111,12 +111,28 @@ namespace Discord.Commands | |||
} | |||
/// <summary> | |||
/// Add a command module from a <see cref="Type"/>. | |||
/// Add a command module from a <see cref="Type" /> . | |||
/// </summary> | |||
/// <typeparam name="T">The type of module.</typeparam> | |||
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>. </param> | |||
/// <returns>A built module.</returns> | |||
/// <param name="services"> | |||
/// The <see cref="IServiceProvider" /> for your dependency injection solution, if using one - otherwise, pass | |||
/// <see langword="null" /> . | |||
/// </param> | |||
/// <returns> | |||
/// A built module. | |||
/// </returns> | |||
public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services); | |||
/// <summary> | |||
/// Adds a command module from a <see cref="Type" /> . | |||
/// </summary> | |||
/// <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 | |||
/// <see langword="null" /> . | |||
/// </param> | |||
/// <returns> | |||
/// A built module. | |||
/// </returns> | |||
public async Task<ModuleInfo> AddModuleAsync(Type type, IServiceProvider services) | |||
{ | |||
services = services ?? EmptyServiceProvider.Instance; | |||
@@ -144,11 +160,16 @@ namespace Discord.Commands | |||
} | |||
} | |||
/// <summary> | |||
/// Add command modules from an <see cref="Assembly"/>. | |||
/// Add command modules from an <see cref="Assembly" /> . | |||
/// </summary> | |||
/// <param name="assembly">The <see cref="Assembly"/> containing command modules.</param> | |||
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>.</param> | |||
/// <returns>A collection of built modules.</returns> | |||
/// <param name="assembly">The <see cref="Assembly" /> containing command modules.</param> | |||
/// <param name="services"> | |||
/// An <see cref="IServiceProvider" /> for your dependency injection solution, if using one - otherwise, pass | |||
/// <see langword="null" /> . | |||
/// </param> | |||
/// <returns> | |||
/// A collection of built modules. | |||
/// </returns> | |||
public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly, IServiceProvider services) | |||
{ | |||
services = services ?? EmptyServiceProvider.Instance; | |||
@@ -184,7 +205,13 @@ namespace Discord.Commands | |||
return module; | |||
} | |||
/// <summary> | |||
/// Removes the command module. | |||
/// </summary> | |||
/// <param name="module">The <see cref="ModuleInfo" /> to be removed from the service.</param> | |||
/// <returns> | |||
/// Returns whether the <paramref name="module"/> is successfully removed. | |||
/// </returns> | |||
public async Task<bool> RemoveModuleAsync(ModuleInfo module) | |||
{ | |||
await _moduleLock.WaitAsync().ConfigureAwait(false); | |||
@@ -231,29 +258,25 @@ namespace Discord.Commands | |||
//Type Readers | |||
/// <summary> | |||
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. | |||
/// <para> | |||
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added. | |||
/// </para> | |||
/// <para> | |||
/// If a default <see cref="TypeReader"/> exists for <typeparamref name="T"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced. | |||
/// </para> | |||
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object type. | |||
/// If <typeparamref name="T" /> is a <see cref="ValueType" />, a nullable <see cref="TypeReader" /> will also be | |||
/// added. | |||
/// If a default <see cref="TypeReader" /> exists for <typeparamref name="T" />, a warning will be logged and the | |||
/// default <see cref="TypeReader" /> will be replaced. | |||
/// </summary> | |||
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam> | |||
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> | |||
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader" />.</typeparam> | |||
/// <param name="reader">An instance of the <see cref="TypeReader" /> to be added.</param> | |||
public void AddTypeReader<T>(TypeReader reader) | |||
=> AddTypeReader(typeof(T), reader); | |||
/// <summary> | |||
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. | |||
/// <para> | |||
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added. | |||
/// </para> | |||
/// <para> | |||
/// If a default <see cref="TypeReader"/> exists for <paramref name="type"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced. | |||
/// </para> | |||
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object type. | |||
/// If <paramref name="type" /> is a <see cref="ValueType" />, a nullable <see cref="TypeReader" /> for the value | |||
/// type will also be added. | |||
/// If a default <see cref="TypeReader" /> exists for <paramref name="type" />, a warning will be logged and the | |||
/// default <see cref="TypeReader" /> will be replaced. | |||
/// </summary> | |||
/// <param name="type">A <see cref="Type"/> instance for the type to be read.</param> | |||
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> | |||
/// <param name="type">A <see cref="Type" /> instance for the type to be read.</param> | |||
/// <param name="reader">An instance of the <see cref="TypeReader" /> to be added.</param> | |||
public void AddTypeReader(Type type, TypeReader reader) | |||
{ | |||
if (_defaultTypeReaders.ContainsKey(type)) | |||
@@ -262,25 +285,29 @@ namespace Discord.Commands | |||
AddTypeReader(type, reader, true); | |||
} | |||
/// <summary> | |||
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. | |||
/// <para> | |||
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added. | |||
/// </para> | |||
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object type. | |||
/// If <typeparamref name="T" /> is a <see cref="ValueType" />, a nullable <see cref="TypeReader" /> will also be | |||
/// added. | |||
/// </summary> | |||
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam> | |||
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> | |||
/// <param name="replaceDefault">If <paramref name="reader"/> should replace the default <see cref="TypeReader"/> for <typeparamref name="T"/> if one exists.</param> | |||
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader" />.</typeparam> | |||
/// <param name="reader">An instance of the <see cref="TypeReader" /> to be added.</param> | |||
/// <param name="replaceDefault"> | |||
/// Defines whether the <see cref="TypeReader"/> should replace the default one for | |||
/// <see cref="Type" /> if it exists. | |||
/// </param> | |||
public void AddTypeReader<T>(TypeReader reader, bool replaceDefault) | |||
=> AddTypeReader(typeof(T), reader, replaceDefault); | |||
/// <summary> | |||
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. | |||
/// <para> | |||
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added. | |||
/// </para> | |||
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object type. | |||
/// If <paramref name="type" /> is a <see cref="ValueType" />, a nullable <see cref="TypeReader" /> for the value | |||
/// type will also be added. | |||
/// </summary> | |||
/// <param name="type">A <see cref="Type"/> instance for the type to be read.</param> | |||
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> | |||
/// <param name="replaceDefault">If <paramref name="reader"/> should replace the default <see cref="TypeReader"/> for <paramref name="type"/> if one exists.</param> | |||
/// <param name="type">A <see cref="Type" /> instance for the type to be read.</param> | |||
/// <param name="reader">An instance of the <see cref="TypeReader" /> to be added.</param> | |||
/// <param name="replaceDefault"> | |||
/// Defines whether the <see cref="TypeReader"/> should replace the default one for | |||
/// <see cref="Type" /> if it exists. | |||
/// </param> | |||
public void AddTypeReader(Type type, TypeReader reader, bool replaceDefault) | |||
{ | |||
if (replaceDefault && _defaultTypeReaders.ContainsKey(type)) | |||
@@ -342,8 +369,20 @@ namespace Discord.Commands | |||
} | |||
//Execution | |||
/// <summary> | |||
/// Searches for the command. | |||
/// </summary> | |||
/// <param name="context">The context of the command.</param> | |||
/// <param name="argPos">The position of which the command starts at.</param> | |||
/// <returns>The result containing the matching commands.</returns> | |||
public SearchResult Search(ICommandContext context, int argPos) | |||
=> Search(context, context.Message.Content.Substring(argPos)); | |||
/// <summary> | |||
/// Searches for the command. | |||
/// </summary> | |||
/// <param name="context">The context of the command.</param> | |||
/// <param name="input">The command string.</param> | |||
/// <returns>The result containing the matching commands.</returns> | |||
public SearchResult Search(ICommandContext context, string input) | |||
{ | |||
string searchInput = _caseSensitive ? input : input.ToLowerInvariant(); | |||
@@ -355,8 +394,24 @@ namespace Discord.Commands | |||
return SearchResult.FromError(CommandError.UnknownCommand, "Unknown command."); | |||
} | |||
/// <summary> | |||
/// Executes the command. | |||
/// </summary> | |||
/// <param name="context">The context of the command.</param> | |||
/// <param name="argPos">The position of which the command starts at.</param> | |||
/// <param name="services">The service to be used in the command's dependency injection.</param> | |||
/// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> | |||
/// <returns>The result of the command execution.</returns> | |||
public Task<IResult> ExecuteAsync(ICommandContext context, int argPos, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
=> ExecuteAsync(context, context.Message.Content.Substring(argPos), services, multiMatchHandling); | |||
/// <summary> | |||
/// Executes the command. | |||
/// </summary> | |||
/// <param name="context">The context of the command.</param> | |||
/// <param name="input">The command string.</param> | |||
/// <param name="services">The service to be used in the command's dependency injection.</param> | |||
/// <param name="multiMatchHandling">The handling mode when multiple command matches are found.</param> | |||
/// <returns>The result of the command execution.</returns> | |||
public async Task<IResult> ExecuteAsync(ICommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception) | |||
{ | |||
services = services ?? EmptyServiceProvider.Instance; | |||
@@ -1,9 +1,15 @@ | |||
using System; | |||
using System; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> | |||
/// Extension methods for <see cref="IUserMessage"/> that related to commands. | |||
/// </summary> | |||
public static class MessageExtensions | |||
{ | |||
/// <summary> | |||
/// Gets whether the message starts with the provided <see langword="char" />. | |||
/// </summary> | |||
public static bool HasCharPrefix(this IUserMessage msg, char c, ref int argPos) | |||
{ | |||
var text = msg.Content; | |||
@@ -14,6 +20,9 @@ namespace Discord.Commands | |||
} | |||
return false; | |||
} | |||
/// <summary> | |||
/// Gets whether the message starts with the provided <see langword="string" />. | |||
/// </summary> | |||
public static bool HasStringPrefix(this IUserMessage msg, string str, ref int argPos, StringComparison comparisonType = StringComparison.Ordinal) | |||
{ | |||
var text = msg.Content; | |||
@@ -24,6 +33,9 @@ namespace Discord.Commands | |||
} | |||
return false; | |||
} | |||
/// <summary> | |||
/// Gets whether the message starts with the user's mention string. | |||
/// </summary> | |||
public static bool HasMentionPrefix(this IUserMessage msg, IUser user, ref int argPos) | |||
{ | |||
var text = msg.Content; | |||
@@ -43,4 +55,4 @@ namespace Discord.Commands | |||
return false; | |||
} | |||
} | |||
} | |||
} |
@@ -8,14 +8,15 @@ using System.Linq; | |||
using System.Reflection; | |||
using System.Runtime.ExceptionServices; | |||
using System.Threading.Tasks; | |||
using Microsoft.Extensions.DependencyInjection; | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> The information of a command. </summary> | |||
/// <remarks> | |||
/// This object contains the information of a command. | |||
/// This can include the module of the command, various descriptions regarding the command, and its <see cref="RunMode"/>. | |||
/// <summary> | |||
/// Provides the information of a command. | |||
/// </summary> | |||
/// <remarks> | |||
/// This object contains the information of a command. This can include the module of the command, various | |||
/// descriptions regarding the command, and its <see cref="RunMode" /> . | |||
/// </remarks> | |||
[DebuggerDisplay("{Name,nq}")] | |||
public class CommandInfo | |||
@@ -26,36 +27,59 @@ namespace Discord.Commands | |||
private readonly CommandService _commandService; | |||
private readonly Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> _action; | |||
/// <summary> The module that the command belongs in. </summary> | |||
/// <summary> | |||
/// Gets the module that the command belongs in. | |||
/// </summary> | |||
public ModuleInfo Module { get; } | |||
/// <summary> Name of the command. If none is set, the first alias is used. </summary> | |||
/// <summary> | |||
/// Gets the name of the command. If none is set, the first alias is used. | |||
/// </summary> | |||
public string Name { get; } | |||
/// <summary> Summary of the command. </summary> | |||
/// <remarks> | |||
/// This field returns the summary of the command. | |||
/// Summary and remarks can be useful in help commands and various implementation that fetches details of the command for the user. | |||
/// <summary> | |||
/// Gets the summary of the command. | |||
/// </summary> | |||
/// <remarks> | |||
/// This field returns the summary of the command. <see cref="Summary"/> and <see cref="Remarks"/> can be | |||
/// useful in help commands and various implementation that fetches details of the command for the user. | |||
/// </remarks> | |||
public string Summary { get; } | |||
/// <summary> Remarks of the command. </summary> | |||
/// <remarks> | |||
/// This field returns the remarks of the command. | |||
/// Summary and remarks can be useful in help commands and various implementation that fetches details of the command for the user. | |||
/// <summary> | |||
/// Gets the remarks of the command. | |||
/// </summary> | |||
/// <remarks> | |||
/// This field returns the summary of the command. <see cref="Summary"/> and <see cref="Remarks"/> can be | |||
/// useful in help commands and various implementation that fetches details of the command for the user. | |||
/// </remarks> | |||
public string Remarks { get; } | |||
/// <summary> The priority of the command. This is used when there are multiple overloads of the command. </summary> | |||
/// <summary> | |||
/// Gets the priority of the command. This is used when there are multiple overloads of the command. | |||
/// </summary> | |||
public int Priority { get; } | |||
/// <summary> Indicates whether the command accepts a <see langword="params"/> <see cref="Type"/>[] for its parameter. </summary> | |||
/// <summary> | |||
/// Indicates whether the command accepts a <see langword="params"/> <see cref="Type"/>[] for its | |||
/// parameter. | |||
/// </summary> | |||
public bool HasVarArgs { get; } | |||
/// <summary> Indicates the <see cref="RunMode"/> that is being used for the command. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="RunMode" /> that is being used for the command. | |||
/// </summary> | |||
public RunMode RunMode { get; } | |||
/// <summary> List of aliases defined by the <see cref="AliasAttribute"/> of the command. </summary> | |||
/// <summary> | |||
/// Gets a list of aliases defined by the <see cref="AliasAttribute" /> of the command. | |||
/// </summary> | |||
public IReadOnlyList<string> Aliases { get; } | |||
/// <summary> List of information about the parameters of the command. </summary> | |||
/// <summary> | |||
/// Gets a list of information about the parameters of the command. | |||
/// </summary> | |||
public IReadOnlyList<ParameterInfo> Parameters { get; } | |||
/// <summary> List of preconditions defined by the <see cref="PreconditionAttribute"/> of the command. </summary> | |||
/// <summary> | |||
/// Gets a list of preconditions defined by the <see cref="PreconditionAttribute" /> of the command. | |||
/// </summary> | |||
public IReadOnlyList<PreconditionAttribute> Preconditions { get; } | |||
/// <summary> List of attributes of the command. </summary> | |||
/// <summary> | |||
/// Gets a list of attributes of the command. | |||
/// </summary> | |||
public IReadOnlyList<Attribute> Attributes { get; } | |||
internal CommandInfo(CommandBuilder builder, ModuleInfo module, CommandService service) | |||
@@ -145,8 +169,7 @@ namespace Discord.Commands | |||
string input = searchResult.Text.Substring(startIndex); | |||
return await CommandParser.ParseArgsAsync(this, context, _commandService._ignoreExtraArgs, services, input, 0).ConfigureAwait(false); | |||
} | |||
/// <summary> Executes the command with the provided context, parsed value, and service provider. </summary> | |||
public Task<IResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | |||
{ | |||
if (!parseResult.IsSuccess) | |||
@@ -170,7 +193,6 @@ namespace Discord.Commands | |||
return ExecuteAsync(context, argList, paramList, services); | |||
} | |||
/// <summary> Executes the command with the provided context, argument and parameter list, and service provider. </summary> | |||
public async Task<IResult> ExecuteAsync(ICommandContext context, IEnumerable<object> argList, IEnumerable<object> paramList, IServiceProvider services) | |||
{ | |||
services = services ?? EmptyServiceProvider.Instance; | |||
@@ -2,7 +2,6 @@ using System; | |||
using System.Linq; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Reflection; | |||
using Discord.Commands.Builders; | |||
namespace Discord.Commands | |||
@@ -4,7 +4,6 @@ using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Diagnostics; | |||
using System.Threading.Tasks; | |||
using Microsoft.Extensions.DependencyInjection; | |||
namespace Discord.Commands | |||
{ | |||
@@ -1,4 +1,4 @@ | |||
using System.Collections.Generic; | |||
using System.Collections.Generic; | |||
namespace Discord.Commands | |||
{ | |||
@@ -6,7 +6,6 @@ namespace Discord.Commands | |||
{ | |||
private readonly CommandService _service; | |||
private readonly CommandMapNode _root; | |||
private static readonly string[] _blankAliases = new[] { "" }; | |||
public CommandMap(CommandService service) | |||
{ | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -7,7 +7,7 @@ namespace Discord.Commands | |||
{ | |||
internal class CommandMapNode | |||
{ | |||
private static readonly char[] _whitespaceChars = new[] { ' ', '\r', '\n' }; | |||
private static readonly char[] WhitespaceChars = new[] { ' ', '\r', '\n' }; | |||
private readonly ConcurrentDictionary<string, CommandMapNode> _nodes; | |||
private readonly string _name; | |||
@@ -100,7 +100,7 @@ namespace Discord.Commands | |||
} | |||
//Check if this is the last command segment before args | |||
nextSegment = NextSegment(text, index, _whitespaceChars, service._separatorChar); | |||
nextSegment = NextSegment(text, index, WhitespaceChars, service._separatorChar); | |||
if (nextSegment != -1) | |||
{ | |||
name = text.Substring(index, nextSegment - index); | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Diagnostics; | |||
namespace Discord.Commands | |||
@@ -1,6 +1,6 @@ | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Represents the information of command execution result. </summary> | |||
/// <summary> Represents information of the command execution result. </summary> | |||
public interface IResult | |||
{ | |||
/// <summary> Describes the error type that may have occurred during the operation. </summary> | |||
@@ -11,10 +11,8 @@ namespace Discord.Audio | |||
public override bool CanSeek => false; | |||
public override bool CanWrite => false; | |||
public virtual void WriteHeader(ushort seq, uint timestamp, bool missed) | |||
{ | |||
throw new InvalidOperationException("This stream does not accept headers"); | |||
} | |||
public virtual void WriteHeader(ushort seq, uint timestamp, bool missed) => | |||
throw new InvalidOperationException("This stream does not accept headers."); | |||
public override void Write(byte[] buffer, int offset, int count) | |||
{ | |||
WriteAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult(); | |||
@@ -30,11 +28,13 @@ namespace Discord.Audio | |||
public virtual Task ClearAsync(CancellationToken cancellationToken) { return Task.Delay(0); } | |||
public override long Length { get { throw new NotSupportedException(); } } | |||
public override long Length => | |||
throw new NotSupportedException(); | |||
public override long Position | |||
{ | |||
get { throw new NotSupportedException(); } | |||
set { throw new NotSupportedException(); } | |||
get => throw new NotSupportedException(); | |||
set => throw new NotSupportedException(); | |||
} | |||
public override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } | |||
@@ -1,17 +1,29 @@ | |||
namespace Discord.Commands | |||
{ | |||
/// <summary> Represents the context of a command. This may include the client, guild, channel, user, and message. </summary> | |||
/// <summary> | |||
/// Represents the context of a command. This may include the client, guild, channel, user, and message. | |||
/// </summary> | |||
public interface ICommandContext | |||
{ | |||
/// <summary> Gets the <see cref="IDiscordClient"/> that the command is executed with. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IDiscordClient" /> that the command is executed with. | |||
/// </summary> | |||
IDiscordClient Client { get; } | |||
/// <summary> Gets the <see cref="IGuild"/> that the command is executed in. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IGuild" /> that the command is executed in. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the <see cref="IMessageChannel"/> that the command is executed in. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IMessageChannel" /> that the command is executed in. | |||
/// </summary> | |||
IMessageChannel Channel { get; } | |||
/// <summary> Gets the <see cref="IUser"/> who executed the command. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IUser" /> who executed the command. | |||
/// </summary> | |||
IUser User { get; } | |||
/// <summary> Gets the <see cref="IUserMessage"/> that the command is interpreted from. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IUserMessage" /> that the command is interpreted from. | |||
/// </summary> | |||
IUserMessage Message { get; } | |||
} | |||
} |
@@ -1,15 +1,25 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies a Discord user's activity type. </summary> | |||
/// <summary> | |||
/// Specifies a Discord user's activity type. | |||
/// </summary> | |||
public enum ActivityType | |||
{ | |||
/// <summary> The user is playing a game. </summary> | |||
/// <summary> | |||
/// The user is playing a game. | |||
/// </summary> | |||
Playing = 0, | |||
/// <summary> The user is streaming online. </summary> | |||
/// <summary> | |||
/// The user is streaming online. | |||
/// </summary> | |||
Streaming = 1, | |||
/// <summary> The user is listening to a song. </summary> | |||
/// <summary> | |||
/// The user is listening to a song. | |||
/// </summary> | |||
Listening = 2, | |||
/// <summary> The user is watching a media. </summary> | |||
/// <summary> | |||
/// The user is watching a media. | |||
/// </summary> | |||
Watching = 3 | |||
} | |||
} |
@@ -2,7 +2,9 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> A user's game activity. </summary> | |||
/// <summary> | |||
/// A user's game activity. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class Game : IActivity | |||
{ | |||
@@ -12,9 +14,11 @@ namespace Discord | |||
public ActivityType Type { get; internal set; } | |||
internal Game() { } | |||
/// <summary> Creates a <see cref="Game"/> with the provided name and <see cref="ActivityType"/>. </summary> | |||
/// <summary> | |||
/// Creates a <see cref="Game"/> with the provided <paramref name="name"/> and <see cref="ActivityType"/>. | |||
/// </summary> | |||
/// <param name="name">The name of the game.</param> | |||
/// <param name="type">The type of activity. Default is <see cref="ActivityType.Playing"/>. </param> | |||
/// <param name="type">The type of activity. Default is <see cref="Discord.ActivityType.Playing" /> .</param> | |||
public Game(string name, ActivityType type = ActivityType.Playing) | |||
{ | |||
Name = name; | |||
@@ -1,18 +1,26 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> An asset for a <see cref="RichGame"/> object. </summary> | |||
/// <summary> | |||
/// An asset for a <see cref="RichGame" /> object. | |||
/// </summary> | |||
public class GameAsset | |||
{ | |||
internal GameAsset() { } | |||
internal ulong? ApplicationId { get; set; } | |||
/// <summary> The description of the asset. </summary> | |||
/// <summary> | |||
/// Gets the description of the asset. | |||
/// </summary> | |||
public string Text { get; internal set; } | |||
/// <summary> The image ID of the asset. </summary> | |||
/// <summary> | |||
/// Gets the image ID of the asset. | |||
/// </summary> | |||
public string ImageId { get; internal set; } | |||
/// <summary> The image URL of the asset; may return null when the application ID does not exist.</summary> | |||
/// <summary> | |||
/// Returns the image URL of the asset, or <see langword="null"/> when the application ID does not exist. | |||
/// </summary> | |||
public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) | |||
=> ApplicationId.HasValue ? CDN.GetRichAssetUrl(ApplicationId.Value, ImageId, size, format) : null; | |||
} | |||
@@ -4,8 +4,14 @@ namespace Discord | |||
{ | |||
internal GameParty() { } | |||
/// <summary> | |||
/// Gets the id of the party. | |||
/// </summary> | |||
public string Id { get; internal set; } | |||
public long Members { get; internal set; } | |||
/// <summary> | |||
/// Gets the party's current and maximum size. | |||
/// </summary> | |||
public long Capacity { get; internal set; } | |||
} | |||
} |
@@ -1,9 +1,18 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
public class GameSecrets | |||
{ | |||
/// <summary> | |||
/// Gets the secret for a specific instanced match. | |||
/// </summary> | |||
public string Match { get; } | |||
/// <summary> | |||
/// Gets the secret for joining a party. | |||
/// </summary> | |||
public string Join { get; } | |||
/// <summary> | |||
/// Gets the secret for spectating a game. | |||
/// </summary> | |||
public string Spectate { get; } | |||
internal GameSecrets(string match, string join, string spectate) | |||
@@ -13,4 +22,4 @@ | |||
Spectate = spectate; | |||
} | |||
} | |||
} | |||
} |
@@ -2,10 +2,18 @@ using System; | |||
namespace Discord | |||
{ | |||
/// <summary> Timestamps for a <see cref="RichGame"/> object. </summary> | |||
/// <summary> | |||
/// Timestamps for a <see cref="RichGame" /> object. | |||
/// </summary> | |||
public class GameTimestamps | |||
{ | |||
/// <summary> | |||
/// Gets when the activity started. | |||
/// </summary> | |||
public DateTimeOffset? Start { get; } | |||
/// <summary> | |||
/// Gets when the activity ends. | |||
/// </summary> | |||
public DateTimeOffset? End { get; } | |||
internal GameTimestamps(DateTimeOffset? start, DateTimeOffset? end) | |||
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> A Discord activity. </summary> | |||
/// <summary> | |||
/// A Discord activity, typically a game. | |||
/// </summary> | |||
public interface IActivity | |||
{ | |||
/// <summary> Gets the name of the activity. </summary> | |||
/// <summary> | |||
/// Gets the name of the activity. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Gets the type of the activity. </summary> | |||
/// <summary> | |||
/// Gets the type of the activity. | |||
/// </summary> | |||
ActivityType Type { get; } | |||
} | |||
} |
@@ -7,15 +7,42 @@ namespace Discord | |||
{ | |||
internal RichGame() { } | |||
/// <summary> | |||
/// Gets what the player is currently doing. | |||
/// </summary> | |||
public string Details { get; internal set; } | |||
/// <summary> | |||
/// Gets the user's current party status. | |||
/// </summary> | |||
public string State { get; internal set; } | |||
/// <summary> | |||
/// Gets the application ID for the game. | |||
/// </summary> | |||
public ulong ApplicationId { get; internal set; } | |||
/// <summary> | |||
/// Gets the small image for the presence and their hover texts. | |||
/// </summary> | |||
public GameAsset SmallAsset { get; internal set; } | |||
/// <summary> | |||
/// Gets the large image for the presence and their hover texts. | |||
/// </summary> | |||
public GameAsset LargeAsset { get; internal set; } | |||
/// <summary> | |||
/// Gets the information for the current party of the player. | |||
/// </summary> | |||
public GameParty Party { get; internal set; } | |||
/// <summary> | |||
/// Gets the secrets for Rich Presence joining and spectating. | |||
/// </summary> | |||
public GameSecrets Secrets { get; internal set; } | |||
/// <summary> | |||
/// Gets the timestamps for start and/or end of the game. | |||
/// </summary> | |||
public GameTimestamps Timestamps { get; internal set; } | |||
/// <summary> | |||
/// Returns the name of the Rich Presence. | |||
/// </summary> | |||
public override string ToString() => Name; | |||
private string DebuggerDisplay => $"{Name} (Rich)"; | |||
} | |||
@@ -4,23 +4,39 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> A user's activity for listening to a song on Spotify. </summary> | |||
/// <summary> | |||
/// A user's activity for listening to a song on Spotify. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class SpotifyGame : Game | |||
{ | |||
/// <summary> Gets the song's artist(s). </summary> | |||
/// <summary> | |||
/// Gets the song's artist(s). | |||
/// </summary> | |||
public IEnumerable<string> Artists { get; internal set; } | |||
/// <summary> Gets the Spotify album art for the song. </summary> | |||
/// <summary> | |||
/// Gets the Spotify album art of the song. | |||
/// </summary> | |||
public string AlbumArt { get; internal set; } | |||
/// <summary> Gets the Spotify album title for the song. </summary> | |||
/// <summary> | |||
/// Gets the Spotify album title of the song. | |||
/// </summary> | |||
public string AlbumTitle { get; internal set; } | |||
/// <summary> Gets the track title for the song. </summary> | |||
/// <summary> | |||
/// Gets the track title of the song. | |||
/// </summary> | |||
public string TrackTitle { get; internal set; } | |||
/// <summary> Gets the synchronization ID for the song. </summary> | |||
/// <summary> | |||
/// Gets the synchronization ID of the song. | |||
/// </summary> | |||
public string SyncId { get; internal set; } | |||
/// <summary> Gets the session ID for the song. </summary> | |||
/// <summary> | |||
/// Gets the session ID of the song. | |||
/// </summary> | |||
public string SessionId { get; internal set; } | |||
/// <summary> Gets the duration for the song. </summary> | |||
/// <summary> | |||
/// Gets the duration of the song. | |||
/// </summary> | |||
public TimeSpan? Duration { get; internal set; } | |||
internal SpotifyGame() { } | |||
@@ -2,13 +2,22 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> A user's activity for streaming on services such as Twitch. </summary> | |||
/// <summary> | |||
/// A user's activity for streaming on services such as Twitch. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class StreamingGame : Game | |||
{ | |||
/// <summary> Gets the URL of the stream. </summary> | |||
/// <summary> | |||
/// Gets the URL of the stream. | |||
/// </summary> | |||
public string Url { get; internal set; } | |||
/// <summary> | |||
/// Creates a new <see cref="StreamingGame" /> based on the <paramref name="name"/> on the stream URL. | |||
/// </summary> | |||
/// <param name="name">The name of the stream.</param> | |||
/// <param name="url">The URL of the stream.</param> | |||
public StreamingGame(string name, string url) | |||
{ | |||
Name = name; | |||
@@ -16,7 +25,9 @@ namespace Discord | |||
Type = ActivityType.Streaming; | |||
} | |||
/// <summary> Gets the name of the stream. </summary> | |||
/// <summary> | |||
/// Gets the name of the stream. | |||
/// </summary> | |||
public override string ToString() => Name; | |||
private string DebuggerDisplay => $"{Name} ({Url})"; | |||
} | |||
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the cache mode that should be used. </summary> | |||
/// <summary> | |||
/// Specifies the cache mode that should be used. | |||
/// </summary> | |||
public enum CacheMode | |||
{ | |||
/// <summary> Allows the object to be downloaded if it does not exist in the current cache. </summary> | |||
/// <summary> | |||
/// Allows the object to be downloaded if it does not exist in the current cache. | |||
/// </summary> | |||
AllowDownload, | |||
/// <summary> Only allows the object to be pulled from the existing cache. </summary> | |||
/// <summary> | |||
/// Only allows the object to be pulled from the existing cache. | |||
/// </summary> | |||
CacheOnly | |||
} | |||
} |
@@ -1,33 +1,35 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="IGuildChannel"/> with the specified changes. | |||
/// Properties that are used to modify an <see cref="IGuildChannel" /> with the specified changes. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await (Context.Channel as ITextChannel)?.ModifyAsync(x => | |||
/// { | |||
/// x.Name = "do-not-enter"; | |||
/// }); | |||
/// </code> | |||
/// <code lang="c#"> | |||
/// await (Context.Channel as ITextChannel)?.ModifyAsync(x => | |||
/// { | |||
/// x.Name = "do-not-enter"; | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
public class GuildChannelProperties | |||
{ | |||
/// <summary> | |||
/// Sets the channel to this name. | |||
/// Gets or sets the channel to this name. | |||
/// </summary> | |||
/// <remarks> | |||
/// When modifying an ITextChannel, the Name MUST be alphanumeric with dashes. | |||
/// It must match the following RegEx: [a-z0-9-_]{2,100} | |||
/// When modifying an <see cref="ITextChannel" />, the <see cref="Name" /> | |||
/// MUST be alphanumeric with dashes. It must match the following RegEx: [a-z0-9-_]{2,100} | |||
/// </remarks> | |||
/// <exception cref="Net.HttpException">A BadRequest will be thrown if the name does not match the above RegEx.</exception> | |||
/// <exception cref="Discord.Net.HttpException"> | |||
/// A BadRequest will be thrown if the name does not match the above RegEx. | |||
/// </exception> | |||
public Optional<string> Name { get; set; } | |||
/// <summary> | |||
/// Moves the channel to the following position. This is 0-based! | |||
/// Moves the channel to the following position. This is 0-based! | |||
/// </summary> | |||
public Optional<int> Position { get; set; } | |||
/// <summary> | |||
/// Sets the category for this channel. | |||
/// Gets or sets the category for this channel. | |||
/// </summary> | |||
public Optional<ulong?> CategoryId { get; set; } | |||
} | |||
@@ -1,12 +1,17 @@ | |||
using Discord.Audio; | |||
using Discord.Audio; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic audio channel. | |||
/// </summary> | |||
public interface IAudioChannel : IChannel | |||
{ | |||
/// <summary> Connects to this audio channel. </summary> | |||
/// <summary> | |||
/// Connects to this audio channel. | |||
/// </summary> | |||
Task<IAudioClient> ConnectAsync(Action<IAudioClient> configAction = null); | |||
} | |||
} |
@@ -1,11 +1,8 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic category channel. | |||
/// </summary> | |||
public interface ICategoryChannel : IGuildChannel | |||
{ | |||
} | |||
@@ -3,16 +3,24 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a generic Discord channel. </summary> | |||
/// <summary> | |||
/// Represents a generic Discord channel. | |||
/// </summary> | |||
public interface IChannel : ISnowflakeEntity | |||
{ | |||
/// <summary> Gets the name of this channel. </summary> | |||
/// <summary> | |||
/// Gets the name of this channel. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Gets a collection of all users in this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of all users in this channel. | |||
/// </summary> | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a user in this channel with the provided id. </summary> | |||
/// <summary> | |||
/// Gets a user in this channel with the provided ID. | |||
/// </summary> | |||
Task<IUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
} | |||
} |
@@ -1,13 +1,20 @@ | |||
using System.Threading.Tasks; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic DM channel. | |||
/// </summary> | |||
public interface IDMChannel : IMessageChannel, IPrivateChannel | |||
{ | |||
/// <summary> Gets the recipient of all messages in this channel. </summary> | |||
/// <summary> | |||
/// Gets the recipient of all messages in this channel. | |||
/// </summary> | |||
IUser Recipient { get; } | |||
/// <summary> Closes this private channel, removing it from your channel list. </summary> | |||
/// <summary> | |||
/// Closes this private channel, removing it from your channel list. | |||
/// </summary> | |||
Task CloseAsync(RequestOptions options = null); | |||
} | |||
} | |||
} |
@@ -1,10 +1,15 @@ | |||
using System.Threading.Tasks; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic group channel. | |||
/// </summary> | |||
public interface IGroupChannel : IMessageChannel, IPrivateChannel, IAudioChannel | |||
{ | |||
/// <summary> Leaves this group. </summary> | |||
/// <summary> | |||
/// Leaves this group. | |||
/// </summary> | |||
Task LeaveAsync(RequestOptions options = null); | |||
} | |||
} | |||
} |
@@ -4,50 +4,95 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a guild channel (text, voice, category). </summary> | |||
/// <summary> | |||
/// Represents a guild channel (text, voice, category). | |||
/// </summary> | |||
public interface IGuildChannel : IChannel, IDeletable | |||
{ | |||
/// <summary> Gets the position of this channel in the guild's channel list, relative to others of the same type. </summary> | |||
/// <summary> | |||
/// Gets the position of this channel in the guild's channel list, relative to others of the same type. | |||
/// </summary> | |||
int Position { get; } | |||
/// <summary> Gets the parent ID (category) of this channel in the guild's channel list. </summary> | |||
/// <summary> | |||
/// Gets the parent ID (category) of this channel in the guild's channel list. | |||
/// </summary> | |||
ulong? CategoryId { get; } | |||
/// <summary> Gets the parent channel (category) of this channel. </summary> | |||
/// <summary> | |||
/// Gets the parent channel (category) of this channel. | |||
/// </summary> | |||
Task<ICategoryChannel> GetCategoryAsync(); | |||
/// <summary> Gets the guild this channel is a member of. </summary> | |||
/// <summary> | |||
/// Gets the guild this channel is a member of. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the id of the guild this channel is a member of. </summary> | |||
/// <summary> | |||
/// Gets the id of the guild this channel is a member of. | |||
/// </summary> | |||
ulong GuildId { get; } | |||
/// <summary> Gets a collection of permission overwrites for this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of permission overwrites for this channel. | |||
/// </summary> | |||
IReadOnlyCollection<Overwrite> PermissionOverwrites { get; } | |||
/// <summary> Creates a new invite to this channel. </summary> | |||
/// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param> | |||
/// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param> | |||
/// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param> | |||
/// <summary> | |||
/// Creates a new invite to this channel. | |||
/// </summary> | |||
/// <param name="maxAge"> | |||
/// The time (in seconds) until the invite expires. Set to <see langword="null"/> to never expire. | |||
/// </param> | |||
/// <param name="maxUses"> | |||
/// The max amount of times this invite may be used. Set to <see langword="null"/> to have unlimited uses. | |||
/// </param> | |||
/// <param name="isTemporary"> | |||
/// If <see langword="true"/>, a user accepting this invite will be kicked from the guild after closing their client. | |||
/// </param> | |||
/// <param name="isUnique"> | |||
/// If <see langword="true"/>, don't try to reuse a similar invite (useful for creating many unique one time use invites). | |||
/// </param> | |||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = default(int?), bool isTemporary = false, bool isUnique = false, RequestOptions options = null); | |||
/// <summary> Returns a collection of all invites to this channel. </summary> | |||
/// <summary> | |||
/// Returns a collection of all invites to this channel. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null); | |||
/// <summary> Modifies this guild channel. </summary> | |||
/// <summary> | |||
/// Modifies this guild channel. | |||
/// </summary> | |||
Task ModifyAsync(Action<GuildChannelProperties> func, RequestOptions options = null); | |||
/// <summary> Gets the permission overwrite for a specific role, or null if one does not exist. </summary> | |||
/// <summary> | |||
/// Gets the permission overwrite for a specific role, or <see langword="null"/> if one does not exist. | |||
/// </summary> | |||
OverwritePermissions? GetPermissionOverwrite(IRole role); | |||
/// <summary> Gets the permission overwrite for a specific user, or null if one does not exist. </summary> | |||
/// <summary> | |||
/// Gets the permission overwrite for a specific user, or <see langword="null"/> if one does not exist. | |||
/// </summary> | |||
OverwritePermissions? GetPermissionOverwrite(IUser user); | |||
/// <summary> Removes the permission overwrite for the given role, if one exists. </summary> | |||
/// <summary> | |||
/// Removes the permission overwrite for the given role, if one exists. | |||
/// </summary> | |||
Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null); | |||
/// <summary> Removes the permission overwrite for the given user, if one exists. </summary> | |||
/// <summary> | |||
/// Removes the permission overwrite for the given user, if one exists. | |||
/// </summary> | |||
Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null); | |||
/// <summary> Adds or updates the permission overwrite for the given role. </summary> | |||
/// <summary> | |||
/// Adds or updates the permission overwrite for the given role. | |||
/// </summary> | |||
Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null); | |||
/// <summary> Adds or updates the permission overwrite for the given user. </summary> | |||
/// <summary> | |||
/// Adds or updates the permission overwrite for the given user. | |||
/// </summary> | |||
Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null); | |||
/// <summary> Gets a collection of all users in this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of all users in this channel. | |||
/// </summary> | |||
new IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a user in this channel with the provided id.</summary> | |||
/// <summary> | |||
/// Gets a user in this channel with the provided ID. | |||
/// </summary> | |||
new Task<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
} | |||
} |
@@ -5,34 +5,58 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic channel that can send and receive messages. | |||
/// </summary> | |||
public interface IMessageChannel : IChannel | |||
{ | |||
/// <summary> Sends a message to this message channel. </summary> | |||
/// <summary> | |||
/// Sends a message to this message channel. | |||
/// </summary> | |||
Task<IUserMessage> SendMessageAsync(string text, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
#if FILESYSTEM | |||
/// <summary> Sends a file to this text channel, with an optional caption. </summary> | |||
/// <summary> | |||
/// Sends a file to this <paramref name="text"/> channel, with an optional caption. | |||
/// </summary> | |||
Task<IUserMessage> SendFileAsync(string filePath, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
#endif | |||
/// <summary> Sends a file to this text channel, with an optional caption. </summary> | |||
/// <summary> | |||
/// Sends a file to this <paramref name="text"/> channel, with an optional caption. | |||
/// </summary> | |||
Task<IUserMessage> SendFileAsync(Stream stream, string filename, string text = null, bool isTTS = false, Embed embed = null, RequestOptions options = null); | |||
/// <summary> Gets a message from this message channel with the given id, or null if not found. </summary> | |||
/// <summary> | |||
/// Gets a message from this message channel with the given id, or <see langword="null"/> if not found. | |||
/// </summary> | |||
Task<IMessage> GetMessageAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the last N messages from this message channel. </summary> | |||
/// <summary> | |||
/// Gets the last N messages from this message channel. | |||
/// </summary> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of messages in this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of messages in this channel. | |||
/// </summary> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of messages in this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of messages in this channel. | |||
/// </summary> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of pinned messages in this channel. </summary> | |||
/// <summary> | |||
/// Gets a collection of pinned messages in this channel. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IMessage>> GetPinnedMessagesAsync(RequestOptions options = null); | |||
/// <summary> Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds. </summary> | |||
/// <summary> | |||
/// Broadcasts the "user is typing" message to all users in this channel, lasting 10 seconds. | |||
/// </summary> | |||
Task TriggerTypingAsync(RequestOptions options = null); | |||
/// <summary> Continuously broadcasts the "user is typing" message to all users in this channel until the returned object is disposed. </summary> | |||
/// <summary> | |||
/// Continuously broadcasts the "user is typing" message to all users in this channel until the returned | |||
/// object is disposed. | |||
/// </summary> | |||
IDisposable EnterTypingState(RequestOptions options = null); | |||
} | |||
} |
@@ -1,9 +1,15 @@ | |||
using System.Collections.Generic; | |||
using System.Collections.Generic; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic channel that is private to select recipients. | |||
/// </summary> | |||
public interface IPrivateChannel : IChannel | |||
{ | |||
/// <summary> | |||
/// Users that can access this channel. | |||
/// </summary> | |||
IReadOnlyCollection<IUser> Recipients { get; } | |||
} | |||
} |
@@ -1,31 +1,50 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic channel in a guild that can send and receive messages. | |||
/// </summary> | |||
public interface ITextChannel : IMessageChannel, IMentionable, IGuildChannel | |||
{ | |||
/// <summary> Checks if the channel is NSFW. </summary> | |||
/// <summary> | |||
/// Gets whether the channel is NSFW. | |||
/// </summary> | |||
bool IsNsfw { get; } | |||
/// <summary> Gets the current topic for this text channel. </summary> | |||
/// <summary> | |||
/// Gets the current topic for this text channel. | |||
/// </summary> | |||
string Topic { get; } | |||
/// <summary> Bulk deletes multiple messages. </summary> | |||
/// <summary> | |||
/// Bulk deletes multiple messages. | |||
/// </summary> | |||
Task DeleteMessagesAsync(IEnumerable<IMessage> messages, RequestOptions options = null); | |||
/// <summary> Bulk deletes multiple messages. </summary> | |||
/// <summary> | |||
/// Bulk deletes multiple messages. | |||
/// </summary> | |||
Task DeleteMessagesAsync(IEnumerable<ulong> messageIds, RequestOptions options = null); | |||
/// <summary> Modifies this text channel. </summary> | |||
/// <summary> | |||
/// Modifies this text channel. | |||
/// </summary> | |||
Task ModifyAsync(Action<TextChannelProperties> func, RequestOptions options = null); | |||
/// <summary> Creates a webhook in this text channel. </summary> | |||
/// <summary> | |||
/// Creates a webhook in this text channel. | |||
/// </summary> | |||
Task<IWebhook> CreateWebhookAsync(string name, Stream avatar = null, RequestOptions options = null); | |||
/// <summary> Gets the webhook in this text channel with the provided id, or null if not found. </summary> | |||
/// <summary> | |||
/// Gets the webhook in this text channel with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null); | |||
/// <summary> Gets the webhooks for this text channel. </summary> | |||
/// <summary> | |||
/// Gets the webhooks for this text channel. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IWebhook>> GetWebhooksAsync(RequestOptions options = null); | |||
} | |||
} | |||
} |
@@ -1,16 +1,26 @@ | |||
using System; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a voice channel in a guild. | |||
/// </summary> | |||
public interface IVoiceChannel : IGuildChannel, IAudioChannel | |||
{ | |||
/// <summary> Gets the bitrate, in bits per second, clients in this voice channel are requested to use. </summary> | |||
/// <summary> | |||
/// Gets the bitrate, in bits per second, clients in this voice channel are requested to use. | |||
/// </summary> | |||
int Bitrate { get; } | |||
/// <summary> Gets the max amount of users allowed to be connected to this channel at one time. </summary> | |||
/// <summary> | |||
/// Gets the max amount of users allowed to be connected to this channel at one time, or | |||
/// <see langword="null"/> if none is set. | |||
/// </summary> | |||
int? UserLimit { get; } | |||
/// <summary> Modifies this voice channel. </summary> | |||
/// <summary> | |||
/// Modifies this voice channel. | |||
/// </summary> | |||
Task ModifyAsync(Action<VoiceChannelProperties> func, RequestOptions options = null); | |||
} | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Properties that are used to reorder an <see cref="IGuildChannel"/>. </summary> | |||
/// <summary> | |||
/// Properties that are used to reorder an <see cref="IGuildChannel" /> . | |||
/// </summary> | |||
public class ReorderChannelProperties | |||
{ | |||
/// <summary> Gets the ID of the channel to apply this position to. </summary> | |||
/// <summary> | |||
/// Gets the ID of the channel to apply this position to. | |||
/// </summary> | |||
public ulong Id { get; } | |||
/// <summary> Gets the new zero-based position of this channel. </summary> | |||
/// <summary> | |||
/// Gets the new zero-based position of this channel. | |||
/// </summary> | |||
public int Position { get; } | |||
/// <summary> Creates a <see cref="ReorderChannelProperties"/> used to reorder a channel. </summary> | |||
@@ -1,14 +1,16 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <inheritdoc /> | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="ITextChannel"/> with the specified changes. | |||
/// </summary> | |||
public class TextChannelProperties : GuildChannelProperties | |||
{ | |||
/// <summary> | |||
/// What the topic of the channel should be set to. | |||
/// Gets or sets the topic of the channel. | |||
/// </summary> | |||
public Optional<string> Topic { get; set; } | |||
/// <summary> | |||
/// Should this channel be flagged as NSFW? | |||
/// Gets or sets whether this channel should be flagged as NSFW. | |||
/// </summary> | |||
public Optional<bool> IsNsfw { get; set; } | |||
} | |||
@@ -1,14 +1,16 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <inheritdoc /> | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="IVoiceChannel" /> with the specified changes. | |||
/// </summary> | |||
public class VoiceChannelProperties : GuildChannelProperties | |||
{ | |||
/// <summary> | |||
/// The bitrate of the voice connections in this channel. Must be greater than 8000 | |||
/// Gets or sets the bitrate of the voice connections in this channel. Must be greater than 8000. | |||
/// </summary> | |||
public Optional<int> Bitrate { get; set; } | |||
/// <summary> | |||
/// The maximum number of users that can be present in a channel. | |||
/// Gets or sets the maximum number of users that can be present in a channel, or <see langword="null"/> if none. | |||
/// </summary> | |||
public Optional<int?> UserLimit { get; set; } | |||
} | |||
@@ -1,17 +1,25 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> A Unicode emoji. </summary> | |||
/// <summary> | |||
/// A Unicode emoji. | |||
/// </summary> | |||
public class Emoji : IEmote | |||
{ | |||
// TODO: need to constrain this to Unicode-only emojis somehow | |||
/// <summary> Gets the Unicode representation of this emote. </summary> | |||
/// <summary> | |||
/// Gets the Unicode representation of this emote. | |||
/// </summary> | |||
public string Name { get; } | |||
/// <summary> Gets the Unicode representation of this emote. </summary> | |||
/// <summary> | |||
/// Gets the Unicode representation of this emote. | |||
/// </summary> | |||
public override string ToString() => Name; | |||
/// <summary> Creates a Unicode emoji. </summary> | |||
/// <param name="unicode">The pure UTF-8 encoding of an emoji</param> | |||
/// <summary> | |||
/// Creates a Unicode emoji. | |||
/// </summary> | |||
/// <param name="unicode">The pure UTF-8 encoding of an emoji.</param> | |||
public Emoji(string unicode) | |||
{ | |||
Name = unicode; | |||
@@ -3,18 +3,30 @@ using System.Globalization; | |||
namespace Discord | |||
{ | |||
/// <summary> A custom image-based emote. </summary> | |||
/// <summary> | |||
/// A custom image-based emote. | |||
/// </summary> | |||
public class Emote : IEmote, ISnowflakeEntity | |||
{ | |||
/// <summary> Gets the display name (tooltip) of this emote. </summary> | |||
/// <summary> | |||
/// Gets the display name (tooltip) of this emote. | |||
/// </summary> | |||
public string Name { get; } | |||
/// <summary> Gets the ID of this emote. </summary> | |||
/// <summary> | |||
/// Gets the ID of this emote. | |||
/// </summary> | |||
public ulong Id { get; } | |||
/// <summary> Gets whether this emote animated? </summary> | |||
/// <summary> | |||
/// Gets whether this emote is animated. | |||
/// </summary> | |||
public bool Animated { get; } | |||
/// <summary> Gets the date when this emote is created. </summary> | |||
/// <summary> | |||
/// Gets the date when this emote is created. | |||
/// </summary> | |||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | |||
/// <summary> Gets the image URL of this emote. </summary> | |||
/// <summary> | |||
/// Gets the image URL of this emote. | |||
/// </summary> | |||
public string Url => CDN.GetEmojiUrl(Id, Animated); | |||
internal Emote(ulong id, string name, bool animated) | |||
@@ -3,7 +3,9 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> An image-based emote that is attached to a guild. </summary> | |||
/// <summary> | |||
/// An image-based emote that is attached to a guild. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class GuildEmote : Emote | |||
{ | |||
@@ -1,9 +1,13 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a general container for any type of emote in a message. </summary> | |||
/// <summary> | |||
/// Represents a general container for any type of emote in a message. | |||
/// </summary> | |||
public interface IEmote | |||
{ | |||
/// <summary> Gets the display name or Unicode representation of this emote. </summary> | |||
/// <summary> | |||
/// Gets the display name or Unicode representation of this emote. | |||
/// </summary> | |||
string Name { get; } | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the default message notification behavior the guild uses. </summary> | |||
/// <summary> | |||
/// Specifies the default message notification behavior the guild uses. | |||
/// </summary> | |||
public enum DefaultMessageNotifications | |||
{ | |||
/// <summary> By default, all messages will trigger notifications. </summary> | |||
/// <summary> | |||
/// By default, all messages will trigger notifications. | |||
/// </summary> | |||
AllMessages = 0, | |||
/// <summary> By default, only mentions will trigger notifications. </summary> | |||
/// <summary> | |||
/// By default, only mentions will trigger notifications. | |||
/// </summary> | |||
MentionsOnly = 1 | |||
} | |||
} |
@@ -1,20 +1,20 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify the widget of an <see cref="IGuild"/> with the specified changes. | |||
/// Properties that are used to modify the widget of an <see cref="IGuild" /> with the specified changes. | |||
/// </summary> | |||
public class GuildEmbedProperties | |||
{ | |||
/// <summary> | |||
/// Should the widget be enabled? | |||
/// Sets whether the widget should be enabled. | |||
/// </summary> | |||
public Optional<bool> Enabled { get; set; } | |||
/// <summary> | |||
/// What channel should the invite place users in, if not null. | |||
/// Sets the channel that the invite should place its users in, if not <see langword="null"/>. | |||
/// </summary> | |||
public Optional<IChannel> Channel { get; set; } | |||
/// <summary> | |||
/// What channel should the invite place users in, if not null. | |||
/// Sets the channel the invite should place its users in, if not <see langword="null"/>. | |||
/// </summary> | |||
public Optional<ulong?> ChannelId { get; set; } | |||
} | |||
@@ -1,13 +1,21 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Properties used to modify an <see cref="IGuildIntegration"/> with the specified changes.</summary> | |||
/// <summary> | |||
/// Properties used to modify an <see cref="IGuildIntegration" /> with the specified changes. | |||
/// </summary> | |||
public class GuildIntegrationProperties | |||
{ | |||
/// <summary> Gets or sets the behavior when an integration subscription lapses. </summary> | |||
/// <summary> | |||
/// Gets or sets the behavior when an integration subscription lapses. | |||
/// </summary> | |||
public Optional<int> ExpireBehavior { get; set; } | |||
/// <summary> Gets or sets the period (in seconds) where the integration will ignore lapsed subscriptions. </summary> | |||
/// <summary> | |||
/// Gets or sets the period (in seconds) where the integration will ignore lapsed subscriptions. | |||
/// </summary> | |||
public Optional<int> ExpireGracePeriod { get; set; } | |||
/// <summary> Gets or sets whether emoticons should be synced for this integration. </summary> | |||
/// <summary> | |||
/// Gets or sets whether emoticons should be synced for this integration. | |||
/// </summary> | |||
public Optional<bool> EnableEmoticons { get; set; } | |||
} | |||
} |
@@ -1,78 +1,79 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="IGuild"/> with the specified changes. | |||
/// Properties that are used to modify an <see cref="IGuild" /> with the specified changes. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await Context.Guild.ModifyAsync(async x => | |||
/// { | |||
/// x.Name = "aaaaaah"; | |||
/// x.RegionId = (await Context.Client.GetOptimalVoiceRegionAsync()).Id; | |||
/// }); | |||
/// <code lang="c#"> | |||
/// await Context.Guild.ModifyAsync(async x => | |||
/// { | |||
/// x.Name = "aaaaaah"; | |||
/// x.RegionId = (await Context.Client.GetOptimalVoiceRegionAsync()).Id; | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
/// <see cref="IGuild"/> | |||
/// <see cref="T:Discord.IGuild" /> | |||
public class GuildProperties | |||
{ | |||
public Optional<string> Username { get; set; } | |||
/// <summary> | |||
/// The name of the Guild. | |||
/// Gets or sets the name of the Guild. | |||
/// </summary> | |||
public Optional<string> Name { get; set; } | |||
/// <summary> | |||
/// The region for the Guild's voice connections. | |||
/// Gets or sets the region for the Guild's voice connections. | |||
/// </summary> | |||
public Optional<IVoiceRegion> Region { get; set; } | |||
/// <summary> | |||
/// The ID of the region for the Guild's voice connections. | |||
/// Gets or sets the ID of the region for the Guild's voice connections. | |||
/// </summary> | |||
public Optional<string> RegionId { get; set; } | |||
/// <summary> | |||
/// What verification level new users need to achieve before speaking. | |||
/// Gets or sets the verification level new users need to achieve before speaking. | |||
/// </summary> | |||
public Optional<VerificationLevel> VerificationLevel { get; set; } | |||
/// <summary> | |||
/// The default message notification state for the guild. | |||
/// Gets or sets the default message notification state for the guild. | |||
/// </summary> | |||
public Optional<DefaultMessageNotifications> DefaultMessageNotifications { get; set; } | |||
/// <summary> | |||
/// How many seconds before a user is sent to AFK. This value MUST be one of: (60, 300, 900, 1800, 3600). | |||
/// Gets or sets how many seconds before a user is sent to AFK. This value MUST be one of: (60, 300, 900, | |||
/// 1800, 3600). | |||
/// </summary> | |||
public Optional<int> AfkTimeout { get; set; } | |||
/// <summary> | |||
/// The icon of the guild. | |||
/// Gets or sets the icon of the guild. | |||
/// </summary> | |||
public Optional<Image?> Icon { get; set; } | |||
/// <summary> | |||
/// The guild's splash image. | |||
/// Gets or sets the guild's splash image. | |||
/// </summary> | |||
/// <remarks> | |||
/// The guild must be partnered for this value to have any effect. | |||
/// The guild must be partnered for this value to have any effect. | |||
/// </remarks> | |||
public Optional<Image?> Splash { get; set; } | |||
/// <summary> | |||
/// The IVoiceChannel where AFK users should be sent. | |||
/// Gets or sets the <see cref="IVoiceChannel"/> where AFK users should be sent. | |||
/// </summary> | |||
public Optional<IVoiceChannel> AfkChannel { get; set; } | |||
/// <summary> | |||
/// The ID of the IVoiceChannel where AFK users should be sent. | |||
/// Gets or sets the ID of the <see cref="IVoiceChannel"/> where AFK users should be sent. | |||
/// </summary> | |||
public Optional<ulong?> AfkChannelId { get; set; } | |||
/// <summary> | |||
/// The ITextChannel where System messages should be sent. | |||
/// Gets or sets the <see cref="ITextChannel" /> where System messages should be sent. | |||
/// </summary> | |||
public Optional<ITextChannel> SystemChannel { get; set; } | |||
/// <summary> | |||
/// The ID of the ITextChannel where System messages should be sent. | |||
/// Gets or sets the ID of the <see cref="ITextChannel" /> where System messages should be sent. | |||
/// </summary> | |||
public Optional<ulong?> SystemChannelId { get; set; } | |||
/// <summary> | |||
/// The owner of this guild. | |||
/// Gets or sets the owner of this guild. | |||
/// </summary> | |||
public Optional<IUser> Owner { get; set; } | |||
/// <summary> | |||
/// The ID of the owner of this guild. | |||
/// Gets or sets the ID of the owner of this guild. | |||
/// </summary> | |||
public Optional<ulong> OwnerId { get; set; } | |||
} | |||
@@ -1,8 +1,17 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic ban object. | |||
/// </summary> | |||
public interface IBan | |||
{ | |||
/// <summary> | |||
/// Gets the banned user. | |||
/// </summary> | |||
IUser User { get; } | |||
/// <summary> | |||
/// Gets the reason why the user is banned. | |||
/// </summary> | |||
string Reason { get; } | |||
} | |||
} |
@@ -7,166 +7,310 @@ namespace Discord | |||
{ | |||
public interface IGuild : IDeletable, ISnowflakeEntity | |||
{ | |||
/// <summary> Gets the name of this guild. </summary> | |||
/// <summary> | |||
/// Gets the name of this guild. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are automatically moved to the AFK voice channel, if one is set. </summary> | |||
/// <summary> | |||
/// Gets the amount of time (in seconds) a user must be inactive in a voice channel for until they are | |||
/// automatically moved to the AFK voice channel, if one is set. | |||
/// </summary> | |||
int AFKTimeout { get; } | |||
/// <summary> Returns true if this guild is embeddable (e.g. widget) </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this guild is embeddable (e.g. widget) | |||
/// </summary> | |||
bool IsEmbeddable { get; } | |||
/// <summary> Gets the default message notifications for users who haven't explicitly set their notification settings. </summary> | |||
/// <summary> | |||
/// Gets the default message notifications for users who haven't explicitly set their notification settings. | |||
/// </summary> | |||
DefaultMessageNotifications DefaultMessageNotifications { get; } | |||
/// <summary> Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to perform administrative actions in this guild. </summary> | |||
/// <summary> | |||
/// Gets the level of Multi-Factor Authentication requirements a user must fulfill before being allowed to | |||
/// perform administrative actions in this guild. | |||
/// </summary> | |||
MfaLevel MfaLevel { get; } | |||
/// <summary> Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. </summary> | |||
/// <summary> | |||
/// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. | |||
/// </summary> | |||
VerificationLevel VerificationLevel { get; } | |||
/// <summary> Returns the ID of this guild's icon, or null if one is not set. </summary> | |||
/// <summary> | |||
/// Returns the ID of this guild's icon, or <see langword="null"/> if one is not set. | |||
/// </summary> | |||
string IconId { get; } | |||
/// <summary> Returns the url to this guild's icon, or null if one is not set. </summary> | |||
/// <summary> | |||
/// Returns the URL of this guild's icon, or <see langword="null"/> if one is not set. | |||
/// </summary> | |||
string IconUrl { get; } | |||
/// <summary> Returns the ID of this guild's splash image, or null if one is not set. </summary> | |||
/// <summary> | |||
/// Returns the ID of this guild's splash image, or <see langword="null"/> if one is not set. | |||
/// </summary> | |||
string SplashId { get; } | |||
/// <summary> Returns the url to this guild's splash image, or null if one is not set. </summary> | |||
/// <summary> | |||
/// Returns the URL of this guild's splash image, or <see langword="null"/> if one is not set. | |||
/// </summary> | |||
string SplashUrl { get; } | |||
/// <summary> Returns true if this guild is currently connected and ready to be used. Only applies to the WebSocket client. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this guild is currently connected and ready to be used. Only applies | |||
/// to the WebSocket client. | |||
/// </summary> | |||
bool Available { get; } | |||
/// <summary> Gets the ID of the AFK voice channel for this guild if set, or null if not. </summary> | |||
/// <summary> | |||
/// Gets the ID of the AFK voice channel for this guild if set, or <see langword="null"/> if not. | |||
/// </summary> | |||
ulong? AFKChannelId { get; } | |||
/// <summary> Gets the ID of the the default channel for this guild. </summary> | |||
/// <summary> | |||
/// Gets the ID of the the default channel for this guild. | |||
/// </summary> | |||
ulong DefaultChannelId { get; } | |||
/// <summary> Gets the ID of the embed channel for this guild if set, or null if not. </summary> | |||
/// <summary> | |||
/// Gets the ID of the embed channel for this guild if set, or <see langword="null"/> if not. | |||
/// </summary> | |||
ulong? EmbedChannelId { get; } | |||
/// <summary> Gets the ID of the channel where randomized welcome messages are sent, or null if not. </summary> | |||
/// <summary> | |||
/// Gets the ID of the channel where randomized welcome messages are sent, or <see langword="null"/> if not. | |||
/// </summary> | |||
ulong? SystemChannelId { get; } | |||
/// <summary> Gets the ID of the user that created this guild. </summary> | |||
/// <summary> | |||
/// Gets the ID of the user that created this guild. | |||
/// </summary> | |||
ulong OwnerId { get; } | |||
/// <summary> Gets the ID of the region hosting this guild's voice channels. </summary> | |||
/// <summary> | |||
/// Gets the ID of the region hosting this guild's voice channels. | |||
/// </summary> | |||
string VoiceRegionId { get; } | |||
/// <summary> Gets the <see cref="IAudioClient"/> currently associated with this guild. </summary> | |||
/// <summary> | |||
/// Gets the <see cref="IAudioClient" /> currently associated with this guild. | |||
/// </summary> | |||
IAudioClient AudioClient { get; } | |||
/// <summary> Gets the built-in role containing all users in this guild. </summary> | |||
/// <summary> | |||
/// Gets the built-in role containing all users in this guild. | |||
/// </summary> | |||
IRole EveryoneRole { get; } | |||
/// <summary> Gets a collection of all custom emojis for this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all custom emotes for this guild. | |||
/// </summary> | |||
IReadOnlyCollection<GuildEmote> Emotes { get; } | |||
/// <summary> Gets a collection of all extra features added to this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all extra features added to this guild. | |||
/// </summary> | |||
IReadOnlyCollection<string> Features { get; } | |||
/// <summary> Gets a collection of all roles in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all roles in this guild. | |||
/// </summary> | |||
IReadOnlyCollection<IRole> Roles { get; } | |||
/// <summary> Modifies this guild. </summary> | |||
/// <summary> | |||
/// Modifies this guild. | |||
/// </summary> | |||
Task ModifyAsync(Action<GuildProperties> func, RequestOptions options = null); | |||
/// <summary> Modifies this guild's embed. </summary> | |||
/// <summary> | |||
/// Modifies this guild's embed channel. | |||
/// </summary> | |||
Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null); | |||
/// <summary> Bulk modifies the channels of this guild. </summary> | |||
/// <summary> | |||
/// Bulk modifies the order of channels in this guild. | |||
/// </summary> | |||
Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null); | |||
/// <summary> Bulk modifies the roles of this guild. </summary> | |||
/// <summary> | |||
/// Bulk modifies the order of roles in this guild. | |||
/// </summary> | |||
Task ReorderRolesAsync(IEnumerable<ReorderRoleProperties> args, RequestOptions options = null); | |||
/// <summary> Leaves this guild. If you are the owner, use Delete instead. </summary> | |||
/// <summary> | |||
/// Leaves this guild. If you are the owner, use | |||
/// <see cref="IDeletable.DeleteAsync(Discord.RequestOptions)" /> instead. | |||
/// </summary> | |||
Task LeaveAsync(RequestOptions options = null); | |||
/// <summary> Gets a collection of all users banned on this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all users banned on this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IBan>> GetBansAsync(RequestOptions options = null); | |||
/// <summary> Bans the provided user from this guild and optionally prunes their recent messages. </summary> | |||
/// <param name="user"> The user to ban. </param> | |||
/// <param name="pruneDays"> The number of days to remove messages from this user for - must be between [0, 7]</param> | |||
/// <param name="reason"> The reason of the ban to be written in the audit log. </param> | |||
/// <summary> | |||
/// Bans the provided <paramref name="user"/> from this guild and optionally prunes their recent messages. | |||
/// </summary> | |||
/// <param name="user"> | |||
/// The user to ban. | |||
/// </param> | |||
/// <param name="pruneDays"> | |||
/// The number of days to remove messages from this <paramref name="user"/> for - must be between [0, 7] | |||
/// </param> | |||
/// <param name="reason"> | |||
/// The reason of the ban to be written in the audit log. | |||
/// </param> | |||
Task AddBanAsync(IUser user, int pruneDays = 0, string reason = null, RequestOptions options = null); | |||
/// <summary> Bans the provided user ID from this guild and optionally prunes their recent messages. </summary> | |||
/// <param name="userId"> The ID of the user to ban. </param> | |||
/// <param name="pruneDays">The number of days to remove messages from this user for - must be between [0, 7]</param> | |||
/// <param name="reason"> The reason of the ban to be written in the audit log. </param> | |||
/// <summary> | |||
/// Bans the provided user ID from this guild and optionally prunes their recent messages. | |||
/// </summary> | |||
/// <param name="userId"> | |||
/// The ID of the user to ban. | |||
/// </param> | |||
/// <param name="pruneDays"> | |||
/// The number of days to remove messages from this user for - must be between [0, 7] | |||
/// </param> | |||
/// <param name="reason"> | |||
/// The reason of the ban to be written in the audit log. | |||
/// </param> | |||
Task AddBanAsync(ulong userId, int pruneDays = 0, string reason = null, RequestOptions options = null); | |||
/// <summary> Unbans the provided user if it is currently banned. </summary> | |||
/// <summary> | |||
/// Unbans the provided <paramref name="user"/> if they are currently banned. | |||
/// </summary> | |||
Task RemoveBanAsync(IUser user, RequestOptions options = null); | |||
/// <summary> Unbans the provided user ID if it is currently banned. </summary> | |||
/// <summary> | |||
/// Unbans the provided user ID if it is currently banned. | |||
/// </summary> | |||
Task RemoveBanAsync(ulong userId, RequestOptions options = null); | |||
/// <summary> Gets a collection of all channels in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all channels in this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IGuildChannel>> GetChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the channel in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The channel ID. </param> | |||
/// <summary> | |||
/// Gets the channel in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The channel ID.</param> | |||
Task<IGuildChannel> GetChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of all text channels in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all text channels in this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<ITextChannel>> GetTextChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a text channel in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The text channel ID. </param> | |||
/// <summary> | |||
/// Gets a text channel in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The text channel ID.</param> | |||
Task<ITextChannel> GetTextChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of all voice channels in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all voice channels in this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IVoiceChannel>> GetVoiceChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets a collection of all category channels in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all category channels in this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<ICategoryChannel>> GetCategoriesAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the voice channel in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The text channel ID. </param> | |||
/// <summary> | |||
/// Gets the voice channel in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The text channel ID.</param> | |||
Task<IVoiceChannel> GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the voice AFK channel in this guild with the provided ID, or null if not found. </summary> | |||
/// <summary> | |||
/// Gets the voice AFK channel in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
Task<IVoiceChannel> GetAFKChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the default system text channel in this guild with the provided ID, or null if none is set. </summary> | |||
/// <summary> | |||
/// Gets the default system text channel in this guild with the provided ID, or <see langword="null"/> if | |||
/// none is set. | |||
/// </summary> | |||
Task<ITextChannel> GetSystemChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the top viewable text channel in this guild with the provided ID, or null if not found. </summary> | |||
/// <summary> | |||
/// Gets the top viewable text channel in this guild with the provided ID, or <see langword="null"/> if not | |||
/// found. | |||
/// </summary> | |||
Task<ITextChannel> GetDefaultChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the embed channel in this guild. </summary> | |||
/// <summary> | |||
/// Gets the embed channel in this guild. | |||
/// </summary> | |||
Task<IGuildChannel> GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Creates a new text channel. </summary> | |||
/// <param name="name"> The new name for the text channel. </param> | |||
/// <summary> | |||
/// Creates a new text channel. | |||
/// </summary> | |||
/// <param name="name">The new name for the text channel.</param> | |||
Task<ITextChannel> CreateTextChannelAsync(string name, RequestOptions options = null); | |||
/// <summary> Creates a new voice channel. </summary> | |||
/// <param name="name"> The new name for the voice channel. </param> | |||
/// <summary> | |||
/// Creates a new voice channel. | |||
/// </summary> | |||
/// <param name="name">The new name for the voice channel.</param> | |||
Task<IVoiceChannel> CreateVoiceChannelAsync(string name, RequestOptions options = null); | |||
/// <summary> Creates a new channel category. </summary> | |||
/// <param name="name"> The new name for the category. </param> | |||
/// <summary> | |||
/// Creates a new channel category. | |||
/// </summary> | |||
/// <param name="name">The new name for the category.</param> | |||
Task<ICategoryChannel> CreateCategoryAsync(string name, RequestOptions options = null); | |||
Task<IReadOnlyCollection<IGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null); | |||
Task<IGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null); | |||
/// <summary> Gets a collection of all invites to this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all invites to this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(RequestOptions options = null); | |||
/// <summary> Gets the role in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The role ID. </param> | |||
/// <summary> | |||
/// Gets the role in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The role ID.</param> | |||
IRole GetRole(ulong id); | |||
/// <summary> Creates a new role with the provided name. </summary> | |||
/// <param name="name"> The new name for the role. </param> | |||
/// <param name="permissions"> The guild permission that the role should possess. </param> | |||
/// <param name="color"> The color of the role. </param> | |||
/// <param name="isHoisted"> Whether the role is separated from others on the sidebar. </param> | |||
/// <summary> | |||
/// Creates a new role with the provided name. | |||
/// </summary> | |||
/// <param name="name">The new name for the role.</param> | |||
/// <param name="permissions">The guild permission that the role should possess.</param> | |||
/// <param name="color">The color of the role.</param> | |||
/// <param name="isHoisted">Whether the role is separated from others on the sidebar.</param> | |||
Task<IRole> CreateRoleAsync(string name, GuildPermissions? permissions = null, Color? color = null, bool isHoisted = false, RequestOptions options = null); | |||
/// <summary> Gets a collection of all users in this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all users in this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IGuildUser>> GetUsersAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); //TODO: shouldnt this be paged? | |||
/// <summary> Gets the user in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The user ID. </param> | |||
/// <summary> | |||
/// Gets the user in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The user ID.</param> | |||
Task<IGuildUser> GetUserAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the current user for this guild. </summary> | |||
/// <summary> | |||
/// Gets the current user for this guild. | |||
/// </summary> | |||
Task<IGuildUser> GetCurrentUserAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Gets the owner of this guild. </summary> | |||
/// <summary> | |||
/// Gets the owner of this guild. | |||
/// </summary> | |||
Task<IGuildUser> GetOwnerAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> Downloads all users for this guild if the current list is incomplete. </summary> | |||
/// <summary> | |||
/// Downloads all users for this guild if the current list is incomplete. | |||
/// </summary> | |||
Task DownloadUsersAsync(); | |||
/// <summary> Removes all users from this guild if they have not logged on in a provided number of days or, if simulate is true, returns the number of users that would be removed. </summary> | |||
/// <param name="days"> The number of days required for the users to be kicked. </param> | |||
/// <param name="simulate"> Whether this prune action is a simulation. </param> | |||
/// <return> The number of users removed from this guild. </return> | |||
/// <summary> | |||
/// Removes all users from this guild if they have not logged on in a provided number of | |||
/// <paramref name="days"/> or, if <paramref name="simulate"/> is true, returns the number of users that | |||
/// would be removed. | |||
/// </summary> | |||
/// <param name="days">The number of days required for the users to be kicked.</param> | |||
/// <param name="simulate">Whether this prune action is a simulation.</param> | |||
/// <returns> | |||
/// The number of users removed from this guild. | |||
/// </returns> | |||
Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null); | |||
/// <summary> Gets the webhook in this guild with the provided ID, or null if not found. </summary> | |||
/// <param name="id"> The webhook ID. </param> | |||
/// <summary> | |||
/// Gets the webhook in this guild with the provided ID, or <see langword="null"/> if not found. | |||
/// </summary> | |||
/// <param name="id">The webhook ID.</param> | |||
Task<IWebhook> GetWebhookAsync(ulong id, RequestOptions options = null); | |||
/// <summary> Gets a collection of all webhooks for this guild. </summary> | |||
/// <summary> | |||
/// Gets a collection of all webhooks from this guild. | |||
/// </summary> | |||
Task<IReadOnlyCollection<IWebhook>> GetWebhooksAsync(RequestOptions options = null); | |||
/// <summary> Gets a specific emote from this guild. </summary> | |||
/// <param name="id"> The guild emote ID. </param> | |||
/// <summary> | |||
/// Gets a specific emote from this guild. | |||
/// </summary> | |||
/// <param name="id">The guild emote ID.</param> | |||
Task<GuildEmote> GetEmoteAsync(ulong id, RequestOptions options = null); | |||
/// <summary> Creates a new emote in this guild. </summary> | |||
/// <param name="name"> The name of the guild emote. </param> | |||
/// <param name="image"> The image of the new emote. </param> | |||
/// <param name="roles"> The roles to limit the emote usage to. </param> | |||
/// <summary> | |||
/// Creates a new emote in this guild. | |||
/// </summary> | |||
/// <param name="name">The name of the guild emote.</param> | |||
/// <param name="image">The image of the new emote.</param> | |||
/// <param name="roles">The roles to limit the emote usage to.</param> | |||
Task<GuildEmote> CreateEmoteAsync(string name, Image image, Optional<IEnumerable<IRole>> roles = default(Optional<IEnumerable<IRole>>), RequestOptions options = null); | |||
/// <summary> Modifies an existing emote in this guild. </summary> | |||
/// <summary> | |||
/// Modifies an existing <paramref name="emote"/> in this guild. | |||
/// </summary> | |||
Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null); | |||
/// <summary> Deletes an existing emote from this guild. </summary> | |||
/// <param name="emote"> The guild emote to delete. </param> | |||
/// <summary> | |||
/// Deletes an existing <paramref name="emote"/> from this guild. | |||
/// </summary> | |||
/// <param name="emote">The guild emote to delete.</param> | |||
Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null); | |||
} | |||
} |
@@ -1,18 +1,33 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a region of which the user connects to when using voice. | |||
/// </summary> | |||
public interface IVoiceRegion | |||
{ | |||
/// <summary> Gets the unique identifier for this voice region. </summary> | |||
/// <summary> | |||
/// Gets the unique identifier for this voice region. | |||
/// </summary> | |||
string Id { get; } | |||
/// <summary> Gets the name of this voice region. </summary> | |||
/// <summary> | |||
/// Gets the name of this voice region. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Returns true if this voice region is exclusive to VIP accounts. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this voice region is exclusive to VIP accounts. | |||
/// </summary> | |||
bool IsVip { get; } | |||
/// <summary> Returns true if this voice region is the closest to your machine. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this voice region is the closest to your machine. | |||
/// </summary> | |||
bool IsOptimal { get; } | |||
/// <summary> Gets an example hostname for this voice region. </summary> | |||
/// <summary> | |||
/// Gets an example hostname for this voice region. | |||
/// </summary> | |||
string SampleHostname { get; } | |||
/// <summary> Gets an example port for this voice region. </summary> | |||
/// <summary> | |||
/// Gets an example port for this voice region. | |||
/// </summary> | |||
int SamplePort { get; } | |||
} | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the guild's Multi-Factor Authentication (MFA) level requirement. </summary> | |||
/// <summary> | |||
/// Specifies the guild's Multi-Factor Authentication (MFA) level requirement. | |||
/// </summary> | |||
public enum MfaLevel | |||
{ | |||
/// <summary> Users have no additional MFA restriction on this guild. </summary> | |||
/// <summary> | |||
/// Users have no additional MFA restriction on this guild. | |||
/// </summary> | |||
Disabled = 0, | |||
/// <summary> Users must have MFA enabled on their account to perform administrative actions. </summary> | |||
/// <summary> | |||
/// Users must have MFA enabled on their account to perform administrative actions. | |||
/// </summary> | |||
Enabled = 1 | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the target of the permission. </summary> | |||
/// <summary> | |||
/// Specifies the target of the permission. | |||
/// </summary> | |||
public enum PermissionTarget | |||
{ | |||
/// <summary> The target of the permission is a role. </summary> | |||
/// <summary> | |||
/// The target of the permission is a role. | |||
/// </summary> | |||
Role, | |||
/// <summary> The target of the permission is a user. </summary> | |||
/// <summary> | |||
/// The target of the permission is a user. | |||
/// </summary> | |||
User | |||
} | |||
} |
@@ -1,17 +1,29 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the verification level the guild uses. </summary> | |||
/// <summary> | |||
/// Specifies the verification level the guild uses. | |||
/// </summary> | |||
public enum VerificationLevel | |||
{ | |||
/// <summary> Users have no additional restrictions on sending messages to this guild. </summary> | |||
/// <summary> | |||
/// Users have no additional restrictions on sending messages to this guild. | |||
/// </summary> | |||
None = 0, | |||
/// <summary> Users must have a verified email on their account. </summary> | |||
/// <summary> | |||
/// Users must have a verified email on their account. | |||
/// </summary> | |||
Low = 1, | |||
/// <summary> Users must fulfill the requirements of Low, and be registered on Discord for at least 5 minutes. </summary> | |||
/// <summary> | |||
/// Users must fulfill the requirements of Low and be registered on Discord for at least 5 minutes. | |||
/// </summary> | |||
Medium = 2, | |||
/// <summary> Users must fulfill the requirements of Medium, and be a member of this guild for at least 10 minutes. </summary> | |||
/// <summary> | |||
/// Users must fulfill the requirements of Medium and be a member of this guild for at least 10 minutes. | |||
/// </summary> | |||
High = 3, | |||
/// <summary> Users must fulfill the requirements of High, and must have a verified phone on their Discord account. </summary> | |||
/// <summary> | |||
/// Users must fulfill the requirements of High and must have a verified phone on their Discord account. | |||
/// </summary> | |||
Extreme = 4 | |||
} | |||
} |
@@ -2,10 +2,14 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents whether the object is deletable or not. </summary> | |||
/// <summary> | |||
/// Represents whether the object is deletable or not. | |||
/// </summary> | |||
public interface IDeletable | |||
{ | |||
/// <summary> Deletes this object and all its children. </summary> | |||
/// <summary> | |||
/// Deletes this object and all its children. | |||
/// </summary> | |||
Task DeleteAsync(RequestOptions options = null); | |||
} | |||
} |
@@ -8,7 +8,9 @@ namespace Discord | |||
///// <summary> Gets the IDiscordClient that created this object. </summary> | |||
//IDiscordClient Discord { get; } | |||
/// <summary> Gets the unique identifier for this object. </summary> | |||
/// <summary> | |||
/// Gets the unique identifier for this object. | |||
/// </summary> | |||
TId Id { get; } | |||
} | |||
@@ -1,9 +1,13 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Represents whether the object is mentionable or not. </summary> | |||
/// <summary> | |||
/// Represents whether the object is mentionable or not. | |||
/// </summary> | |||
public interface IMentionable | |||
{ | |||
/// <summary> Returns a special string used to mention this object. </summary> | |||
/// <summary> | |||
/// Returns a special string used to mention this object. | |||
/// </summary> | |||
string Mention { get; } | |||
} | |||
} |
@@ -5,6 +5,7 @@ namespace Discord | |||
/// <summary> Represents a Discord snowflake entity. </summary> | |||
public interface ISnowflakeEntity : IEntity<ulong> | |||
{ | |||
/// <summary> Gets when the snowflake is created. </summary> | |||
DateTimeOffset CreatedAt { get; } | |||
} | |||
} |
@@ -2,10 +2,14 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents whether the object is updatable or not. </summary> | |||
/// <summary> | |||
/// Represents whether the object is updatable or not. | |||
/// </summary> | |||
public interface IUpdateable | |||
{ | |||
/// <summary> Updates this object's properties with its current state. </summary> | |||
/// <summary> | |||
/// Updates this object's properties with its current state. | |||
/// </summary> | |||
Task UpdateAsync(RequestOptions options = null); | |||
} | |||
} |
@@ -2,25 +2,29 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// An image that will be uploaded to Discord. | |||
/// An image that will be uploaded to Discord. | |||
/// </summary> | |||
public struct Image | |||
{ | |||
public Stream Stream { get; } | |||
/// <summary> | |||
/// Create the image with a Stream. | |||
/// Create the image with a <see cref="System.IO.Stream" /> . | |||
/// </summary> | |||
/// <param name="stream">This must be some type of stream with the contents of a file in it.</param> | |||
/// <param name="stream"> | |||
/// The <see cref="System.IO.Stream" /> to create the image with. Note that this must be some type of stream | |||
/// with the contents of a file in it. | |||
/// </param> | |||
public Image(Stream stream) | |||
{ | |||
Stream = stream; | |||
} | |||
#if FILESYSTEM | |||
/// <summary> | |||
/// Create the image from a file path. | |||
/// Create the image from a file path. | |||
/// </summary> | |||
/// <remarks> | |||
/// This file path is NOT validated, and is passed directly into a <see cref="File.OpenRead(string)"/> | |||
/// This file <paramref name="path" /> is NOT validated, and is passed directly into a | |||
/// <see cref="File.OpenRead" /> | |||
/// </remarks> | |||
/// <param name="path">The path to the file.</param> | |||
public Image(string path) | |||
@@ -1,12 +1,29 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Specifies the type of format the image should return in. </summary> | |||
/// <summary> | |||
/// Specifies the type of format the image should return in. | |||
/// </summary> | |||
public enum ImageFormat | |||
{ | |||
/// <summary> | |||
/// Use automatically detected format. | |||
/// </summary> | |||
Auto, | |||
/// <summary> | |||
/// Use Google's WebP image format. | |||
/// </summary> | |||
WebP, | |||
/// <summary> | |||
/// Use PNG. | |||
/// </summary> | |||
Png, | |||
/// <summary> | |||
/// Use JPEG. | |||
/// </summary> | |||
Jpeg, | |||
/// <summary> | |||
/// Use GIF. | |||
/// </summary> | |||
Gif, | |||
} | |||
} |
@@ -1,29 +1,47 @@ | |||
using System.Threading.Tasks; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
public interface IInvite : IEntity<string>, IDeletable | |||
{ | |||
/// <summary> Gets the unique identifier for this invite. </summary> | |||
/// <summary> | |||
/// Gets the unique identifier for this invite. | |||
/// </summary> | |||
string Code { get; } | |||
/// <summary> Gets the url used to accept this invite, using Code. </summary> | |||
/// <summary> | |||
/// Gets the URL used to accept this invite, using Code. | |||
/// </summary> | |||
string Url { get; } | |||
/// <summary> Gets the channel this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the channel this invite is linked to. | |||
/// </summary> | |||
IChannel Channel { get; } | |||
/// <summary> Gets the id of the channel this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the ID of the channel this invite is linked to. | |||
/// </summary> | |||
ulong ChannelId { get; } | |||
/// <summary> Gets the name of the channel this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the name of the channel this invite is linked to. | |||
/// </summary> | |||
string ChannelName { get; } | |||
/// <summary> Gets the guild this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the guild this invite is linked to. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the id of the guild this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the ID of the guild this invite is linked to. | |||
/// </summary> | |||
ulong GuildId { get; } | |||
/// <summary> Gets the name of the guild this invite is linked to. </summary> | |||
/// <summary> | |||
/// Gets the name of the guild this invite is linked to. | |||
/// </summary> | |||
string GuildName { get; } | |||
/// <summary> Accepts this invite and joins the target guild. This will fail on bot accounts. </summary> | |||
/// <summary> | |||
/// Accepts this invite and joins the target guild. This will fail on bot accounts. | |||
/// </summary> | |||
Task AcceptAsync(RequestOptions options = null); | |||
} | |||
} |
@@ -1,22 +1,38 @@ | |||
using System; | |||
using System; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents additional information regarding the invite object. </summary> | |||
public interface IInviteMetadata : IInvite | |||
{ | |||
/// <summary> Gets the user that created this invite. </summary> | |||
/// <summary> | |||
/// Gets the user that created this invite. | |||
/// </summary> | |||
IUser Inviter { get; } | |||
/// <summary> Returns true if this invite was revoked. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this invite was revoked. | |||
/// </summary> | |||
bool IsRevoked { get; } | |||
/// <summary> Returns true if users accepting this invite will be removed from the guild when they log off. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if users accepting this invite will be removed from the guild when they | |||
/// log off. | |||
/// </summary> | |||
bool IsTemporary { get; } | |||
/// <summary> Gets the time (in seconds) until the invite expires, or null if it never expires. </summary> | |||
/// <summary> | |||
/// Gets the time (in seconds) until the invite expires, or <see langword="null"/> if it never expires. | |||
/// </summary> | |||
int? MaxAge { get; } | |||
/// <summary> Gets the max amount of times this invite may be used, or null if there is no limit. </summary> | |||
/// <summary> | |||
/// Gets the max amount of times this invite may be used, or <see langword="null"/> if there is no limit. | |||
/// </summary> | |||
int? MaxUses { get; } | |||
/// <summary> Gets the amount of times this invite has been used. </summary> | |||
/// <summary> | |||
/// Gets the amount of times this invite has been used. | |||
/// </summary> | |||
int Uses { get; } | |||
/// <summary> Gets when this invite was created. </summary> | |||
/// <summary> | |||
/// Gets when this invite was created. | |||
/// </summary> | |||
DateTimeOffset CreatedAt { get; } | |||
} | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a message sent by the system. </summary> | |||
public interface ISystemMessage : IMessage | |||
{ | |||
} | |||
@@ -23,7 +23,7 @@ namespace Discord | |||
Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null); | |||
/// <summary> Removes all reactions from this message. </summary> | |||
Task RemoveAllReactionsAsync(RequestOptions options = null); | |||
/// <summary> Gets all users that reacted to a message with a given emote </summary> | |||
/// <summary> Gets all users that reacted to a message with a given emote. </summary> | |||
Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null); | |||
/// <summary> Transforms this message's text into a human-readable form by resolving its tags. </summary> | |||
@@ -7,54 +7,97 @@ namespace Discord | |||
public enum ChannelPermission : ulong | |||
{ | |||
// General | |||
/// <summary> Allows creation of instant invites. </summary> | |||
CreateInstantInvite = 0x00_00_00_01, | |||
/// <summary> Allows management and editing of channels. </summary> | |||
ManageChannels = 0x00_00_00_10, | |||
/// <summary> | |||
/// Allows creation of instant invites. | |||
/// </summary> | |||
CreateInstantInvite = 0x00_00_00_01, | |||
/// <summary> | |||
/// Allows management and editing of channels. | |||
/// </summary> | |||
ManageChannels = 0x00_00_00_10, | |||
// Text | |||
/// <summary> Allows for the addition of reactions to messages. </summary> | |||
AddReactions = 0x00_00_00_40, | |||
/// <summary> Allows for reading of message. </summary> | |||
/// <summary> | |||
/// Allows for the addition of reactions to messages. | |||
/// </summary> | |||
AddReactions = 0x00_00_00_40, | |||
/// <summary> | |||
/// Allows for reading of message. | |||
/// </summary> | |||
[Obsolete("Use ViewChannel instead.")] | |||
ReadMessages = ViewChannel, | |||
/// <summary> Allows guild members to view a channel, which includes reading messages in text channels. </summary> | |||
ViewChannel = 0x00_00_04_00, | |||
/// <summary> Allows for sending messages in a channel. </summary> | |||
SendMessages = 0x00_00_08_00, | |||
/// <summary> Allows for sending of text-to-speech messages. </summary> | |||
SendTTSMessages = 0x00_00_10_00, | |||
/// <summary> Allows for deletion of other users messages. </summary> | |||
ManageMessages = 0x00_00_20_00, | |||
/// <summary> Allows links sent by users with this permission will be auto-embedded. </summary> | |||
EmbedLinks = 0x00_00_40_00, | |||
/// <summary> Allows for uploading images and files. </summary> | |||
AttachFiles = 0x00_00_80_00, | |||
/// <summary> Allows for reading of message history. </summary> | |||
ReadMessageHistory = 0x00_01_00_00, | |||
/// <summary> Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel. </summary> | |||
MentionEveryone = 0x00_02_00_00, | |||
/// <summary> Allows the usage of custom emojis from other servers. </summary> | |||
UseExternalEmojis = 0x00_04_00_00, | |||
ReadMessages = ViewChannel, | |||
/// <summary> | |||
/// Allows guild members to view a channel, which includes reading messages in text channels. | |||
/// </summary> | |||
ViewChannel = 0x00_00_04_00, | |||
/// <summary> | |||
/// Allows for sending messages in a channel. | |||
/// </summary> | |||
SendMessages = 0x00_00_08_00, | |||
/// <summary> | |||
/// Allows for sending of text-to-speech messages. | |||
/// </summary> | |||
SendTTSMessages = 0x00_00_10_00, | |||
/// <summary> | |||
/// Allows for deletion of other users messages. | |||
/// </summary> | |||
ManageMessages = 0x00_00_20_00, | |||
/// <summary> | |||
/// Allows links sent by users with this permission will be auto-embedded. | |||
/// </summary> | |||
EmbedLinks = 0x00_00_40_00, | |||
/// <summary> | |||
/// Allows for uploading images and files. | |||
/// </summary> | |||
AttachFiles = 0x00_00_80_00, | |||
/// <summary> | |||
/// Allows for reading of message history. | |||
/// </summary> | |||
ReadMessageHistory = 0x00_01_00_00, | |||
/// <summary> | |||
/// Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all | |||
/// online users in a channel. | |||
/// </summary> | |||
MentionEveryone = 0x00_02_00_00, | |||
/// <summary> | |||
/// Allows the usage of custom emojis from other servers. | |||
/// </summary> | |||
UseExternalEmojis = 0x00_04_00_00, | |||
// Voice | |||
/// <summary> Allows for joining of a voice channel. </summary> | |||
Connect = 0x00_10_00_00, | |||
/// <summary> Allows for speaking in a voice channel. </summary> | |||
Speak = 0x00_20_00_00, | |||
/// <summary> Allows for muting members in a voice channel. </summary> | |||
MuteMembers = 0x00_40_00_00, | |||
/// <summary> Allows for deafening of members in a voice channel. </summary> | |||
DeafenMembers = 0x00_80_00_00, | |||
/// <summary> Allows for moving of members between voice channels. </summary> | |||
MoveMembers = 0x01_00_00_00, | |||
/// <summary> Allows for using voice-activity-detection in a voice channel. </summary> | |||
UseVAD = 0x02_00_00_00, | |||
/// <summary> | |||
/// Allows for joining of a voice channel. | |||
/// </summary> | |||
Connect = 0x00_10_00_00, | |||
/// <summary> | |||
/// Allows for speaking in a voice channel. | |||
/// </summary> | |||
Speak = 0x00_20_00_00, | |||
/// <summary> | |||
/// Allows for muting members in a voice channel. | |||
/// </summary> | |||
MuteMembers = 0x00_40_00_00, | |||
/// <summary> | |||
/// Allows for deafening of members in a voice channel. | |||
/// </summary> | |||
DeafenMembers = 0x00_80_00_00, | |||
/// <summary> | |||
/// Allows for moving of members between voice channels. | |||
/// </summary> | |||
MoveMembers = 0x01_00_00_00, | |||
/// <summary> | |||
/// Allows for using voice-activity-detection in a voice channel. | |||
/// </summary> | |||
UseVAD = 0x02_00_00_00, | |||
// More General | |||
/// <summary> Allows management and editing of roles. </summary> | |||
ManageRoles = 0x10_00_00_00, | |||
/// <summary> Allows management and editing of webhooks. </summary> | |||
ManageWebhooks = 0x20_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of roles. | |||
/// </summary> | |||
ManageRoles = 0x10_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of webhooks. | |||
/// </summary> | |||
ManageWebhooks = 0x20_00_00_00, | |||
} | |||
} |
@@ -3,43 +3,129 @@ using System; | |||
namespace Discord | |||
{ | |||
/// <summary> Defines the available permissions for a channel. </summary> | |||
[FlagsAttribute] | |||
[Flags] | |||
public enum GuildPermission : ulong | |||
{ | |||
// General | |||
/// <summary> | |||
/// Allows creation of instant invites. | |||
/// </summary> | |||
CreateInstantInvite = 0x00_00_00_01, | |||
KickMembers = 0x00_00_00_02, | |||
BanMembers = 0x00_00_00_04, | |||
Administrator = 0x00_00_00_08, | |||
ManageChannels = 0x00_00_00_10, | |||
ManageGuild = 0x00_00_00_20, | |||
/// <summary> | |||
/// Allows kicking members. | |||
/// </summary> | |||
KickMembers = 0x00_00_00_02, | |||
/// <summary> | |||
/// Allows banning members. | |||
/// </summary> | |||
BanMembers = 0x00_00_00_04, | |||
/// <summary> | |||
/// Allows all permissions and bypasses channel permission overwrites. | |||
/// </summary> | |||
Administrator = 0x00_00_00_08, | |||
/// <summary> | |||
/// Allows management and editing of channels. | |||
/// </summary> | |||
ManageChannels = 0x00_00_00_10, | |||
/// <summary> | |||
/// Allows management and editing of the guild. | |||
/// </summary> | |||
ManageGuild = 0x00_00_00_20, | |||
// Text | |||
/// <summary> | |||
/// Allows for the addition of reactions to messages. | |||
/// </summary> | |||
AddReactions = 0x00_00_00_40, | |||
/// <summary> | |||
/// Allows for viewing of audit logs. | |||
/// </summary> | |||
ViewAuditLog = 0x00_00_00_80, | |||
ReadMessages = 0x00_00_04_00, | |||
/// <summary> | |||
/// Allows for reading of message. | |||
/// </summary> | |||
ReadMessages = 0x00_00_04_00, | |||
/// <summary> | |||
/// Allows for sending messages in a channel. | |||
/// </summary> | |||
SendMessages = 0x00_00_08_00, | |||
/// <summary> | |||
/// Allows for sending of text-to-speech messages. | |||
/// </summary> | |||
SendTTSMessages = 0x00_00_10_00, | |||
ManageMessages = 0x00_00_20_00, | |||
EmbedLinks = 0x00_00_40_00, | |||
AttachFiles = 0x00_00_80_00, | |||
ReadMessageHistory = 0x00_01_00_00, | |||
MentionEveryone = 0x00_02_00_00, | |||
UseExternalEmojis = 0x00_04_00_00, | |||
/// <summary> | |||
/// Allows for deletion of other users messages. | |||
/// </summary> | |||
ManageMessages = 0x00_00_20_00, | |||
/// <summary> | |||
/// Allows links sent by users with this permission will be auto-embedded. | |||
/// </summary> | |||
EmbedLinks = 0x00_00_40_00, | |||
/// <summary> | |||
/// Allows for uploading images and files. | |||
/// </summary> | |||
AttachFiles = 0x00_00_80_00, | |||
/// <summary> | |||
/// Allows for reading of message history. | |||
/// </summary> | |||
ReadMessageHistory = 0x00_01_00_00, | |||
/// <summary> | |||
/// Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all | |||
/// online users in a channel. | |||
/// </summary> | |||
MentionEveryone = 0x00_02_00_00, | |||
/// <summary> | |||
/// Allows the usage of custom emojis from other servers. | |||
/// </summary> | |||
UseExternalEmojis = 0x00_04_00_00, | |||
// Voice | |||
Connect = 0x00_10_00_00, | |||
Speak = 0x00_20_00_00, | |||
MuteMembers = 0x00_40_00_00, | |||
DeafenMembers = 0x00_80_00_00, | |||
MoveMembers = 0x01_00_00_00, | |||
UseVAD = 0x02_00_00_00, | |||
/// <summary> | |||
/// Allows for joining of a voice channel. | |||
/// </summary> | |||
Connect = 0x00_10_00_00, | |||
/// <summary> | |||
/// Allows for speaking in a voice channel. | |||
/// </summary> | |||
Speak = 0x00_20_00_00, | |||
/// <summary> | |||
/// Allows for muting members in a voice channel. | |||
/// </summary> | |||
MuteMembers = 0x00_40_00_00, | |||
/// <summary> | |||
/// Allows for deafening of members in a voice channel. | |||
/// </summary> | |||
DeafenMembers = 0x00_80_00_00, | |||
/// <summary> | |||
/// Allows for moving of members between voice channels. | |||
/// </summary> | |||
MoveMembers = 0x01_00_00_00, | |||
/// <summary> | |||
/// Allows for using voice-activity-detection in a voice channel. | |||
/// </summary> | |||
UseVAD = 0x02_00_00_00, | |||
// General 2 | |||
ChangeNickname = 0x04_00_00_00, | |||
/// <summary> | |||
/// Allows for modification of own nickname. | |||
/// </summary> | |||
ChangeNickname = 0x04_00_00_00, | |||
/// <summary> | |||
/// Allows for modification of other users nicknames. | |||
/// </summary> | |||
ManageNicknames = 0x08_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of roles. | |||
/// </summary> | |||
ManageRoles = 0x10_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of webhooks. | |||
/// </summary> | |||
ManageWebhooks = 0x20_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of emojis. | |||
/// </summary> | |||
ManageEmojis = 0x40_00_00_00 | |||
} | |||
} |
@@ -1,15 +1,23 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
public struct Overwrite | |||
{ | |||
/// <summary> Gets the unique identifier for the object this overwrite is targeting. </summary> | |||
/// <summary> | |||
/// Gets the unique identifier for the object this overwrite is targeting. | |||
/// </summary> | |||
public ulong TargetId { get; } | |||
/// <summary> Gets the type of object this overwrite is targeting. </summary> | |||
/// <summary> | |||
/// Gets the type of object this overwrite is targeting. | |||
/// </summary> | |||
public PermissionTarget TargetType { get; } | |||
/// <summary> Gets the permissions associated with this overwrite entry. </summary> | |||
/// <summary> | |||
/// Gets the permissions associated with this overwrite entry. | |||
/// </summary> | |||
public OverwritePermissions Permissions { get; } | |||
/// <summary> Creates a new Overwrite with provided target information and modified permissions. </summary> | |||
/// <summary> | |||
/// Creates a new <see cref="Overwrite"/> with provided target information and modified permissions. | |||
/// </summary> | |||
public Overwrite(ulong targetId, PermissionTarget targetType, OverwritePermissions permissions) | |||
{ | |||
TargetId = targetId; | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
@@ -7,18 +7,28 @@ namespace Discord | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public struct OverwritePermissions | |||
{ | |||
/// <summary> Gets a blank OverwritePermissions that inherits all permissions. </summary> | |||
/// <summary> | |||
/// Gets a blank <see cref="OverwritePermissions" /> that inherits all permissions. | |||
/// </summary> | |||
public static OverwritePermissions InheritAll { get; } = new OverwritePermissions(); | |||
/// <summary> Gets a OverwritePermissions that grants all permissions for a given channelType. </summary> | |||
/// <summary> | |||
/// Gets a <see cref="OverwritePermissions" /> that grants all permissions for the given channel. | |||
/// </summary> | |||
public static OverwritePermissions AllowAll(IChannel channel) | |||
=> new OverwritePermissions(ChannelPermissions.All(channel).RawValue, 0); | |||
/// <summary> Gets a OverwritePermissions that denies all permissions for a given channelType. </summary> | |||
/// <summary> | |||
/// Gets a <see cref="OverwritePermissions" /> that denies all permissions for the given channel. | |||
/// </summary> | |||
public static OverwritePermissions DenyAll(IChannel channel) | |||
=> new OverwritePermissions(0, ChannelPermissions.All(channel).RawValue); | |||
/// <summary> Gets a packed value representing all the allowed permissions in this OverwritePermissions. </summary> | |||
/// <summary> | |||
/// Gets a packed value representing all the allowed permissions in this <see cref="OverwritePermissions" />. | |||
/// </summary> | |||
public ulong AllowValue { get; } | |||
/// <summary> Gets a packed value representing all the denied permissions in this OverwritePermissions. </summary> | |||
/// <summary> | |||
/// Gets a packed value representing all the denied permissions in this <see cref="OverwritePermissions" />. | |||
/// </summary> | |||
public ulong DenyValue { get; } | |||
/// <summary> If Allowed, a user may create invites. </summary> | |||
@@ -62,7 +72,7 @@ namespace Discord | |||
/// <summary> If Allowed, a user may use voice-activity-detection rather than push-to-talk. </summary> | |||
public PermValue UseVAD => Permissions.GetValue(AllowValue, DenyValue, ChannelPermission.UseVAD); | |||
/// <summary> If Allowed, a user may adjust role permissions. This also implictly grants all other permissions. </summary> | |||
/// <summary> If Allowed, a user may adjust role permissions. This also implicitly grants all other permissions. </summary> | |||
public PermValue ManageRoles => Permissions.GetValue(AllowValue, DenyValue, ChannelPermission.ManageRoles); | |||
/// <summary> If True, a user may edit the webhooks for this channel. </summary> | |||
public PermValue ManageWebhooks => Permissions.GetValue(AllowValue, DenyValue, ChannelPermission.ManageWebhooks); | |||
@@ -107,7 +117,9 @@ namespace Discord | |||
DenyValue = denyValue; | |||
} | |||
/// <summary> Creates a new ChannelPermissions with the provided permissions. </summary> | |||
/// <summary> | |||
/// Creates a new <see cref="ChannelPermissions" /> with the provided permissions. | |||
/// </summary> | |||
public OverwritePermissions(PermValue createInstantInvite = PermValue.Inherit, PermValue manageChannel = PermValue.Inherit, | |||
PermValue addReactions = PermValue.Inherit, | |||
PermValue readMessages = PermValue.Inherit, PermValue sendMessages = PermValue.Inherit, PermValue sendTTSMessages = PermValue.Inherit, PermValue manageMessages = PermValue.Inherit, | |||
@@ -118,7 +130,10 @@ namespace Discord | |||
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, | |||
moveMembers, useVoiceActivation, manageRoles, manageWebhooks) { } | |||
/// <summary> Creates a new OverwritePermissions from this one, changing the provided non-null permissions. </summary> | |||
/// <summary> | |||
/// Creates a new <see cref="OverwritePermissions" /> from this one, changing the provided non-null | |||
/// permissions. | |||
/// </summary> | |||
public OverwritePermissions Modify(PermValue? createInstantInvite = null, PermValue? manageChannel = null, | |||
PermValue? addReactions = null, | |||
PermValue? readMessages = null, PermValue? sendMessages = null, PermValue? sendTTSMessages = null, PermValue? manageMessages = null, | |||
@@ -3,7 +3,9 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> A color object that Discord uses. </summary> | |||
/// <summary> | |||
/// A color object that Discord uses. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public struct Color | |||
{ | |||
@@ -1,29 +1,50 @@ | |||
using System; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a generic role object. | |||
/// </summary> | |||
public interface IRole : ISnowflakeEntity, IDeletable, IMentionable, IComparable<IRole> | |||
{ | |||
/// <summary> Gets the guild owning this role.</summary> | |||
/// <summary> | |||
/// Gets the guild owning this role. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the color given to users of this role. </summary> | |||
/// <summary> | |||
/// Gets the color given to users of this role. | |||
/// </summary> | |||
Color Color { get; } | |||
/// <summary> Returns true if users of this role are separated in the user list. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if users of this role are separated in the user list. | |||
/// </summary> | |||
bool IsHoisted { get; } | |||
/// <summary> Returns true if this role is automatically managed by Discord. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this role is automatically managed by Discord. | |||
/// </summary> | |||
bool IsManaged { get; } | |||
/// <summary> Returns true if this role may be mentioned in messages. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this role may be mentioned in messages. | |||
/// </summary> | |||
bool IsMentionable { get; } | |||
/// <summary> Gets the name of this role. </summary> | |||
/// <summary> | |||
/// Gets the name of this role. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Gets the permissions granted to members of this role. </summary> | |||
/// <summary> | |||
/// Gets the permissions granted to members of this role. | |||
/// </summary> | |||
GuildPermissions Permissions { get; } | |||
/// <summary> Gets this role's position relative to other roles in the same guild. </summary> | |||
/// <summary> | |||
/// Gets this role's position relative to other roles in the same guild. | |||
/// </summary> | |||
int Position { get; } | |||
///// <summary> Modifies this role. </summary> | |||
/// <summary> | |||
/// Modifies this role. | |||
/// </summary> | |||
Task ModifyAsync(Action<RoleProperties> func, RequestOptions options = null); | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Properties that are used to reorder an <see cref="IRole"/>. </summary> | |||
/// <summary> | |||
/// Properties that are used to reorder an <see cref="IRole" /> . | |||
/// </summary> | |||
public class ReorderRoleProperties | |||
{ | |||
/// <summary> Gets the ID of the role to be edited. </summary> | |||
/// <summary> | |||
/// Gets the ID of the role to be edited. | |||
/// </summary> | |||
public ulong Id { get; } | |||
/// <summary> Gets the new zero-based position of the role. </summary> | |||
/// <summary> | |||
/// Gets the new zero-based position of the role. | |||
/// </summary> | |||
public int Position { get; } | |||
public ReorderRoleProperties(ulong id, int pos) | |||
@@ -1,57 +1,57 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="IRole"/> with the specified changes. | |||
/// Properties that are used to modify an <see cref="IRole" /> with the specified changes. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await role.ModifyAsync(x => | |||
/// { | |||
/// x.Color = new Color(180, 15, 40); | |||
/// x.Hoist = true; | |||
/// }); | |||
/// <code lang="c#"> | |||
/// await role.ModifyAsync(x => | |||
/// { | |||
/// x.Color = new Color(180, 15, 40); | |||
/// x.Hoist = true; | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
/// <seealso cref="IRole"/> | |||
/// <seealso cref="T:Discord.IRole" /> | |||
public class RoleProperties | |||
{ | |||
/// <summary> | |||
/// Gets or sets the name of the role. | |||
/// Gets or sets the name of the role. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// </remarks> | |||
public Optional<string> Name { get; set; } | |||
/// <summary> | |||
/// Gets or sets the role's <see cref="GuildPermission"/>. | |||
/// Gets or sets the role's <see cref="GuildPermission" /> . | |||
/// </summary> | |||
public Optional<GuildPermissions> Permissions { get; set; } | |||
/// <summary> | |||
/// Gets or sets the position of the role. This is 0-based! | |||
/// Gets or sets the position of the role. This is 0-based! | |||
/// </summary> | |||
/// <remarks> | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// </remarks> | |||
public Optional<int> Position { get; set; } | |||
/// <summary> | |||
/// Gets or sets the color of the Role. | |||
/// Gets or sets the color of the role. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// </remarks> | |||
public Optional<Color> Color { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether or not this role should be displayed independently in the userlist. | |||
/// Gets or sets whether or not this role should be displayed independently in the user list. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// </remarks> | |||
public Optional<bool> Hoist { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether or not this role can be mentioned. | |||
/// Gets or sets whether or not this role can be mentioned. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// If this role is the EveryoneRole, this value may not be set. | |||
/// </remarks> | |||
public Optional<bool> Mentionable { get; set; } | |||
} | |||
@@ -3,68 +3,81 @@ using System.Collections.Generic; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify an <see cref="IGuildUser"/> with the following parameters. | |||
/// Properties that are used to modify an <see cref="IGuildUser" /> with the following parameters. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await (Context.User as IGuildUser)?.ModifyAsync(x => | |||
/// <code lang="c#"> | |||
/// await (Context.User as IGuildUser)?.ModifyAsync(x => | |||
/// { | |||
/// x.Nickname = $"festive {Context.User.Username}"; | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
/// <seealso cref="IGuildUser"/> | |||
/// <seealso cref="T:Discord.IGuildUser" /> | |||
public class GuildUserProperties | |||
{ | |||
/// <summary> | |||
/// Should the user be guild-muted in a voice channel? | |||
/// Sets whether the user should be muted in a voice channel. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this value is set to true, no user will be able to hear this user speak in the guild. | |||
/// If this value is set to <see langword="true"/>, no user will be able to hear this user speak in the guild. | |||
/// </remarks> | |||
public Optional<bool> Mute { get; set; } | |||
/// <summary> | |||
/// Should the user be guild-deafened in a voice channel? | |||
/// Sets whether the user should be deafened in a voice channel. | |||
/// </summary> | |||
/// <remarks> | |||
/// If this value is set to true, this user will not be able to hear anyone speak in the guild. | |||
/// If this value is set to <see langword="true"/>, this user will not be able to hear anyone speak in the guild. | |||
/// </remarks> | |||
public Optional<bool> Deaf { get; set; } | |||
/// <summary> | |||
/// Should the user have a nickname set? | |||
/// Sets the user's nickname. | |||
/// </summary> | |||
/// <remarks> | |||
/// To clear the user's nickname, this value can be set to <see langword="null" /> or <see cref="string.Empty" />. | |||
/// To clear the user's nickname, this value can be set to <see langword="null" /> or | |||
/// <see cref="string.Empty" /> . | |||
/// </remarks> | |||
public Optional<string> Nickname { get; set; } | |||
/// <summary> | |||
/// What roles should the user have? | |||
/// Sets the roles the user should have. | |||
/// </summary> | |||
/// <remarks> | |||
/// To add a role to a user: <see cref="IGuildUser.AddRolesAsync(IEnumerable<IRole>, RequestOptions)"/> | |||
/// To remove a role from a user: <see cref="IGuildUser.RemoveRolesAsync(IEnumerable<IRole>, RequestOptions)"/> | |||
/// <para> | |||
/// To add a role to a user: | |||
/// <see cref="IGuildUser.AddRolesAsync(IEnumerable{IRole},RequestOptions)" /> | |||
/// </para> | |||
/// <para> | |||
/// To remove a role from a user: | |||
/// <see cref="IGuildUser.RemoveRolesAsync(IEnumerable{IRole},RequestOptions)" /> | |||
/// </para> | |||
/// </remarks> | |||
public Optional<IEnumerable<IRole>> Roles { get; set; } | |||
/// <summary> | |||
/// What roles should the user have? | |||
/// Sets the roles the user should have. | |||
/// </summary> | |||
/// <remarks> | |||
/// To add a role to a user: <see cref="IGuildUser.AddRolesAsync(IEnumerable<IRole>, RequestOptions)"/> | |||
/// To remove a role from a user: <see cref="IGuildUser.RemoveRolesAsync(IEnumerable<IRole>, RequestOptions)"/> | |||
/// <para> | |||
/// To add a role to a user: | |||
/// <see cref="IGuildUser.AddRolesAsync(IEnumerable{IRole},RequestOptions)" /> | |||
/// </para> | |||
/// <para> | |||
/// To remove a role from a user: | |||
/// <see cref="IGuildUser.RemoveRolesAsync(IEnumerable{IRole},RequestOptions)" /> | |||
/// </para> | |||
/// </remarks> | |||
public Optional<IEnumerable<ulong>> RoleIds { get; set; } | |||
/// <summary> | |||
/// Moves a user to a voice channel. | |||
/// Moves a user to a voice channel. | |||
/// </summary> | |||
/// <remarks> | |||
/// This user MUST already be in a Voice Channel for this to work. | |||
/// This user MUST already be in a <see cref="IVoiceChannel"/> for this to work. | |||
/// </remarks> | |||
public Optional<IVoiceChannel> Channel { get; set; } | |||
/// <summary> | |||
/// Moves a user to a voice channel. | |||
/// Moves a user to a voice channel. | |||
/// </summary> | |||
/// <remarks> | |||
/// This user MUST already be in a Voice Channel for this to work. | |||
/// This user MUST already be in a <see cref="IVoiceChannel"/> for this to work. | |||
/// </remarks> | |||
public Optional<ulong> ChannelId { get; set; } | |||
} | |||
@@ -1,6 +1,8 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a Discord user that is in a group. </summary> | |||
/// <summary> | |||
/// Represents a Discord user that is in a group. | |||
/// </summary> | |||
public interface IGroupUser : IUser, IVoiceState | |||
{ | |||
///// <summary> Kicks this user from this group. </summary> | |||
@@ -4,44 +4,73 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a Discord user that is in a guild. </summary> | |||
/// <summary> | |||
/// Represents a Discord user that is in a guild. | |||
/// </summary> | |||
public interface IGuildUser : IUser, IVoiceState | |||
{ | |||
/// <summary> Gets when this user joined this guild. </summary> | |||
/// <summary> | |||
/// Gets when this user joined this guild. | |||
/// </summary> | |||
DateTimeOffset? JoinedAt { get; } | |||
/// <summary> Gets the nickname for this user. </summary> | |||
/// <summary> | |||
/// Gets the nickname for this user. | |||
/// </summary> | |||
string Nickname { get; } | |||
/// <summary> Gets the guild-level permissions for this user. </summary> | |||
/// <summary> | |||
/// Gets the guild-level permissions for this user. | |||
/// </summary> | |||
GuildPermissions GuildPermissions { get; } | |||
/// <summary> Gets the guild for this user. </summary> | |||
/// <summary> | |||
/// Gets the guild for this user. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the id of the guild for this user. </summary> | |||
/// <summary> | |||
/// Gets the ID of the guild for this user. | |||
/// </summary> | |||
ulong GuildId { get; } | |||
/// <summary> Returns a collection of the ids of the roles this user is a member of in this guild, including the guild's @everyone role. </summary> | |||
/// <summary> | |||
/// Returns a collection of the ids of the roles this user is a member of in this guild, including the | |||
/// guild's @everyone role. | |||
/// </summary> | |||
IReadOnlyCollection<ulong> RoleIds { get; } | |||
/// <summary> Gets the level permissions granted to this user to a given channel. </summary> | |||
/// <param name="channel"> The channel to get the permission from. </param> | |||
/// <summary> | |||
/// Gets the level permissions granted to this user to a given channel. | |||
/// </summary> | |||
/// <param name="channel">The channel to get the permission from.</param> | |||
ChannelPermissions GetPermissions(IGuildChannel channel); | |||
/// <summary> Kicks this user from this guild. </summary> | |||
/// <param name="reason"> The reason for the kick which will be recorded in the audit log. </param> | |||
/// <summary> | |||
/// Kicks this user from this guild. | |||
/// </summary> | |||
/// <param name="reason">The reason for the kick which will be recorded in the audit log.</param> | |||
Task KickAsync(string reason = null, RequestOptions options = null); | |||
/// <summary> Modifies this user's properties in this guild. </summary> | |||
/// <summary> | |||
/// Modifies this user's properties in this guild. | |||
/// </summary> | |||
Task ModifyAsync(Action<GuildUserProperties> func, RequestOptions options = null); | |||
/// <summary> Adds a role to this user in this guild. </summary> | |||
/// <param name="role"> The role to be added to the user. </param> | |||
/// <summary> | |||
/// Adds a <paramref name="role"/> to this user in this guild. | |||
/// </summary> | |||
/// <param name="role">The role to be added to the user.</param> | |||
Task AddRoleAsync(IRole role, RequestOptions options = null); | |||
/// <summary> Adds roles to this user in this guild. </summary> | |||
/// <param name="roles"> The roles to be added to the user. </param> | |||
/// <summary> | |||
/// Adds <paramref name="roles"/> to this user in this guild. | |||
/// </summary> | |||
/// <param name="roles">The roles to be added to the user.</param> | |||
Task AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options = null); | |||
/// <summary> Removes a role from this user in this guild. </summary> | |||
/// <param name="role"> The role to be removed from the user. </param> | |||
/// <summary> | |||
/// Removes a <paramref name="role"/> from this user in this guild. | |||
/// </summary> | |||
/// <param name="role">The role to be removed from the user.</param> | |||
Task RemoveRoleAsync(IRole role, RequestOptions options = null); | |||
/// <summary> Removes roles from this user in this guild. </summary> | |||
/// <param name="roles"> The roles to be removed from the user. </param> | |||
/// <summary> | |||
/// Removes <paramref name="roles"/> from this user in this guild. | |||
/// </summary> | |||
/// <param name="roles">The roles to be removed from the user.</param> | |||
Task RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options = null); | |||
} | |||
} |
@@ -1,11 +1,17 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a Discord user's presence status. </summary> | |||
/// <summary> | |||
/// Represents a Discord user's presence status. | |||
/// </summary> | |||
public interface IPresence | |||
{ | |||
/// <summary> Gets the activity this user is currently doing. </summary> | |||
/// <summary> | |||
/// Gets the activity this user is currently doing. | |||
/// </summary> | |||
IActivity Activity { get; } | |||
/// <summary> Gets the current status of this user. </summary> | |||
/// <summary> | |||
/// Gets the current status of this user. | |||
/// </summary> | |||
UserStatus Status { get; } | |||
} | |||
} |
@@ -3,16 +3,27 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a logged-in Discord user. </summary> | |||
/// <summary> | |||
/// Represents the logged-in Discord user. | |||
/// </summary> | |||
public interface ISelfUser : IUser | |||
{ | |||
/// <summary> Gets the email associated with this user. </summary> | |||
/// <summary> | |||
/// Gets the email associated with this user. | |||
/// </summary> | |||
string Email { get; } | |||
/// <summary> Returns true if this user's email has been verified. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this user's email has been verified. | |||
/// </summary> | |||
bool IsVerified { get; } | |||
/// <summary> Returns true if this user has enabled MFA on their account. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this user has enabled MFA on their account. | |||
/// </summary> | |||
bool IsMfaEnabled { get; } | |||
/// <summary> | |||
/// Modifies the user's properties. | |||
/// </summary> | |||
Task ModifyAsync(Action<SelfUserProperties> func, RequestOptions options = null); | |||
} | |||
} |
@@ -2,27 +2,48 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> Represents a Discord user. </summary> | |||
/// <summary> | |||
/// Represents a Discord user. | |||
/// </summary> | |||
public interface IUser : ISnowflakeEntity, IMentionable, IPresence | |||
{ | |||
/// <summary> Gets the id of this user's avatar. </summary> | |||
/// <summary> | |||
/// Gets the ID of this user's avatar. | |||
/// </summary> | |||
string AvatarId { get; } | |||
/// <summary> Gets the url to this user's avatar. </summary> | |||
/// <summary> | |||
/// Gets the URL to this user's avatar. | |||
/// </summary> | |||
string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); | |||
/// <summary> Gets the url to this user's default avatar. </summary> | |||
/// <summary> | |||
/// Gets the URL to this user's default avatar. | |||
/// </summary> | |||
string GetDefaultAvatarUrl(); | |||
/// <summary> Gets the per-username unique id for this user. </summary> | |||
/// <summary> | |||
/// Gets the per-username unique ID for this user. | |||
/// </summary> | |||
string Discriminator { get; } | |||
/// <summary> Gets the per-username unique id for this user. </summary> | |||
/// <summary> | |||
/// Gets the per-username unique ID for this user. | |||
/// </summary> | |||
ushort DiscriminatorValue { get; } | |||
/// <summary> Returns true if this user is a bot user. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this user is a bot user. | |||
/// </summary> | |||
bool IsBot { get; } | |||
/// <summary> Returns true if this user is a webhook user. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true"/> if this user is a webhook user. | |||
/// </summary> | |||
bool IsWebhook { get; } | |||
/// <summary> Gets the username for this user. </summary> | |||
/// <summary> | |||
/// Gets the username for this user. | |||
/// </summary> | |||
string Username { get; } | |||
/// <summary> Returns a private message channel to this user, creating one if it does not already exist. </summary> | |||
/// <summary> | |||
/// Returns a private message channel to this user, creating one if it does not already | |||
/// exist. | |||
/// </summary> | |||
Task<IDMChannel> GetOrCreateDMChannelAsync(RequestOptions options = null); | |||
} | |||
} |
@@ -1,20 +1,37 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a user's voice connection status. | |||
/// </summary> | |||
public interface IVoiceState | |||
{ | |||
/// <summary> Returns <see langword="true"/> if the guild has deafened this user. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true" /> if the guild has deafened this user. | |||
/// </summary> | |||
bool IsDeafened { get; } | |||
/// <summary> Returns <see langword="true"/> if the guild has muted this user. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true" /> if the guild has muted this user. | |||
/// </summary> | |||
bool IsMuted { get; } | |||
/// <summary> Returns <see langword="true"/> if this user has marked themselves as deafened. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true" /> if this user has marked themselves as deafened. | |||
/// </summary> | |||
bool IsSelfDeafened { get; } | |||
/// <summary> Returns <see langword="true"/> if this user has marked themselves as muted. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true" /> if this user has marked themselves as muted. | |||
/// </summary> | |||
bool IsSelfMuted { get; } | |||
/// <summary> Returns <see langword="true"/> if the guild is temporarily blocking audio to/from this user. </summary> | |||
/// <summary> | |||
/// Returns <see langword="true" /> if the guild is temporarily blocking audio to/from this user. | |||
/// </summary> | |||
bool IsSuppressed { get; } | |||
/// <summary> Gets the voice channel this user is currently in, if any. </summary> | |||
/// <summary> | |||
/// Gets the voice channel this user is currently in, if any. | |||
/// </summary> | |||
IVoiceChannel VoiceChannel { get; } | |||
/// <summary> Gets the unique identifier for this user's voice session. </summary> | |||
/// <summary> | |||
/// Gets the unique identifier for this user's voice session. | |||
/// </summary> | |||
string VoiceSessionId { get; } | |||
} | |||
} |
@@ -3,6 +3,7 @@ namespace Discord | |||
/// <summary> Represents a Webhook Discord user. </summary> | |||
public interface IWebhookUser : IGuildUser | |||
{ | |||
/// <summary> Gets the ID of a webhook. </summary> | |||
ulong WebhookId { get; } | |||
} | |||
} |
@@ -1,25 +1,25 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties that are used to modify the <see cref="ISelfUser"/> with the specified changes. | |||
/// Properties that are used to modify the <see cref="ISelfUser" /> with the specified changes. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await Context.Client.CurrentUser.ModifyAsync(x => | |||
/// { | |||
/// x.Avatar = new Image(File.OpenRead("avatar.jpg")); | |||
/// }); | |||
/// </code> | |||
/// <code lang="c#"> | |||
/// await Context.Client.CurrentUser.ModifyAsync(x => | |||
/// { | |||
/// x.Avatar = new Image(File.OpenRead("avatar.jpg")); | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
/// <seealso cref="ISelfUser"/> | |||
/// <seealso cref="T:Discord.ISelfUser" /> | |||
public class SelfUserProperties | |||
{ | |||
/// <summary> | |||
/// Your username | |||
/// Sets the username. | |||
/// </summary> | |||
public Optional<string> Username { get; set; } | |||
/// <summary> | |||
/// Your avatar | |||
/// Sets the avatar. | |||
/// </summary> | |||
public Optional<Image?> Avatar { get; set; } | |||
} | |||
@@ -1,19 +1,33 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> Defines the available Discord user status. </summary> | |||
/// <summary> | |||
/// Defines the available Discord user status. | |||
/// </summary> | |||
public enum UserStatus | |||
{ | |||
/// <summary> The user is offline. </summary> | |||
/// <summary> | |||
/// The user is offline. | |||
/// </summary> | |||
Offline, | |||
/// <summary> The user is online. </summary> | |||
/// <summary> | |||
/// The user is online. | |||
/// </summary> | |||
Online, | |||
/// <summary> The user is idle. </summary> | |||
/// <summary> | |||
/// The user is idle. | |||
/// </summary> | |||
Idle, | |||
/// <summary> The user is AFK. </summary> | |||
/// <summary> | |||
/// The user is AFK. | |||
/// </summary> | |||
AFK, | |||
/// <summary> The user is busy. </summary> | |||
/// <summary> | |||
/// The user is busy. | |||
/// </summary> | |||
DoNotDisturb, | |||
/// <summary> The user is invisible. </summary> | |||
/// <summary> | |||
/// The user is invisible. | |||
/// </summary> | |||
Invisible, | |||
} | |||
} |
@@ -3,32 +3,55 @@ using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a webhook object on Discord. | |||
/// </summary> | |||
public interface IWebhook : IDeletable, ISnowflakeEntity | |||
{ | |||
/// <summary> Gets the token of this webhook. </summary> | |||
/// <summary> | |||
/// Gets the token of this webhook. | |||
/// </summary> | |||
string Token { get; } | |||
/// <summary> Gets the default name of this webhook. </summary> | |||
/// <summary> | |||
/// Gets the default name of this webhook. | |||
/// </summary> | |||
string Name { get; } | |||
/// <summary> Gets the id of this webhook's default avatar. </summary> | |||
/// <summary> | |||
/// Gets the ID of this webhook's default avatar. | |||
/// </summary> | |||
string AvatarId { get; } | |||
/// <summary> Gets the url to this webhook's default avatar. </summary> | |||
/// <summary> | |||
/// Gets the URL to this webhook's default avatar. | |||
/// </summary> | |||
string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128); | |||
/// <summary> Gets the channel for this webhook. </summary> | |||
/// <summary> | |||
/// Gets the channel for this webhook. | |||
/// </summary> | |||
ITextChannel Channel { get; } | |||
/// <summary> Gets the id of the channel for this webhook. </summary> | |||
/// <summary> | |||
/// Gets the ID of the channel for this webhook. | |||
/// </summary> | |||
ulong ChannelId { get; } | |||
/// <summary> Gets the guild owning this webhook. </summary> | |||
/// <summary> | |||
/// Gets the guild owning this webhook. | |||
/// </summary> | |||
IGuild Guild { get; } | |||
/// <summary> Gets the id of the guild owning this webhook. </summary> | |||
/// <summary> | |||
/// Gets the ID of the guild owning this webhook. | |||
/// </summary> | |||
ulong? GuildId { get; } | |||
/// <summary> Gets the user that created this webhook. </summary> | |||
/// <summary> | |||
/// Gets the user that created this webhook. | |||
/// </summary> | |||
IUser Creator { get; } | |||
/// <summary> Modifies this webhook. </summary> | |||
/// <summary> | |||
/// Modifies this webhook. | |||
/// </summary> | |||
Task ModifyAsync(Action<WebhookProperties> func, RequestOptions options = null); | |||
} | |||
} |
@@ -1,40 +1,40 @@ | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Properties used to modify an <see cref="IWebhook"/> with the specified changes. | |||
/// Properties used to modify an <see cref="IWebhook" /> with the specified changes. | |||
/// </summary> | |||
/// <example> | |||
/// <code language="c#"> | |||
/// await webhook.ModifyAsync(x => | |||
/// <code lang="c#"> | |||
/// await webhook.ModifyAsync(x => | |||
/// { | |||
/// x.Name = "Bob"; | |||
/// x.Avatar = new Image("avatar.jpg"); | |||
/// }); | |||
/// </code> | |||
/// </example> | |||
/// <seealso cref="IWebhook"/> | |||
/// <seealso cref="T:Discord.IWebhook" /> | |||
public class WebhookProperties | |||
{ | |||
/// <summary> | |||
/// Gets or sets the default name of the webhook. | |||
/// Gets or sets the default name of the webhook. | |||
/// </summary> | |||
public Optional<string> Name { get; set; } | |||
/// <summary> | |||
/// Gets or sets the default avatar of the webhook. | |||
/// Gets or sets the default avatar of the webhook. | |||
/// </summary> | |||
public Optional<Image?> Image { get; set; } | |||
/// <summary> | |||
/// Gets or sets the channel for this webhook. | |||
/// Gets or sets the channel for this webhook. | |||
/// </summary> | |||
/// <remarks> | |||
/// This field is not used when authenticated with <see cref="TokenType.Webhook"/>. | |||
/// This field is not used when authenticated with <see cref="Discord.TokenType.Webhook" /> . | |||
/// </remarks> | |||
public Optional<ITextChannel> Channel { get; set; } | |||
/// <summary> | |||
/// Gets or sets the channel ID for this webhook. | |||
/// Gets or sets the channel ID for this webhook. | |||
/// </summary> | |||
/// <remarks> | |||
/// This field is not used when authenticated with <see cref="TokenType.Webhook"/>. | |||
/// This field is not used when authenticated with <see cref="Discord.TokenType.Webhook" /> . | |||
/// </remarks> | |||
public Optional<ulong> ChannelId { get; set; } | |||
} | |||
@@ -3,13 +3,31 @@ using System.Net; | |||
namespace Discord.Net | |||
{ | |||
/// <summary> | |||
/// Describes an exception that occurred during the processing of Discord HTTP requests. | |||
/// </summary> | |||
public class HttpException : Exception | |||
{ | |||
/// <summary> | |||
/// Gets the HTTP status code returned by Discord. | |||
/// </summary> | |||
public HttpStatusCode HttpCode { get; } | |||
/// <summary> | |||
/// Gets the JSON error code returned by Discord, or <see langword="null"/> if none. | |||
/// </summary> | |||
public int? DiscordCode { get; } | |||
/// <summary> | |||
/// Gets the reason of the exception. | |||
/// </summary> | |||
public string Reason { get; } | |||
/// <summary> | |||
/// Gets the request object used to send the request. | |||
/// </summary> | |||
public IRequest Request { get; } | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="HttpException" /> class. | |||
/// </summary> | |||
public HttpException(HttpStatusCode httpCode, IRequest request, int? discordCode = null, string reason = null) | |||
: base(CreateMessage(httpCode, discordCode, reason)) | |||
{ | |||
@@ -2,10 +2,20 @@ using System; | |||
namespace Discord.Net | |||
{ | |||
/// <summary> | |||
/// An exception that indicates the user is being rate limited by Discord. | |||
/// </summary> | |||
public class RateLimitedException : TimeoutException | |||
{ | |||
/// <summary> | |||
/// Gets the request object used to send the request. | |||
/// </summary> | |||
public IRequest Request { get; } | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="RateLimitedException" /> class using the | |||
/// <paramref name="request"/> sent. | |||
/// </summary> | |||
public RateLimitedException(IRequest request) | |||
: base("You are being rate limited.") | |||
{ | |||
@@ -1,11 +1,24 @@ | |||
using System; | |||
using System; | |||
namespace Discord.Net | |||
{ | |||
/// <summary> | |||
/// Describes an exception that causes the WebSocket to close during a session. | |||
/// </summary> | |||
public class WebSocketClosedException : Exception | |||
{ | |||
/// <summary> | |||
/// Gets the close code sent by Discord. | |||
/// </summary> | |||
public int CloseCode { get; } | |||
/// <summary> | |||
/// Gets the reason of the interruption. | |||
/// </summary> | |||
public string Reason { get; } | |||
/// <summary> | |||
/// Initializes a new instance of the <see cref="WebSocketClosedException" /> using the Discord close code | |||
/// and the optional reason. | |||
/// </summary> | |||
public WebSocketClosedException(int closeCode, string reason = null) | |||
: base($"The server sent close {closeCode}{(reason != null ? $": \"{reason}\"" : "")}") | |||
{ | |||
@@ -55,36 +55,28 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) => Permissions.ToChannelPerms(channel, GuildPermissions.Webhook.RawValue); | |||
/// <inheritdoc /> | |||
Task IGuildUser.KickAsync(string reason, RequestOptions options) | |||
{ | |||
Task IGuildUser.KickAsync(string reason, RequestOptions options) => | |||
throw new NotSupportedException("Webhook users cannot be kicked."); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuildUser.ModifyAsync(Action<GuildUserProperties> func, RequestOptions options) | |||
{ | |||
Task IGuildUser.ModifyAsync(Action<GuildUserProperties> func, RequestOptions options) => | |||
throw new NotSupportedException("Webhook users cannot be modified."); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) | |||
{ | |||
Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuildUser.AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options) | |||
{ | |||
Task IGuildUser.AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) | |||
{ | |||
Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
/// <inheritdoc /> | |||
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) | |||
{ | |||
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
//IVoiceState | |||
/// <inheritdoc /> | |||
@@ -10,18 +10,26 @@ namespace Discord.WebSocket | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class SocketWebhookUser : SocketUser, IWebhookUser | |||
{ | |||
/// <summary> Gets the guild of this webhook. </summary> | |||
public SocketGuild Guild { get; } | |||
/// <inheritdoc /> | |||
public ulong WebhookId { get; } | |||
/// <inheritdoc /> | |||
public override string Username { get; internal set; } | |||
/// <inheritdoc /> | |||
public override ushort DiscriminatorValue { get; internal set; } | |||
/// <inheritdoc /> | |||
public override string AvatarId { get; internal set; } | |||
/// <inheritdoc /> | |||
public override bool IsBot { get; internal set; } | |||
/// <inheritdoc /> | |||
public override bool IsWebhook => true; | |||
internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null); } set { } } | |||
internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } } | |||
internal override SocketGlobalUser GlobalUser => | |||
throw new NotSupportedException(); | |||
internal SocketWebhookUser(SocketGuild guild, ulong id, ulong webhookId) | |||
: base(guild.Discord, id) | |||
@@ -39,47 +47,59 @@ namespace Discord.WebSocket | |||
//IGuildUser | |||
/// <inheritdoc /> | |||
IGuild IGuildUser.Guild => Guild; | |||
/// <inheritdoc /> | |||
ulong IGuildUser.GuildId => Guild.Id; | |||
/// <inheritdoc /> | |||
IReadOnlyCollection<ulong> IGuildUser.RoleIds => ImmutableArray.Create<ulong>(); | |||
/// <inheritdoc /> | |||
DateTimeOffset? IGuildUser.JoinedAt => null; | |||
/// <inheritdoc /> | |||
string IGuildUser.Nickname => null; | |||
/// <inheritdoc /> | |||
GuildPermissions IGuildUser.GuildPermissions => GuildPermissions.Webhook; | |||
/// <inheritdoc /> | |||
ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) => Permissions.ToChannelPerms(channel, GuildPermissions.Webhook.RawValue); | |||
Task IGuildUser.KickAsync(string reason, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.KickAsync(string reason, RequestOptions options) => | |||
throw new NotSupportedException("Webhook users cannot be kicked."); | |||
} | |||
Task IGuildUser.ModifyAsync(Action<GuildUserProperties> func, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.ModifyAsync(Action<GuildUserProperties> func, RequestOptions options) => | |||
throw new NotSupportedException("Webhook users cannot be modified."); | |||
} | |||
Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
Task IGuildUser.AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) | |||
{ | |||
/// <inheritdoc /> | |||
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => | |||
throw new NotSupportedException("Roles are not supported on webhook users."); | |||
} | |||
//IVoiceState | |||
/// <inheritdoc /> | |||
bool IVoiceState.IsDeafened => false; | |||
/// <inheritdoc /> | |||
bool IVoiceState.IsMuted => false; | |||
/// <inheritdoc /> | |||
bool IVoiceState.IsSelfDeafened => false; | |||
/// <inheritdoc /> | |||
bool IVoiceState.IsSelfMuted => false; | |||
/// <inheritdoc /> | |||
bool IVoiceState.IsSuppressed => false; | |||
/// <inheritdoc /> | |||
IVoiceChannel IVoiceState.VoiceChannel => null; | |||
/// <inheritdoc /> | |||
string IVoiceState.VoiceSessionId => null; | |||
} | |||
} |