| @@ -7,6 +7,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| public class CommandBuilder | public class CommandBuilder | ||||
| { | { | ||||
| #region CommandBuilder | |||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| private readonly List<ParameterBuilder> _parameters; | private readonly List<ParameterBuilder> _parameters; | ||||
| private readonly List<Attribute> _attributes; | private readonly List<Attribute> _attributes; | ||||
| @@ -27,8 +28,9 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | ||||
| public IReadOnlyList<Attribute> Attributes => _attributes; | public IReadOnlyList<Attribute> Attributes => _attributes; | ||||
| public IReadOnlyList<string> Aliases => _aliases; | public IReadOnlyList<string> Aliases => _aliases; | ||||
| #endregion | |||||
| //Automatic | |||||
| #region Automatic | |||||
| internal CommandBuilder(ModuleBuilder module) | internal CommandBuilder(ModuleBuilder module) | ||||
| { | { | ||||
| Module = module; | Module = module; | ||||
| @@ -38,7 +40,9 @@ namespace Discord.Commands.Builders | |||||
| _attributes = new List<Attribute>(); | _attributes = new List<Attribute>(); | ||||
| _aliases = new List<string>(); | _aliases = new List<string>(); | ||||
| } | } | ||||
| //User-defined | |||||
| #endregion | |||||
| #region User-defined | |||||
| internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback) | internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback) | ||||
| : this(module) | : this(module) | ||||
| { | { | ||||
| @@ -132,7 +136,7 @@ namespace Discord.Commands.Builders | |||||
| var firstMultipleParam = _parameters.FirstOrDefault(x => x.IsMultiple); | var firstMultipleParam = _parameters.FirstOrDefault(x => x.IsMultiple); | ||||
| if ((firstMultipleParam != null) && (firstMultipleParam != lastParam)) | if ((firstMultipleParam != null) && (firstMultipleParam != lastParam)) | ||||
| throw new InvalidOperationException($"Only the last parameter in a command may have the Multiple flag. Parameter: {firstMultipleParam.Name} in {PrimaryAlias}"); | throw new InvalidOperationException($"Only the last parameter in a command may have the Multiple flag. Parameter: {firstMultipleParam.Name} in {PrimaryAlias}"); | ||||
| var firstRemainderParam = _parameters.FirstOrDefault(x => x.IsRemainder); | var firstRemainderParam = _parameters.FirstOrDefault(x => x.IsRemainder); | ||||
| if ((firstRemainderParam != null) && (firstRemainderParam != lastParam)) | if ((firstRemainderParam != null) && (firstRemainderParam != lastParam)) | ||||
| throw new InvalidOperationException($"Only the last parameter in a command may have the Remainder flag. Parameter: {firstRemainderParam.Name} in {PrimaryAlias}"); | throw new InvalidOperationException($"Only the last parameter in a command may have the Remainder flag. Parameter: {firstRemainderParam.Name} in {PrimaryAlias}"); | ||||
| @@ -140,5 +144,6 @@ namespace Discord.Commands.Builders | |||||
| return new CommandInfo(this, info, service); | return new CommandInfo(this, info, service); | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -7,6 +7,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| public class ModuleBuilder | public class ModuleBuilder | ||||
| { | { | ||||
| #region ModuleBuilder | |||||
| private readonly List<CommandBuilder> _commands; | private readonly List<CommandBuilder> _commands; | ||||
| private readonly List<ModuleBuilder> _submodules; | private readonly List<ModuleBuilder> _submodules; | ||||
| private readonly List<PreconditionAttribute> _preconditions; | private readonly List<PreconditionAttribute> _preconditions; | ||||
| @@ -27,8 +28,9 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<string> Aliases => _aliases; | public IReadOnlyList<string> Aliases => _aliases; | ||||
| internal TypeInfo TypeInfo { get; set; } | internal TypeInfo TypeInfo { get; set; } | ||||
| #endregion | |||||
| //Automatic | |||||
| #region Automatic | |||||
| internal ModuleBuilder(CommandService service, ModuleBuilder parent) | internal ModuleBuilder(CommandService service, ModuleBuilder parent) | ||||
| { | { | ||||
| Service = service; | Service = service; | ||||
| @@ -40,7 +42,9 @@ namespace Discord.Commands.Builders | |||||
| _attributes = new List<Attribute>(); | _attributes = new List<Attribute>(); | ||||
| _aliases = new List<string>(); | _aliases = new List<string>(); | ||||
| } | } | ||||
| //User-defined | |||||
| #endregion | |||||
| #region User-defined | |||||
| internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) | internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) | ||||
| : this(service, parent) | : this(service, parent) | ||||
| { | { | ||||
| @@ -132,5 +136,6 @@ namespace Discord.Commands.Builders | |||||
| public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | ||||
| internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent); | internal ModuleInfo Build(CommandService service, IServiceProvider services, ModuleInfo parent) => BuildImpl(service, services, parent); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -8,6 +8,7 @@ namespace Discord.Commands.Builders | |||||
| { | { | ||||
| public class ParameterBuilder | public class ParameterBuilder | ||||
| { | { | ||||
| #region ParameterBuilder | |||||
| private readonly List<ParameterPreconditionAttribute> _preconditions; | private readonly List<ParameterPreconditionAttribute> _preconditions; | ||||
| private readonly List<Attribute> _attributes; | private readonly List<Attribute> _attributes; | ||||
| @@ -24,8 +25,9 @@ namespace Discord.Commands.Builders | |||||
| public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions; | public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions; | ||||
| public IReadOnlyList<Attribute> Attributes => _attributes; | public IReadOnlyList<Attribute> Attributes => _attributes; | ||||
| #endregion | |||||
| //Automatic | |||||
| #region Automatic | |||||
| internal ParameterBuilder(CommandBuilder command) | internal ParameterBuilder(CommandBuilder command) | ||||
| { | { | ||||
| _preconditions = new List<ParameterPreconditionAttribute>(); | _preconditions = new List<ParameterPreconditionAttribute>(); | ||||
| @@ -33,7 +35,9 @@ namespace Discord.Commands.Builders | |||||
| Command = command; | Command = command; | ||||
| } | } | ||||
| //User-defined | |||||
| #endregion | |||||
| #region User-defined | |||||
| internal ParameterBuilder(CommandBuilder command, string name, Type type) | internal ParameterBuilder(CommandBuilder command, string name, Type type) | ||||
| : this(command) | : this(command) | ||||
| { | { | ||||
| @@ -132,5 +136,6 @@ namespace Discord.Commands.Builders | |||||
| return new ParameterInfo(this, info, Command.Module.Service); | return new ParameterInfo(this, info, Command.Module.Service); | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -29,6 +29,7 @@ namespace Discord.Commands | |||||
| /// </remarks> | /// </remarks> | ||||
| public class CommandService : IDisposable | public class CommandService : IDisposable | ||||
| { | { | ||||
| #region CommandService | |||||
| /// <summary> | /// <summary> | ||||
| /// Occurs when a command-related information is received. | /// Occurs when a command-related information is received. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -131,8 +132,9 @@ namespace Discord.Commands | |||||
| entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>))); | entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>))); | ||||
| _entityTypeReaders = entityTypeReaders.ToImmutable(); | _entityTypeReaders = entityTypeReaders.ToImmutable(); | ||||
| } | } | ||||
| #endregion | |||||
| //Modules | |||||
| #region Modules | |||||
| public async Task<ModuleInfo> CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc) | public async Task<ModuleInfo> CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc) | ||||
| { | { | ||||
| await _moduleLock.WaitAsync().ConfigureAwait(false); | await _moduleLock.WaitAsync().ConfigureAwait(false); | ||||
| @@ -322,8 +324,9 @@ namespace Discord.Commands | |||||
| return true; | return true; | ||||
| } | } | ||||
| #endregion | |||||
| //Type Readers | |||||
| #region Type Readers | |||||
| /// <summary> | /// <summary> | ||||
| /// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object | /// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object | ||||
| /// type. | /// type. | ||||
| @@ -448,8 +451,9 @@ namespace Discord.Commands | |||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| //Execution | |||||
| #region Execution | |||||
| /// <summary> | /// <summary> | ||||
| /// Searches for the command. | /// Searches for the command. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -602,7 +606,9 @@ namespace Discord.Commands | |||||
| await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result); | await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result); | ||||
| return result; | return result; | ||||
| } | } | ||||
| #endregion | |||||
| #region Dispose | |||||
| protected virtual void Dispose(bool disposing) | protected virtual void Dispose(bool disposing) | ||||
| { | { | ||||
| if (!_isDisposed) | if (!_isDisposed) | ||||
| @@ -620,5 +626,6 @@ namespace Discord.Commands | |||||
| { | { | ||||
| Dispose(true); | Dispose(true); | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -16,6 +16,7 @@ namespace Discord.Commands | |||||
| public abstract class ModuleBase<T> : IModuleBase | public abstract class ModuleBase<T> : IModuleBase | ||||
| where T : class, ICommandContext | where T : class, ICommandContext | ||||
| { | { | ||||
| #region ModuleBase | |||||
| /// <summary> | /// <summary> | ||||
| /// The underlying context of the command. | /// The underlying context of the command. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -65,8 +66,9 @@ namespace Discord.Commands | |||||
| protected virtual void OnModuleBuilding(CommandService commandService, ModuleBuilder builder) | protected virtual void OnModuleBuilding(CommandService commandService, ModuleBuilder builder) | ||||
| { | { | ||||
| } | } | ||||
| #endregion | |||||
| //IModuleBase | |||||
| #region IModuleBase | |||||
| void IModuleBase.SetContext(ICommandContext context) | void IModuleBase.SetContext(ICommandContext context) | ||||
| { | { | ||||
| var newValue = context as T; | var newValue = context as T; | ||||
| @@ -75,5 +77,6 @@ namespace Discord.Commands | |||||
| void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command); | void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command); | ||||
| void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command); | void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command); | ||||
| void IModuleBase.OnModuleBuilding(CommandService commandService, ModuleBuilder builder) => OnModuleBuilding(commandService, builder); | void IModuleBase.OnModuleBuilding(CommandService commandService, ModuleBuilder builder) => OnModuleBuilding(commandService, builder); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -771,6 +771,12 @@ namespace Discord | |||||
| /// <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns> | /// <returns>A guild user associated with the specified <paramref name="userId" />; <see langword="null" /> if the user is already in the guild.</returns> | ||||
| Task<IGuildUser> AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null); | Task<IGuildUser> AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null); | ||||
| /// <summary> | /// <summary> | ||||
| /// Disconnects the user from its current voice channel | |||||
| /// </summary> | |||||
| /// <param name="user">The user to disconnect.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns> | |||||
| Task DisconnectAsync(IGuildUser user); | |||||
| /// <summary> | |||||
| /// Gets a collection of all users in this guild. | /// Gets a collection of all users in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| /// <remarks> | /// <remarks> | ||||
| @@ -951,6 +957,15 @@ namespace Discord | |||||
| /// emote. | /// emote. | ||||
| /// </returns> | /// </returns> | ||||
| Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null); | Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null); | ||||
| /// <summary> | |||||
| /// Moves the user to the voice channel. | |||||
| /// </summary> | |||||
| /// <param name="user">The user to move.</param> | |||||
| /// <param name="targetChannel">the channel where the user gets moved to.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for moving a user.</returns> | |||||
| Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel); | |||||
| /// <summary> | /// <summary> | ||||
| /// Deletes an existing <see cref="GuildEmote"/> from this guild. | /// Deletes an existing <see cref="GuildEmote"/> from this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -22,16 +22,16 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| Pong = 1, | Pong = 1, | ||||
| [Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)] | |||||
| /// <summary> | /// <summary> | ||||
| /// ACK a command without sending a message, eating the user's input. | /// ACK a command without sending a message, eating the user's input. | ||||
| /// </summary> | /// </summary> | ||||
| [Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)] | |||||
| Acknowledge = 2, | Acknowledge = 2, | ||||
| [Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)] | |||||
| /// <summary> | /// <summary> | ||||
| /// Respond with a message, showing the user's input. | /// Respond with a message, showing the user's input. | ||||
| /// </summary> | /// </summary> | ||||
| [Obsolete("This response type has been depricated by discord. Either use ChannelMessageWithSource or DeferredChannelMessageWithSource", true)] | |||||
| ChannelMessage = 3, | ChannelMessage = 3, | ||||
| /// <summary> | /// <summary> | ||||
| @@ -10,11 +10,6 @@ namespace Discord | |||||
| /// </summary> | /// </summary> | ||||
| public class ComponentBuilder | public class ComponentBuilder | ||||
| { | { | ||||
| /// <summary> | |||||
| /// The max length of a <see cref="ButtonComponent.Label"/>. | |||||
| /// </summary> | |||||
| public const int MaxButtonLabelLength = 80; | |||||
| /// <summary> | /// <summary> | ||||
| /// The max length of a <see cref="ButtonComponent.CustomId"/>. | /// The max length of a <see cref="ButtonComponent.CustomId"/>. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -124,6 +119,8 @@ namespace Discord | |||||
| public ComponentBuilder WithSelectMenu(SelectMenuBuilder menu, int row = 0) | public ComponentBuilder WithSelectMenu(SelectMenuBuilder menu, int row = 0) | ||||
| { | { | ||||
| Preconditions.LessThan(row, MaxActionRowCount, nameof(row)); | Preconditions.LessThan(row, MaxActionRowCount, nameof(row)); | ||||
| if (menu.Options.Distinct().Count() != menu.Options.Count()) | |||||
| throw new InvalidOperationException("Please make sure that there is no duplicates values."); | |||||
| var builtMenu = menu.Build(); | var builtMenu = menu.Build(); | ||||
| @@ -351,19 +348,27 @@ namespace Discord | |||||
| /// <summary> | /// <summary> | ||||
| /// The max length of a <see cref="ButtonComponent.Label"/>. | /// The max length of a <see cref="ButtonComponent.Label"/>. | ||||
| /// </summary> | /// </summary> | ||||
| public const int MaxLabelLength = 80; | |||||
| public const int MaxButtonLabelLength = 80; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the label of the current button. | /// Gets or sets the label of the current button. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="ComponentBuilder.MaxButtonLabelLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxButtonLabelLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxButtonLabelLength"/>.</exception> | |||||
| public string Label | public string Label | ||||
| { | { | ||||
| get => _label; | get => _label; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > ComponentBuilder.MaxButtonLabelLength) | |||||
| throw new ArgumentException(message: $"Button label must be {ComponentBuilder.MaxButtonLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > MaxButtonLabelLength) | |||||
| throw new ArgumentException($"Button label must be {MaxButtonLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("Button label must be 1 character or more!", paramName: nameof(Label)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("Button label must not be null or empty!", paramName: nameof(Label)); | |||||
| _label = value; | _label = value; | ||||
| } | } | ||||
| @@ -373,13 +378,21 @@ namespace Discord | |||||
| /// Gets or sets the custom id of the current button. | /// Gets or sets the custom id of the current button. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception> | /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length subceeds 1.</exception> | |||||
| public string CustomId | public string CustomId | ||||
| { | { | ||||
| get => _customId; | get => _customId; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength) | |||||
| throw new ArgumentException(message: $"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > ComponentBuilder.MaxCustomIdLength) | |||||
| throw new ArgumentException($"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("Custom Id must be 1 character or more!", paramName: nameof(CustomId)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("Custom Id must not be null or empty!", paramName: nameof(CustomId)); | |||||
| _customId = value; | _customId = value; | ||||
| } | } | ||||
| } | } | ||||
| @@ -617,14 +630,22 @@ namespace Discord | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the custom id of the current select menu. | /// Gets or sets the custom id of the current select menu. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/></exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="CustomId"/> length subceeds 1.</exception> | |||||
| public string CustomId | public string CustomId | ||||
| { | { | ||||
| get => _customId; | get => _customId; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength) | |||||
| throw new ArgumentException(message: $"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > ComponentBuilder.MaxCustomIdLength) | |||||
| throw new ArgumentException($"Custom Id must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(CustomId)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("Custom Id must be 1 character or more!", paramName: nameof(CustomId)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("Custom Id must not be null or empty!", paramName: nameof(CustomId)); | |||||
| _customId = value; | _customId = value; | ||||
| } | } | ||||
| } | } | ||||
| @@ -633,13 +654,21 @@ namespace Discord | |||||
| /// Gets or sets the placeholder text of the current select menu. | /// Gets or sets the placeholder text of the current select menu. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length exceeds <see cref="MaxPlaceholderLength"/>.</exception> | /// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length exceeds <see cref="MaxPlaceholderLength"/>.</exception> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Placeholder"/> length subceeds 1.</exception> | |||||
| public string Placeholder | public string Placeholder | ||||
| { | { | ||||
| get => _placeholder; | get => _placeholder; | ||||
| set | set | ||||
| { | { | ||||
| if (value?.Length > MaxPlaceholderLength) | |||||
| throw new ArgumentException(message: $"Placeholder must be {MaxPlaceholderLength} characters or less!", paramName: nameof(Placeholder)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > MaxPlaceholderLength) | |||||
| throw new ArgumentException($"The placeholder must be {MaxPlaceholderLength} characters or less!", paramName: nameof(Placeholder)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("The placeholder must be 1 character or more!", paramName: nameof(Placeholder)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("The placeholder must not be null or empty!", paramName: nameof(Placeholder)); | |||||
| _placeholder = value; | _placeholder = value; | ||||
| } | } | ||||
| @@ -880,7 +909,7 @@ namespace Discord | |||||
| /// <summary> | /// <summary> | ||||
| /// The maximum length of a <see cref="SelectMenuOption.Label"/>. | /// The maximum length of a <see cref="SelectMenuOption.Label"/>. | ||||
| /// </summary> | /// </summary> | ||||
| public const int MaxLabelLength = 100; | |||||
| public const int MaxSelectLabelLength = 100; | |||||
| /// <summary> | /// <summary> | ||||
| /// The maximum length of a <see cref="SelectMenuOption.Description"/>. | /// The maximum length of a <see cref="SelectMenuOption.Description"/>. | ||||
| @@ -888,22 +917,29 @@ namespace Discord | |||||
| public const int MaxDescriptionLength = 100; | public const int MaxDescriptionLength = 100; | ||||
| /// <summary> | /// <summary> | ||||
| /// The maximum length of a <see cref="SelectMenuOption.Label"/>. | |||||
| /// The maximum length of a <see cref="SelectMenuOption.Value"/>. | |||||
| /// </summary> | /// </summary> | ||||
| public const int MaxSelectLabelLength = 100; | |||||
| public const int MaxSelectValueLength = 100; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the label of the current select menu. | /// Gets or sets the label of the current select menu. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxSelectLabelLength"/></exception> | /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length exceeds <see cref="MaxSelectLabelLength"/></exception> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length subceeds 1.</exception> | |||||
| public string Label | public string Label | ||||
| { | { | ||||
| get => _label; | get => _label; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null) | if (value != null) | ||||
| { | |||||
| if (value.Length > MaxSelectLabelLength) | if (value.Length > MaxSelectLabelLength) | ||||
| throw new ArgumentException(message: $"Button label must be {MaxSelectLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| throw new ArgumentException($"Select option label must be {MaxSelectLabelLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("Select option label must be 1 character or more!", paramName: nameof(Label)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("Select option label must not be null or empty!", paramName: nameof(Label)); | |||||
| _label = value; | _label = value; | ||||
| } | } | ||||
| @@ -912,14 +948,23 @@ namespace Discord | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets or sets the custom id of the current select menu. | /// Gets or sets the custom id of the current select menu. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length exceeds <see cref="ComponentBuilder.MaxCustomIdLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length exceeds <see cref="MaxSelectValueLength"/>.</exception> | |||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Value"/> length subceeds 1.</exception> | |||||
| public string Value | public string Value | ||||
| { | { | ||||
| get => _value; | get => _value; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > ComponentBuilder.MaxCustomIdLength) | |||||
| throw new ArgumentException(message: $"Value must be {ComponentBuilder.MaxCustomIdLength} characters or less!", paramName: nameof(Value)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > MaxSelectValueLength) | |||||
| throw new ArgumentException($"Select option value must be {MaxSelectValueLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("Select option value must be 1 character or more!", paramName: nameof(Label)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("Select option value must not be null or empty!", paramName: nameof(Label)); | |||||
| _value = value; | _value = value; | ||||
| } | } | ||||
| } | } | ||||
| @@ -928,13 +973,21 @@ namespace Discord | |||||
| /// Gets or sets this menu options description. | /// Gets or sets this menu options description. | ||||
| /// </summary> | /// </summary> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Description"/> length exceeds <see cref="MaxDescriptionLength"/>.</exception> | /// <exception cref="ArgumentException" accessor="set"><see cref="Description"/> length exceeds <see cref="MaxDescriptionLength"/>.</exception> | ||||
| /// <exception cref="ArgumentException" accessor="set"><see cref="Label"/> length subceeds 1.</exception> | |||||
| public string Description | public string Description | ||||
| { | { | ||||
| get => _description; | get => _description; | ||||
| set | set | ||||
| { | { | ||||
| if (value != null && value.Length > MaxDescriptionLength) | |||||
| throw new ArgumentException($"Description must be {MaxDescriptionLength} characters or less!", nameof(Description)); | |||||
| if (value != null) | |||||
| { | |||||
| if (value.Length > MaxDescriptionLength) | |||||
| throw new ArgumentException($"The description must be {MaxDescriptionLength} characters or less!", paramName: nameof(Label)); | |||||
| if (value.Length < 1) | |||||
| throw new ArgumentException("The description must be 1 character or more!", paramName: nameof(Label)); | |||||
| } | |||||
| else | |||||
| throw new ArgumentException("The description must not be null or empty!", paramName: nameof(Label)); | |||||
| _description = value; | _description = value; | ||||
| } | } | ||||
| @@ -10,6 +10,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| public abstract class BaseDiscordClient : IDiscordClient | public abstract class BaseDiscordClient : IDiscordClient | ||||
| { | { | ||||
| #region BaseDiscordClient | |||||
| public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } } | public event Func<LogMessage, Task> Log { add { _logEvent.Add(value); } remove { _logEvent.Remove(value); } } | ||||
| internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); | internal readonly AsyncEvent<Func<LogMessage, Task>> _logEvent = new AsyncEvent<Func<LogMessage, Task>>(); | ||||
| @@ -155,8 +156,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task<BotGateway> GetBotGatewayAsync(RequestOptions options = null) | public Task<BotGateway> GetBotGatewayAsync(RequestOptions options = null) | ||||
| => ClientHelper.GetBotGatewayAsync(this, options); | => ClientHelper.GetBotGatewayAsync(this, options); | ||||
| #endregion | |||||
| //IDiscordClient | |||||
| #region IDiscordClient | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected; | ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -235,5 +237,6 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| Task IDiscordClient.StopAsync() | Task IDiscordClient.StopAsync() | ||||
| => Task.Delay(0); | => Task.Delay(0); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -10,7 +10,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| internal static class ClientHelper | internal static class ClientHelper | ||||
| { | { | ||||
| //Applications | |||||
| #region Applications | |||||
| public static async Task<RestApplication> GetApplicationInfoAsync(BaseDiscordClient client, RequestOptions options) | public static async Task<RestApplication> GetApplicationInfoAsync(BaseDiscordClient client, RequestOptions options) | ||||
| { | { | ||||
| var model = await client.ApiClient.GetMyApplicationAsync(options).ConfigureAwait(false); | var model = await client.ApiClient.GetMyApplicationAsync(options).ConfigureAwait(false); | ||||
| @@ -263,5 +263,6 @@ namespace Discord.Rest | |||||
| public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) | public static Task RemoveRoleAsync(BaseDiscordClient client, ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) | ||||
| => client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options); | => client.ApiClient.RemoveRoleAsync(guildId, userId, roleId, options); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -24,6 +24,7 @@ namespace Discord.API | |||||
| { | { | ||||
| internal class DiscordRestApiClient : IDisposable | internal class DiscordRestApiClient : IDisposable | ||||
| { | { | ||||
| #region DiscordRestApiClient | |||||
| private static readonly ConcurrentDictionary<string, Func<BucketIds, BucketId>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, BucketId>>(); | private static readonly ConcurrentDictionary<string, Func<BucketIds, BucketId>> _bucketIdGenerators = new ConcurrentDictionary<string, Func<BucketIds, BucketId>>(); | ||||
| public event Func<string, string, double, Task> SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } } | public event Func<string, string, double, Task> SentRequest { add { _sentRequestEvent.Add(value); } remove { _sentRequestEvent.Remove(value); } } | ||||
| @@ -167,8 +168,9 @@ namespace Discord.API | |||||
| internal virtual Task ConnectInternalAsync() => Task.Delay(0); | internal virtual Task ConnectInternalAsync() => Task.Delay(0); | ||||
| internal virtual Task DisconnectInternalAsync(Exception ex = null) => Task.Delay(0); | internal virtual Task DisconnectInternalAsync(Exception ex = null) => Task.Delay(0); | ||||
| #endregion | |||||
| //Core | |||||
| #region Core | |||||
| internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ||||
| => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(method, ids, endpointExpr, funcName), clientBucket, options); | => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(method, ids, endpointExpr, funcName), clientBucket, options); | ||||
| @@ -271,15 +273,17 @@ namespace Discord.API | |||||
| return responseStream; | return responseStream; | ||||
| } | } | ||||
| #endregion | |||||
| //Auth | |||||
| #region Auth | |||||
| public async Task ValidateTokenAsync(RequestOptions options = null) | public async Task ValidateTokenAsync(RequestOptions options = null) | ||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| await SendAsync("GET", () => "auth/login", new BucketIds(), options: options).ConfigureAwait(false); | await SendAsync("GET", () => "auth/login", new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Gateway | |||||
| #region Gateway | |||||
| public async Task<GetGatewayResponse> GetGatewayAsync(RequestOptions options = null) | public async Task<GetGatewayResponse> GetGatewayAsync(RequestOptions options = null) | ||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| @@ -290,8 +294,9 @@ namespace Discord.API | |||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| return await SendAsync<GetBotGatewayResponse>("GET", () => "gateway/bot", new BucketIds(), options: options).ConfigureAwait(false); | return await SendAsync<GetBotGatewayResponse>("GET", () => "gateway/bot", new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channels | |||||
| #region Channels | |||||
| public async Task<Channel> GetChannelAsync(ulong channelId, RequestOptions options = null) | public async Task<Channel> GetChannelAsync(ulong channelId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(channelId, 0, nameof(channelId)); | Preconditions.NotEqual(channelId, 0, nameof(channelId)); | ||||
| @@ -414,8 +419,9 @@ namespace Discord.API | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| #endregion | |||||
| // Threads | |||||
| #region Threads | |||||
| public async Task<Channel> ModifyThreadAsync(ulong channelId, ModifyThreadParams args, RequestOptions options = null) | public async Task<Channel> ModifyThreadAsync(ulong channelId, ModifyThreadParams args, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(channelId, 0, nameof(channelId)); | Preconditions.NotEqual(channelId, 0, nameof(channelId)); | ||||
| @@ -582,8 +588,9 @@ namespace Discord.API | |||||
| return await SendAsync<ChannelThreads>("GET", () => $"channels/{channelId}/users/@me/threads/archived/private{query}", bucket, options: options); | return await SendAsync<ChannelThreads>("GET", () => $"channels/{channelId}/users/@me/threads/archived/private{query}", bucket, options: options); | ||||
| } | } | ||||
| #endregion | |||||
| // stage | |||||
| #region Stage | |||||
| public async Task<StageInstance> CreateStageInstanceAsync(CreateStageInstanceParams args, RequestOptions options = null) | public async Task<StageInstance> CreateStageInstanceAsync(CreateStageInstanceParams args, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -658,8 +665,9 @@ namespace Discord.API | |||||
| await SendJsonAsync("PATCH", () => $"guilds/{guildId}/voice-states/{userId}", args, bucket, options: options).ConfigureAwait(false); | await SendJsonAsync("PATCH", () => $"guilds/{guildId}/voice-states/{userId}", args, bucket, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| // roles | |||||
| #region Roles | |||||
| public async Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) | public async Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -682,8 +690,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| await SendAsync("DELETE", () => $"guilds/{guildId}/members/{userId}/roles/{roleId}", ids, options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"guilds/{guildId}/members/{userId}/roles/{roleId}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channel Messages | |||||
| #region Channel Messages | |||||
| public async Task<Message> GetChannelMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null) | public async Task<Message> GetChannelMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(channelId, 0, nameof(channelId)); | Preconditions.NotEqual(channelId, 0, nameof(channelId)); | ||||
| @@ -886,8 +895,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); | return await SendJsonAsync<Message>("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| // Stickers | |||||
| #region Stickers | |||||
| public async Task<Sticker> GetStickerAsync(ulong id, RequestOptions options = null) | public async Task<Sticker> GetStickerAsync(ulong id, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(id, 0, nameof(id)); | Preconditions.NotEqual(id, 0, nameof(id)); | ||||
| @@ -1044,8 +1054,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| await SendAsync("POST", () => $"channels/{channelId}/messages/{messageId}/crosspost", ids, options: options).ConfigureAwait(false); | await SendAsync("POST", () => $"channels/{channelId}/messages/{messageId}/crosspost", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channel Permissions | |||||
| #region Channel Permissions | |||||
| public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null) | public async Task ModifyChannelPermissionsAsync(ulong channelId, ulong targetId, ModifyChannelPermissionsParams args, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(channelId, 0, nameof(channelId)); | Preconditions.NotEqual(channelId, 0, nameof(channelId)); | ||||
| @@ -1065,8 +1076,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| await SendAsync("DELETE", () => $"channels/{channelId}/permissions/{targetId}", ids, options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"channels/{channelId}/permissions/{targetId}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channel Pins | |||||
| #region Channel Pins | |||||
| public async Task AddPinAsync(ulong channelId, ulong messageId, RequestOptions options = null) | public async Task AddPinAsync(ulong channelId, ulong messageId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.GreaterThan(channelId, 0, nameof(channelId)); | Preconditions.GreaterThan(channelId, 0, nameof(channelId)); | ||||
| @@ -1094,8 +1106,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| return await SendAsync<IReadOnlyCollection<Message>>("GET", () => $"channels/{channelId}/pins", ids, options: options).ConfigureAwait(false); | return await SendAsync<IReadOnlyCollection<Message>>("GET", () => $"channels/{channelId}/pins", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channel Recipients | |||||
| #region Channel Recipients | |||||
| public async Task AddGroupRecipientAsync(ulong channelId, ulong userId, RequestOptions options = null) | public async Task AddGroupRecipientAsync(ulong channelId, ulong userId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.GreaterThan(channelId, 0, nameof(channelId)); | Preconditions.GreaterThan(channelId, 0, nameof(channelId)); | ||||
| @@ -1115,8 +1128,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| await SendAsync("DELETE", () => $"channels/{channelId}/recipients/{userId}", ids, options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"channels/{channelId}/recipients/{userId}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Interactions | |||||
| #region Interactions | |||||
| public async Task<ApplicationCommand[]> GetGlobalApplicationCommandsAsync(RequestOptions options = null) | public async Task<ApplicationCommand[]> GetGlobalApplicationCommandsAsync(RequestOptions options = null) | ||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| @@ -1252,8 +1266,9 @@ namespace Discord.API | |||||
| return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false); | return await TrySendApplicationCommand(SendJsonAsync<ApplicationCommand[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands", commands, bucket, options: options)).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Interaction Responses | |||||
| #region Interaction Responses | |||||
| public async Task CreateInteractionResponse(InteractionResponse response, ulong interactionId, string interactionToken, RequestOptions options = null) | public async Task CreateInteractionResponse(InteractionResponse response, ulong interactionId, string interactionToken, RequestOptions options = null) | ||||
| { | { | ||||
| if(response.Data.IsSpecified && response.Data.Value.Content.IsSpecified) | if(response.Data.IsSpecified && response.Data.Value.Content.IsSpecified) | ||||
| @@ -1322,8 +1337,9 @@ namespace Discord.API | |||||
| await SendAsync("DELETE", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", new BucketIds(), options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"webhooks/{CurrentUserId}/{token}/messages/{id}", new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| // Application Command permissions | |||||
| #region Application Command permissions | |||||
| public async Task<GuildApplicationCommandPermission[]> GetGuildApplicationCommandPermissions(ulong guildId, RequestOptions options = null) | public async Task<GuildApplicationCommandPermission[]> GetGuildApplicationCommandPermissions(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1362,8 +1378,9 @@ namespace Discord.API | |||||
| return await SendJsonAsync<GuildApplicationCommandPermission[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | return await SendJsonAsync<GuildApplicationCommandPermission[]>("PUT", () => $"applications/{this.CurrentUserId}/guilds/{guildId}/commands/permissions", permissions, new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guilds | |||||
| #region Guilds | |||||
| public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null) | public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1436,8 +1453,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); | return await SendAsync<GetGuildPruneCountResponse>("GET", () => $"guilds/{guildId}/prune?days={args.Days}{endpointRoleIds}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Bans | |||||
| #region Guild Bans | |||||
| public async Task<IReadOnlyCollection<Ban>> GetGuildBansAsync(ulong guildId, RequestOptions options = null) | public async Task<IReadOnlyCollection<Ban>> GetGuildBansAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1488,8 +1506,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| await SendAsync("DELETE", () => $"guilds/{guildId}/bans/{userId}", ids, options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"guilds/{guildId}/bans/{userId}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Widget | |||||
| #region Guild Widget | |||||
| /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | ||||
| public async Task<GuildWidget> GetGuildWidgetAsync(ulong guildId, RequestOptions options = null) | public async Task<GuildWidget> GetGuildWidgetAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -1514,8 +1533,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false); | return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Integrations | |||||
| #region Guild Integrations | |||||
| /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> | ||||
| public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) | public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -1567,8 +1587,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations/{integrationId}/sync", ids, options: options).ConfigureAwait(false); | return await SendAsync<Integration>("POST", () => $"guilds/{guildId}/integrations/{integrationId}/sync", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Invites | |||||
| #region Guild Invites | |||||
| /// <exception cref="ArgumentException"><paramref name="inviteId"/> cannot be blank.</exception> | /// <exception cref="ArgumentException"><paramref name="inviteId"/> cannot be blank.</exception> | ||||
| /// <exception cref="ArgumentNullException"><paramref name="inviteId"/> must not be <see langword="null"/>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="inviteId"/> must not be <see langword="null"/>.</exception> | ||||
| public async Task<InviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null) | public async Task<InviteMetadata> GetInviteAsync(string inviteId, RequestOptions options = null) | ||||
| @@ -1651,8 +1672,9 @@ namespace Discord.API | |||||
| return await SendAsync<Invite>("DELETE", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false); | return await SendAsync<Invite>("DELETE", () => $"invites/{inviteId}", new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Members | |||||
| #region Guild Members | |||||
| public async Task<GuildMember> AddGuildMemberAsync(ulong guildId, ulong userId, AddGuildMemberParams args, RequestOptions options = null) | public async Task<GuildMember> AddGuildMemberAsync(ulong guildId, ulong userId, AddGuildMemberParams args, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1750,8 +1772,9 @@ namespace Discord.API | |||||
| Expression<Func<string>> endpoint = () => $"guilds/{guildId}/members/search?limit={limit}&query={query}"; | Expression<Func<string>> endpoint = () => $"guilds/{guildId}/members/search?limit={limit}&query={query}"; | ||||
| return await SendAsync<IReadOnlyCollection<GuildMember>>("GET", endpoint, ids, options: options).ConfigureAwait(false); | return await SendAsync<IReadOnlyCollection<GuildMember>>("GET", endpoint, ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild Roles | |||||
| #region Guild Roles | |||||
| public async Task<IReadOnlyCollection<Role>> GetGuildRolesAsync(ulong guildId, RequestOptions options = null) | public async Task<IReadOnlyCollection<Role>> GetGuildRolesAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1798,8 +1821,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendJsonAsync<IReadOnlyCollection<Role>>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false); | return await SendJsonAsync<IReadOnlyCollection<Role>>("PATCH", () => $"guilds/{guildId}/roles", args, ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Guild emoji | |||||
| #region Guild emoji | |||||
| public async Task<IReadOnlyCollection<Emoji>> GetGuildEmotesAsync(ulong guildId, RequestOptions options = null) | public async Task<IReadOnlyCollection<Emoji>> GetGuildEmotesAsync(ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1851,8 +1875,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| await SendAsync("DELETE", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options).ConfigureAwait(false); | await SendAsync("DELETE", () => $"guilds/{guildId}/emojis/{emoteId}", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Users | |||||
| #region Users | |||||
| public async Task<User> GetUserAsync(ulong userId, RequestOptions options = null) | public async Task<User> GetUserAsync(ulong userId, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(userId, 0, nameof(userId)); | Preconditions.NotEqual(userId, 0, nameof(userId)); | ||||
| @@ -1864,8 +1889,9 @@ namespace Discord.API | |||||
| } | } | ||||
| catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } | ||||
| } | } | ||||
| #endregion | |||||
| //Current User/DMs | |||||
| #region Current User/DMs | |||||
| public async Task<User> GetMyUserAsync(RequestOptions options = null) | public async Task<User> GetMyUserAsync(RequestOptions options = null) | ||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| @@ -1924,8 +1950,9 @@ namespace Discord.API | |||||
| return await SendJsonAsync<Channel>("POST", () => "users/@me/channels", args, new BucketIds(), options: options).ConfigureAwait(false); | return await SendJsonAsync<Channel>("POST", () => "users/@me/channels", args, new BucketIds(), options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Voice Regions | |||||
| #region Voice Regions | |||||
| public async Task<IReadOnlyCollection<VoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | public async Task<IReadOnlyCollection<VoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | ||||
| { | { | ||||
| options = RequestOptions.CreateOrClone(options); | options = RequestOptions.CreateOrClone(options); | ||||
| @@ -1939,8 +1966,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(guildId: guildId); | var ids = new BucketIds(guildId: guildId); | ||||
| return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false); | return await SendAsync<IReadOnlyCollection<VoiceRegion>>("GET", () => $"guilds/{guildId}/regions", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Audit logs | |||||
| #region Audit logs | |||||
| public async Task<AuditLog> GetAuditLogsAsync(ulong guildId, GetAuditLogsParams args, RequestOptions options = null) | public async Task<AuditLog> GetAuditLogsAsync(ulong guildId, GetAuditLogsParams args, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(guildId, 0, nameof(guildId)); | Preconditions.NotEqual(guildId, 0, nameof(guildId)); | ||||
| @@ -1969,12 +1997,13 @@ namespace Discord.API | |||||
| .Append(args.ActionType.Value); | .Append(args.ActionType.Value); | ||||
| } | } | ||||
| // still use string interp for the query w/o params, as this is necessary for CreateBucketId | |||||
| // Still use string interp for the query w/o params, as this is necessary for CreateBucketId | |||||
| endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}{queryArgs.ToString()}"; | endpoint = () => $"guilds/{guildId}/audit-logs?limit={limit}{queryArgs.ToString()}"; | ||||
| return await SendAsync<AuditLog>("GET", endpoint, ids, options: options).ConfigureAwait(false); | return await SendAsync<AuditLog>("GET", endpoint, ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Webhooks | |||||
| #region Webhooks | |||||
| public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null) | public async Task<Webhook> CreateWebhookAsync(ulong channelId, CreateWebhookParams args, RequestOptions options = null) | ||||
| { | { | ||||
| Preconditions.NotEqual(channelId, 0, nameof(channelId)); | Preconditions.NotEqual(channelId, 0, nameof(channelId)); | ||||
| @@ -2037,8 +2066,9 @@ namespace Discord.API | |||||
| var ids = new BucketIds(channelId: channelId); | var ids = new BucketIds(channelId: channelId); | ||||
| return await SendAsync<IReadOnlyCollection<Webhook>>("GET", () => $"channels/{channelId}/webhooks", ids, options: options).ConfigureAwait(false); | return await SendAsync<IReadOnlyCollection<Webhook>>("GET", () => $"channels/{channelId}/webhooks", ids, options: options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Helpers | |||||
| #region Helpers | |||||
| /// <exception cref="InvalidOperationException">Client is not logged in.</exception> | /// <exception cref="InvalidOperationException">Client is not logged in.</exception> | ||||
| protected void CheckState() | protected void CheckState() | ||||
| { | { | ||||
| @@ -2248,5 +2278,6 @@ namespace Discord.API | |||||
| return (expr as MemberExpression).Member.Name; | return (expr as MemberExpression).Member.Name; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ namespace Discord.Rest | |||||
| /// </summary> | /// </summary> | ||||
| public class DiscordRestClient : BaseDiscordClient, IDiscordClient | public class DiscordRestClient : BaseDiscordClient, IDiscordClient | ||||
| { | { | ||||
| #region DiscordRestClient | |||||
| private RestApplication _applicationInfo; | private RestApplication _applicationInfo; | ||||
| /// <summary> | /// <summary> | ||||
| @@ -138,7 +139,9 @@ namespace Discord.Rest | |||||
| => MessageHelper.RemoveAllReactionsAsync(channelId, messageId, this, options); | => MessageHelper.RemoveAllReactionsAsync(channelId, messageId, this, options); | ||||
| public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) | public Task RemoveAllReactionsForEmoteAsync(ulong channelId, ulong messageId, IEmote emote, RequestOptions options = null) | ||||
| => MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options); | => MessageHelper.RemoveAllReactionsForEmoteAsync(channelId, messageId, emote, this, options); | ||||
| //IDiscordClient | |||||
| #endregion | |||||
| #region IDiscordClient | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) | async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) | ||||
| => await GetApplicationInfoAsync(options).ConfigureAwait(false); | => await GetApplicationInfoAsync(options).ConfigureAwait(false); | ||||
| @@ -229,5 +232,6 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IApplicationCommand> IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options) | async Task<IApplicationCommand> IDiscordClient.GetGlobalApplicationCommandAsync(ulong id, RequestOptions options) | ||||
| => await ClientHelper.GetGlobalApplicationCommand(this, id, options).ConfigureAwait(false); | => await ClientHelper.GetGlobalApplicationCommand(this, id, options).ConfigureAwait(false); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestCategoryChannel : RestGuildChannel, ICategoryChannel | public class RestCategoryChannel : RestGuildChannel, ICategoryChannel | ||||
| { | { | ||||
| #region RestCategoryChannel | |||||
| internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id) | internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id) | ||||
| : base(discord, guild, id) | : base(discord, guild, id) | ||||
| { | { | ||||
| @@ -24,8 +25,9 @@ namespace Discord.Rest | |||||
| } | } | ||||
| private string DebuggerDisplay => $"{Name} ({Id}, Category)"; | private string DebuggerDisplay => $"{Name} ({Id}, Category)"; | ||||
| #endregion | |||||
| //IChannel | |||||
| #region IChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | ||||
| IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | ||||
| @@ -34,5 +36,6 @@ namespace Discord.Rest | |||||
| /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | /// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | ||||
| Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| => throw new NotSupportedException(); | => throw new NotSupportedException(); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -11,6 +11,7 @@ namespace Discord.Rest | |||||
| /// </summary> | /// </summary> | ||||
| public class RestChannel : RestEntity<ulong>, IChannel, IUpdateable | public class RestChannel : RestEntity<ulong>, IChannel, IUpdateable | ||||
| { | { | ||||
| #region RestChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | ||||
| @@ -53,8 +54,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public virtual Task UpdateAsync(RequestOptions options = null) => Task.Delay(0); | public virtual Task UpdateAsync(RequestOptions options = null) => Task.Delay(0); | ||||
| #endregion | |||||
| //IChannel | |||||
| #region IChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| string IChannel.Name => null; | string IChannel.Name => null; | ||||
| @@ -64,5 +66,6 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | ||||
| => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden | => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,6 +12,7 @@ namespace Discord.Rest | |||||
| /// </summary> | /// </summary> | ||||
| public class RestGuildChannel : RestChannel, IGuildChannel | public class RestGuildChannel : RestChannel, IGuildChannel | ||||
| { | { | ||||
| #region RestGuildChannel | |||||
| private ImmutableArray<Overwrite> _overwrites; | private ImmutableArray<Overwrite> _overwrites; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -191,8 +192,9 @@ namespace Discord.Rest | |||||
| /// A string that is the name of this channel. | /// A string that is the name of this channel. | ||||
| /// </returns> | /// </returns> | ||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| #endregion | |||||
| //IGuildChannel | |||||
| #region IGuildChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IGuild IGuildChannel.Guild | IGuild IGuildChannel.Guild | ||||
| { | { | ||||
| @@ -229,13 +231,15 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| => Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice | => Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice | ||||
| #endregion | |||||
| //IChannel | |||||
| #region IChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | ||||
| => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice | => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| => Task.FromResult<IUser>(null); //Overridden in Text/Voice | => Task.FromResult<IUser>(null); //Overridden in Text/Voice | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,6 +14,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel | public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel | ||||
| { | { | ||||
| #region RestTextChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public string Topic { get; private set; } | public string Topic { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -210,8 +211,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task SyncPermissionsAsync(RequestOptions options = null) | public Task SyncPermissionsAsync(RequestOptions options = null) | ||||
| => ChannelHelper.SyncPermissionsAsync(this, Discord, options); | => ChannelHelper.SyncPermissionsAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Invites | |||||
| #region Invites | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) | public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) | ||||
| => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); | => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); | ||||
| @@ -261,8 +263,9 @@ namespace Discord.Rest | |||||
| var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, options); | var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, options); | ||||
| return RestThreadChannel.Create(Discord, this.Guild, model); | return RestThreadChannel.Create(Discord, this.Guild, model); | ||||
| } | } | ||||
| #endregion | |||||
| //ITextChannel | |||||
| #region ITextChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options) | async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options) | ||||
| => await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false); | => await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false); | ||||
| @@ -275,8 +278,9 @@ namespace Discord.Rest | |||||
| async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options) | async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options) | ||||
| => await CreateThreadAsync(name, type, autoArchiveDuration, message, options); | => await CreateThreadAsync(name, type, autoArchiveDuration, message, options); | ||||
| #endregion | |||||
| //IMessageChannel | |||||
| #region IMessageChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) | async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -324,8 +328,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers) | async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers) | ||||
| => await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false); | => await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false); | ||||
| #endregion | |||||
| //IGuildChannel | |||||
| #region IGuildChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -342,8 +347,9 @@ namespace Discord.Rest | |||||
| else | else | ||||
| return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | ||||
| } | } | ||||
| #endregion | |||||
| //IChannel | |||||
| #region IChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -360,8 +366,9 @@ namespace Discord.Rest | |||||
| else | else | ||||
| return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | ||||
| } | } | ||||
| #endregion | |||||
| // INestedChannel | |||||
| #region ITextChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -369,5 +376,6 @@ namespace Discord.Rest | |||||
| return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; | return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,6 +14,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel | public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel | ||||
| { | { | ||||
| #region RestVoiceChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public int Bitrate { get; private set; } | public int Bitrate { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -63,8 +64,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task SyncPermissionsAsync(RequestOptions options = null) | public Task SyncPermissionsAsync(RequestOptions options = null) | ||||
| => ChannelHelper.SyncPermissionsAsync(this, Discord, options); | => ChannelHelper.SyncPermissionsAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Invites | |||||
| #region Invites | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) | public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) | ||||
| => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); | => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); | ||||
| @@ -79,22 +81,25 @@ namespace Discord.Rest | |||||
| => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); | => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); | ||||
| private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; | private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; | ||||
| #endregion | |||||
| //IAudioChannel | |||||
| #region IAudioChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| /// <exception cref="NotSupportedException">Connecting to a REST-based channel is not supported.</exception> | /// <exception cref="NotSupportedException">Connecting to a REST-based channel is not supported.</exception> | ||||
| Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); } | Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); } | ||||
| Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); } | Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); } | ||||
| #endregion | |||||
| //IGuildChannel | |||||
| #region IGuildChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| => Task.FromResult<IGuildUser>(null); | => Task.FromResult<IGuildUser>(null); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | ||||
| => AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | => AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | ||||
| #endregion | |||||
| // INestedChannel | |||||
| #region INestedChannel | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -102,5 +107,6 @@ namespace Discord.Rest | |||||
| return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; | return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,7 +14,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| internal static class GuildHelper | internal static class GuildHelper | ||||
| { | { | ||||
| //General | |||||
| #region General | |||||
| /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> | ||||
| public static async Task<Model> ModifyAsync(IGuild guild, BaseDiscordClient client, | public static async Task<Model> ModifyAsync(IGuild guild, BaseDiscordClient client, | ||||
| Action<GuildProperties> func, RequestOptions options) | Action<GuildProperties> func, RequestOptions options) | ||||
| @@ -123,8 +123,9 @@ namespace Discord.Rest | |||||
| { | { | ||||
| await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); | await client.ApiClient.DeleteGuildAsync(guild.Id, options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Bans | |||||
| #region Bans | |||||
| public static async Task<IReadOnlyCollection<RestBan>> GetBansAsync(IGuild guild, BaseDiscordClient client, | public static async Task<IReadOnlyCollection<RestBan>> GetBansAsync(IGuild guild, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| @@ -148,8 +149,9 @@ namespace Discord.Rest | |||||
| { | { | ||||
| await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); | await client.ApiClient.RemoveGuildBanAsync(guild.Id, userId, options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| //Channels | |||||
| #region Channels | |||||
| public static async Task<RestGuildChannel> GetChannelAsync(IGuild guild, BaseDiscordClient client, | public static async Task<RestGuildChannel> GetChannelAsync(IGuild guild, BaseDiscordClient client, | ||||
| ulong id, RequestOptions options) | ulong id, RequestOptions options) | ||||
| { | { | ||||
| @@ -275,16 +277,18 @@ namespace Discord.Rest | |||||
| var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); | var model = await client.ApiClient.CreateGuildChannelAsync(guild.Id, args, options).ConfigureAwait(false); | ||||
| return RestCategoryChannel.Create(client, guild, model); | return RestCategoryChannel.Create(client, guild, model); | ||||
| } | } | ||||
| #endregion | |||||
| //Voice Regions | |||||
| #region Voice Regions | |||||
| public static async Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(IGuild guild, BaseDiscordClient client, | public static async Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(IGuild guild, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetGuildVoiceRegionsAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildVoiceRegionsAsync(guild.Id, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestVoiceRegion.Create(client, x)).ToImmutableArray(); | return models.Select(x => RestVoiceRegion.Create(client, x)).ToImmutableArray(); | ||||
| } | } | ||||
| #endregion | |||||
| //Integrations | |||||
| #region Integrations | |||||
| public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, | public static async Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(IGuild guild, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| @@ -298,8 +302,9 @@ namespace Discord.Rest | |||||
| var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); | var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); | ||||
| return RestGuildIntegration.Create(client, guild, model); | return RestGuildIntegration.Create(client, guild, model); | ||||
| } | } | ||||
| #endregion | |||||
| //Interactions | |||||
| #region Interactions | |||||
| public static async Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client, | public static async Task<IReadOnlyCollection<RestGuildCommand>> GetSlashCommandsAsync(IGuild guild, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| @@ -312,8 +317,9 @@ namespace Discord.Rest | |||||
| var model = await client.ApiClient.GetGuildApplicationCommandAsync(guild.Id, id, options); | var model = await client.ApiClient.GetGuildApplicationCommandAsync(guild.Id, id, options); | ||||
| return RestGuildCommand.Create(client, model, guild.Id); | return RestGuildCommand.Create(client, model, guild.Id); | ||||
| } | } | ||||
| #endregion | |||||
| //Invites | |||||
| #region Invites | |||||
| public static async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client, | public static async Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(IGuild guild, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| @@ -329,8 +335,9 @@ namespace Discord.Rest | |||||
| inviteModel.Uses = vanityModel.Uses; | inviteModel.Uses = vanityModel.Uses; | ||||
| return RestInviteMetadata.Create(client, guild, null, inviteModel); | return RestInviteMetadata.Create(client, guild, null, inviteModel); | ||||
| } | } | ||||
| #endregion | |||||
| //Roles | |||||
| #region Roles | |||||
| /// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="name"/> is <c>null</c>.</exception> | ||||
| public static async Task<RestRole> CreateRoleAsync(IGuild guild, BaseDiscordClient client, | public static async Task<RestRole> CreateRoleAsync(IGuild guild, BaseDiscordClient client, | ||||
| string name, GuildPermissions? permissions, Color? color, bool isHoisted, bool isMentionable, RequestOptions options) | string name, GuildPermissions? permissions, Color? color, bool isHoisted, bool isMentionable, RequestOptions options) | ||||
| @@ -350,8 +357,9 @@ namespace Discord.Rest | |||||
| return RestRole.Create(client, guild, model); | return RestRole.Create(client, guild, model); | ||||
| } | } | ||||
| #endregion | |||||
| //Users | |||||
| #region Users | |||||
| public static async Task<RestGuildUser> AddGuildUserAsync(IGuild guild, BaseDiscordClient client, ulong userId, string accessToken, | public static async Task<RestGuildUser> AddGuildUserAsync(IGuild guild, BaseDiscordClient client, ulong userId, string accessToken, | ||||
| Action<AddGuildUserProperties> func, RequestOptions options) | Action<AddGuildUserProperties> func, RequestOptions options) | ||||
| { | { | ||||
| @@ -470,8 +478,9 @@ namespace Discord.Rest | |||||
| var models = await client.ApiClient.SearchGuildMembersAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | var models = await client.ApiClient.SearchGuildMembersAsync(guild.Id, apiArgs, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestGuildUser.Create(client, guild, x)).ToImmutableArray(); | return models.Select(x => RestGuildUser.Create(client, guild, x)).ToImmutableArray(); | ||||
| } | } | ||||
| #endregion | |||||
| // Audit logs | |||||
| #region Audit logs | |||||
| public static IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client, | public static IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(IGuild guild, BaseDiscordClient client, | ||||
| ulong? from, int? limit, RequestOptions options, ulong? userId = null, ActionType? actionType = null) | ulong? from, int? limit, RequestOptions options, ulong? userId = null, ActionType? actionType = null) | ||||
| { | { | ||||
| @@ -503,8 +512,9 @@ namespace Discord.Rest | |||||
| count: limit | count: limit | ||||
| ); | ); | ||||
| } | } | ||||
| #endregion | |||||
| //Webhooks | |||||
| #region Webhooks | |||||
| public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options) | public static async Task<RestWebhook> GetWebhookAsync(IGuild guild, BaseDiscordClient client, ulong id, RequestOptions options) | ||||
| { | { | ||||
| var model = await client.ApiClient.GetWebhookAsync(id, options: options).ConfigureAwait(false); | var model = await client.ApiClient.GetWebhookAsync(id, options: options).ConfigureAwait(false); | ||||
| @@ -517,8 +527,9 @@ namespace Discord.Rest | |||||
| var models = await client.ApiClient.GetGuildWebhooksAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildWebhooksAsync(guild.Id, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestWebhook.Create(client, guild, x)).ToImmutableArray(); | return models.Select(x => RestWebhook.Create(client, guild, x)).ToImmutableArray(); | ||||
| } | } | ||||
| #endregion | |||||
| //Emotes | |||||
| #region Emotes | |||||
| public static async Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) | public static async Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(IGuild guild, BaseDiscordClient client, RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetGuildEmotesAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildEmotesAsync(guild.Id, options).ConfigureAwait(false); | ||||
| @@ -637,5 +648,6 @@ namespace Discord.Rest | |||||
| public static async Task DeleteStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, RequestOptions options = null) | public static async Task DeleteStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, RequestOptions options = null) | ||||
| => await client.ApiClient.DeleteStickerAsync(guildId, sticker.Id, options).ConfigureAwait(false); | => await client.ApiClient.DeleteStickerAsync(guildId, sticker.Id, options).ConfigureAwait(false); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -18,6 +18,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable | public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable | ||||
| { | { | ||||
| #region RestGuild | |||||
| private ImmutableDictionary<ulong, RestRole> _roles; | private ImmutableDictionary<ulong, RestRole> _roles; | ||||
| private ImmutableArray<GuildEmote> _emotes; | private ImmutableArray<GuildEmote> _emotes; | ||||
| private ImmutableArray<CustomSticker> _stickers; | private ImmutableArray<CustomSticker> _stickers; | ||||
| @@ -217,8 +218,9 @@ namespace Discord.Rest | |||||
| WidgetChannelId = model.ChannelId; | WidgetChannelId = model.ChannelId; | ||||
| IsWidgetEnabled = model.Enabled; | IsWidgetEnabled = model.Enabled; | ||||
| } | } | ||||
| #endregion | |||||
| //General | |||||
| #region General | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public async Task UpdateAsync(RequestOptions options = null) | public async Task UpdateAsync(RequestOptions options = null) | ||||
| => Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false)); | => Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false)); | ||||
| @@ -277,8 +279,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task LeaveAsync(RequestOptions options = null) | public Task LeaveAsync(RequestOptions options = null) | ||||
| => GuildHelper.LeaveAsync(this, Discord, options); | => GuildHelper.LeaveAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Interactions | |||||
| #region Interactions | |||||
| /// <summary> | /// <summary> | ||||
| /// Deletes all slash commands in the current guild. | /// Deletes all slash commands in the current guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -311,8 +314,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null) | public Task<RestGuildCommand> GetSlashCommandAsync(ulong id, RequestOptions options = null) | ||||
| => GuildHelper.GetSlashCommandAsync(this, id, Discord, options); | => GuildHelper.GetSlashCommandAsync(this, id, Discord, options); | ||||
| #endregion | |||||
| //Bans | |||||
| #region Bans | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all users banned in this guild. | /// Gets a collection of all users banned in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -360,8 +364,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task RemoveBanAsync(ulong userId, RequestOptions options = null) | public Task RemoveBanAsync(ulong userId, RequestOptions options = null) | ||||
| => GuildHelper.RemoveBanAsync(this, Discord, userId, options); | => GuildHelper.RemoveBanAsync(this, Discord, userId, options); | ||||
| #endregion | |||||
| //Channels | |||||
| #region Channels | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all channels in this guild. | /// Gets a collection of all channels in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -697,14 +702,16 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetVoiceRegionsAsync(this, Discord, options); | => GuildHelper.GetVoiceRegionsAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Integrations | |||||
| #region Integrations | |||||
| public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetIntegrationsAsync(this, Discord, options); | => GuildHelper.GetIntegrationsAsync(this, Discord, options); | ||||
| public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | ||||
| => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | ||||
| #endregion | |||||
| //Invites | |||||
| #region Invites | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all invites in this guild. | /// Gets a collection of all invites in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -724,8 +731,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null) | public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetVanityInviteAsync(this, Discord, options); | => GuildHelper.GetVanityInviteAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Roles | |||||
| #region Roles | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a role in this guild. | /// Gets a role in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -765,8 +773,9 @@ namespace Discord.Rest | |||||
| _roles = _roles.Add(role.Id, role); | _roles = _roles.Add(role.Id, role); | ||||
| return role; | return role; | ||||
| } | } | ||||
| #endregion | |||||
| //Users | |||||
| #region Users | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all users in this guild. | /// Gets a collection of all users in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -860,8 +869,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) | public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) | ||||
| => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); | => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); | ||||
| #endregion | |||||
| //Audit logs | |||||
| #region Audit logs | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the specified number of audit log entries for this guild. | /// Gets the specified number of audit log entries for this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -876,8 +886,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null) | public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null) | ||||
| => GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType); | => GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType); | ||||
| #endregion | |||||
| //Webhooks | |||||
| #region Webhooks | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a webhook found within this guild. | /// Gets a webhook found within this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -900,8 +911,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetWebhooksAsync(this, Discord, options); | => GuildHelper.GetWebhooksAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Interactions | |||||
| #region Interactions | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets this guilds slash commands commands | /// Gets this guilds slash commands commands | ||||
| /// </summary> | /// </summary> | ||||
| @@ -961,8 +973,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| private string DebuggerDisplay => $"{Name} ({Id})"; | private string DebuggerDisplay => $"{Name} ({Id})"; | ||||
| #endregion | |||||
| //Emotes | |||||
| #region Emotes | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetEmotesAsync(this, Discord, options); | => GuildHelper.GetEmotesAsync(this, Discord, options); | ||||
| @@ -976,11 +989,20 @@ namespace Discord.Rest | |||||
| /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception> | /// <exception cref="ArgumentNullException"><paramref name="func"/> is <see langword="null"/>.</exception> | ||||
| public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null) | public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null) | ||||
| => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options); | => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options); | ||||
| /// <summary> | |||||
| /// Moves the user to the voice channel. | |||||
| /// </summary> | |||||
| /// <param name="user">The user to move.</param> | |||||
| /// <param name="targetChannel">the channel where the user gets moved to.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for moving a user.</returns> | |||||
| public Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel) | |||||
| => user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>(targetChannel)); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) | public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) | ||||
| => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); | => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); | ||||
| #endregion | |||||
| //Stickers | |||||
| #region Stickers | |||||
| /// <summary> | /// <summary> | ||||
| /// Creates a new sticker in this guild. | /// Creates a new sticker in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -1087,8 +1109,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public Task DeleteStickerAsync(CustomSticker sticker, RequestOptions options = null) | public Task DeleteStickerAsync(CustomSticker sticker, RequestOptions options = null) | ||||
| => sticker.DeleteAsync(options); | => sticker.DeleteAsync(options); | ||||
| #endregion | |||||
| //IGuild | |||||
| #region IGuild | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| bool IGuild.Available => Available; | bool IGuild.Available => Available; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -1291,6 +1314,13 @@ namespace Discord.Rest | |||||
| async Task<IGuildUser> IGuild.AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func, RequestOptions options) | async Task<IGuildUser> IGuild.AddGuildUserAsync(ulong userId, string accessToken, Action<AddGuildUserProperties> func, RequestOptions options) | ||||
| => await AddGuildUserAsync(userId, accessToken, func, options); | => await AddGuildUserAsync(userId, accessToken, func, options); | ||||
| /// <summary> | |||||
| /// Disconnects the user from its current voice channel | |||||
| /// </summary> | |||||
| /// <param name="user">The user to disconnect.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns> | |||||
| async Task IGuild.DisconnectAsync(IGuildUser user) => await user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>()); | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | ||||
| { | { | ||||
| @@ -1399,5 +1429,6 @@ namespace Discord.Rest | |||||
| else | else | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -11,6 +11,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| internal static class InteractionHelper | internal static class InteractionHelper | ||||
| { | { | ||||
| #region InteractionHelper | |||||
| public static Task DeleteAllGuildCommandsAsync(BaseDiscordClient client, ulong guildId, RequestOptions options = null) | public static Task DeleteAllGuildCommandsAsync(BaseDiscordClient client, ulong guildId, RequestOptions options = null) | ||||
| { | { | ||||
| return client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, new CreateApplicationCommandParams[0], options); | return client.ApiClient.BulkOverwriteGuildApplicationCommands(guildId, new CreateApplicationCommandParams[0], options); | ||||
| @@ -42,8 +43,9 @@ namespace Discord.Rest | |||||
| RestFollowupMessage entity = RestFollowupMessage.Create(client, model, token, channel); | RestFollowupMessage entity = RestFollowupMessage.Create(client, model, token, channel); | ||||
| return entity; | return entity; | ||||
| } | } | ||||
| #endregion | |||||
| // Global commands | |||||
| #region Global commands | |||||
| public static async Task<RestGlobalCommand> GetGlobalCommandAsync(BaseDiscordClient client, ulong id, | public static async Task<RestGlobalCommand> GetGlobalCommandAsync(BaseDiscordClient client, ulong id, | ||||
| RequestOptions options = null) | RequestOptions options = null) | ||||
| { | { | ||||
| @@ -236,8 +238,9 @@ namespace Discord.Rest | |||||
| await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false); | await client.ApiClient.DeleteGlobalApplicationCommandAsync(command.Id, options).ConfigureAwait(false); | ||||
| } | } | ||||
| #endregion | |||||
| // Guild Commands | |||||
| #region Guild Commands | |||||
| public static Task<ApplicationCommand> CreateGuildCommand<TArg>(BaseDiscordClient client, ulong guildId, | public static Task<ApplicationCommand> CreateGuildCommand<TArg>(BaseDiscordClient client, ulong guildId, | ||||
| Action<TArg> func, RequestOptions options) where TArg : ApplicationCommandProperties | Action<TArg> func, RequestOptions options) where TArg : ApplicationCommandProperties | ||||
| { | { | ||||
| @@ -324,8 +327,9 @@ namespace Discord.Rest | |||||
| return DeleteGlobalCommand(client, command, options); | return DeleteGlobalCommand(client, command, options); | ||||
| } | } | ||||
| } | } | ||||
| #endregion | |||||
| // Responses | |||||
| #region Responses | |||||
| public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func, | public static async Task<Discord.API.Message> ModifyFollowupMessage(BaseDiscordClient client, RestFollowupMessage message, Action<MessageProperties> func, | ||||
| RequestOptions options = null) | RequestOptions options = null) | ||||
| { | { | ||||
| @@ -412,8 +416,9 @@ namespace Discord.Rest | |||||
| public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | public static async Task DeletedInteractionResponse(BaseDiscordClient client, RestInteractionMessage message, RequestOptions options = null) | ||||
| => await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options); | => await client.ApiClient.DeleteInteractionFollowupMessage(message.Id, message.Token, options); | ||||
| #endregion | |||||
| // Guild permissions | |||||
| #region Guild permissions | |||||
| public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> GetGuildCommandPermissionsAsync(BaseDiscordClient client, | public static async Task<IReadOnlyCollection<GuildApplicationCommandPermission>> GetGuildCommandPermissionsAsync(BaseDiscordClient client, | ||||
| ulong guildId, RequestOptions options) | ulong guildId, RequestOptions options) | ||||
| { | { | ||||
| @@ -506,5 +511,6 @@ namespace Discord.Rest | |||||
| x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select( | x => new GuildApplicationCommandPermission(x.Id, x.ApplicationId, x.GuildId, x.Permissions.Select( | ||||
| y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray(); | y => new ApplicationCommandPermission(y.Id, y.Type, y.Permission)).ToArray())).ToArray(); | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -13,6 +13,7 @@ namespace Discord.Rest | |||||
| /// </summary> | /// </summary> | ||||
| public class RestApplicationCommandOption : IApplicationCommandOption | public class RestApplicationCommandOption : IApplicationCommandOption | ||||
| { | { | ||||
| #region RestApplicationCommandOption | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public ApplicationCommandOptionType Type { get; private set; } | public ApplicationCommandOptionType Type { get; private set; } | ||||
| @@ -67,11 +68,13 @@ namespace Discord.Rest | |||||
| ? model.Choices.Value.Select(x => new RestApplicationCommandChoice(x)).ToImmutableArray() | ? model.Choices.Value.Select(x => new RestApplicationCommandChoice(x)).ToImmutableArray() | ||||
| : null; | : null; | ||||
| } | } | ||||
| #endregion | |||||
| //IApplicationCommandOption | |||||
| #region IApplicationCommandOption | |||||
| IReadOnlyCollection<IApplicationCommandOption> IApplicationCommandOption.Options | IReadOnlyCollection<IApplicationCommandOption> IApplicationCommandOption.Options | ||||
| => Options; | => Options; | ||||
| IReadOnlyCollection<IApplicationCommandOptionChoice> IApplicationCommandOption.Choices | IReadOnlyCollection<IApplicationCommandOptionChoice> IApplicationCommandOption.Choices | ||||
| => Choices; | => Choices; | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -11,6 +11,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestRole : RestEntity<ulong>, IRole | public class RestRole : RestEntity<ulong>, IRole | ||||
| { | { | ||||
| #region RestRole | |||||
| internal IGuild Guild { get; } | internal IGuild Guild { get; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Color Color { get; private set; } | public Color Color { get; private set; } | ||||
| @@ -64,7 +65,7 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public async Task ModifyAsync(Action<RoleProperties> func, RequestOptions options = null) | public async Task ModifyAsync(Action<RoleProperties> func, RequestOptions options = null) | ||||
| { | |||||
| { | |||||
| var model = await RoleHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); | var model = await RoleHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); | ||||
| Update(model); | Update(model); | ||||
| } | } | ||||
| @@ -83,8 +84,9 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| private string DebuggerDisplay => $"{Name} ({Id})"; | private string DebuggerDisplay => $"{Name} ({Id})"; | ||||
| #endregion | |||||
| //IRole | |||||
| #region IRole | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IGuild IRole.Guild | IGuild IRole.Guild | ||||
| { | { | ||||
| @@ -7,7 +7,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| internal static class RoleHelper | internal static class RoleHelper | ||||
| { | { | ||||
| //General | |||||
| #region General | |||||
| public static async Task DeleteAsync(IRole role, BaseDiscordClient client, | public static async Task DeleteAsync(IRole role, BaseDiscordClient client, | ||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| @@ -36,5 +36,6 @@ namespace Discord.Rest | |||||
| } | } | ||||
| return model; | return model; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -14,6 +14,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestGuildUser : RestUser, IGuildUser | public class RestGuildUser : RestUser, IGuildUser | ||||
| { | { | ||||
| #region RestGuildUser | |||||
| private long? _premiumSinceTicks; | private long? _premiumSinceTicks; | ||||
| private long? _joinedAtTicks; | private long? _joinedAtTicks; | ||||
| private ImmutableArray<ulong> _roleIds; | private ImmutableArray<ulong> _roleIds; | ||||
| @@ -155,8 +156,9 @@ namespace Discord.Rest | |||||
| var guildPerms = GuildPermissions; | var guildPerms = GuildPermissions; | ||||
| return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | ||||
| } | } | ||||
| #endregion | |||||
| //IGuildUser | |||||
| #region IGuildUser | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IGuild IGuildUser.Guild | IGuild IGuildUser.Guild | ||||
| { | { | ||||
| @@ -167,8 +169,9 @@ namespace Discord.Rest | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | ||||
| } | } | ||||
| } | } | ||||
| #endregion | |||||
| //IVoiceState | |||||
| #region IVoiceState | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| bool IVoiceState.IsSelfDeafened => false; | bool IVoiceState.IsSelfDeafened => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -183,5 +186,6 @@ namespace Discord.Rest | |||||
| bool IVoiceState.IsStreaming => false; | bool IVoiceState.IsStreaming => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; | DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -13,6 +13,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestUser : RestEntity<ulong>, IUser, IUpdateable | public class RestUser : RestEntity<ulong>, IUser, IUpdateable | ||||
| { | { | ||||
| #region RestUser | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public bool IsBot { get; private set; } | public bool IsBot { get; private set; } | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -116,10 +117,12 @@ namespace Discord.Rest | |||||
| /// </returns> | /// </returns> | ||||
| public override string ToString() => $"{Username}#{Discriminator}"; | public override string ToString() => $"{Username}#{Discriminator}"; | ||||
| private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")})"; | private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")})"; | ||||
| #endregion | |||||
| //IUser | |||||
| #region IUser | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| async Task<IDMChannel> IUser.CreateDMChannelAsync(RequestOptions options) | async Task<IDMChannel> IUser.CreateDMChannelAsync(RequestOptions options) | ||||
| => await CreateDMChannelAsync(options).ConfigureAwait(false); | => await CreateDMChannelAsync(options).ConfigureAwait(false); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -10,6 +10,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestWebhookUser : RestUser, IWebhookUser | public class RestWebhookUser : RestUser, IWebhookUser | ||||
| { | { | ||||
| #region RestWebhookUser | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public ulong WebhookId { get; } | public ulong WebhookId { get; } | ||||
| internal IGuild Guild { get; } | internal IGuild Guild { get; } | ||||
| @@ -33,8 +34,9 @@ namespace Discord.Rest | |||||
| entity.Update(model); | entity.Update(model); | ||||
| return entity; | return entity; | ||||
| } | } | ||||
| #endregion | |||||
| //IGuildUser | |||||
| #region IGuildUser | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IGuild IGuildUser.Guild | IGuild IGuildUser.Guild | ||||
| { | { | ||||
| @@ -91,8 +93,9 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <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."); | throw new NotSupportedException("Roles are not supported on webhook users."); | ||||
| #endregion | |||||
| //IVoiceState | |||||
| #region IVoiceState | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| bool IVoiceState.IsDeafened => false; | bool IVoiceState.IsDeafened => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -111,5 +114,6 @@ namespace Discord.Rest | |||||
| bool IVoiceState.IsStreaming => false; | bool IVoiceState.IsStreaming => false; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; | DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -8,6 +8,7 @@ namespace Discord.Rest | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable | public class RestWebhook : RestEntity<ulong>, IWebhook, IUpdateable | ||||
| { | { | ||||
| #region RestWebhook | |||||
| internal IGuild Guild { get; private set; } | internal IGuild Guild { get; private set; } | ||||
| internal ITextChannel Channel { get; private set; } | internal ITextChannel Channel { get; private set; } | ||||
| @@ -95,8 +96,9 @@ namespace Discord.Rest | |||||
| public override string ToString() => $"Webhook: {Name}:{Id}"; | public override string ToString() => $"Webhook: {Name}:{Id}"; | ||||
| private string DebuggerDisplay => $"Webhook: {Name} ({Id})"; | private string DebuggerDisplay => $"Webhook: {Name} ({Id})"; | ||||
| #endregion | |||||
| //IWebhook | |||||
| #region IWebhook | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| IGuild IWebhook.Guild | IGuild IWebhook.Guild | ||||
| => Guild ?? throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | => Guild ?? throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | ||||
| @@ -106,5 +108,6 @@ namespace Discord.Rest | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| Task IWebhook.ModifyAsync(Action<WebhookProperties> func, RequestOptions options) | Task IWebhook.ModifyAsync(Action<WebhookProperties> func, RequestOptions options) | ||||
| => ModifyAsync(func, options); | => ModifyAsync(func, options); | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -10,6 +10,7 @@ namespace Discord.Net.Converters | |||||
| { | { | ||||
| internal class DiscordContractResolver : DefaultContractResolver | internal class DiscordContractResolver : DefaultContractResolver | ||||
| { | { | ||||
| #region DiscordContractResolver | |||||
| private static readonly TypeInfo _ienumerable = typeof(IEnumerable<ulong[]>).GetTypeInfo(); | private static readonly TypeInfo _ienumerable = typeof(IEnumerable<ulong[]>).GetTypeInfo(); | ||||
| private static readonly MethodInfo _shouldSerialize = typeof(DiscordContractResolver).GetTypeInfo().GetDeclaredMethod("ShouldSerialize"); | private static readonly MethodInfo _shouldSerialize = typeof(DiscordContractResolver).GetTypeInfo().GetDeclaredMethod("ShouldSerialize"); | ||||
| @@ -57,8 +58,9 @@ namespace Discord.Net.Converters | |||||
| else if (genericType == typeof(EntityOrId<>)) | else if (genericType == typeof(EntityOrId<>)) | ||||
| return MakeGenericConverter(property, propInfo, typeof(UInt64EntityOrIdConverter<>), type.GenericTypeArguments[0], depth); | return MakeGenericConverter(property, propInfo, typeof(UInt64EntityOrIdConverter<>), type.GenericTypeArguments[0], depth); | ||||
| } | } | ||||
| #endregion | |||||
| //Primitives | |||||
| #region Primitives | |||||
| bool hasInt53 = propInfo.GetCustomAttribute<Int53Attribute>() != null; | bool hasInt53 = propInfo.GetCustomAttribute<Int53Attribute>() != null; | ||||
| if (!hasInt53) | if (!hasInt53) | ||||
| { | { | ||||
| @@ -107,5 +109,6 @@ namespace Discord.Net.Converters | |||||
| var innerConverter = GetConverter(property, propInfo, innerType, depth + 1); | var innerConverter = GetConverter(property, propInfo, innerType, depth + 1); | ||||
| return genericType.DeclaredConstructors.First().Invoke(new object[] { innerConverter }) as JsonConverter; | return genericType.DeclaredConstructors.First().Invoke(new object[] { innerConverter }) as JsonConverter; | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||
| @@ -572,7 +572,7 @@ namespace Discord.WebSocket | |||||
| _emotes = emotes.ToImmutable(); | _emotes = emotes.ToImmutable(); | ||||
| } | } | ||||
| //General | |||||
| #region General | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task DeleteAsync(RequestOptions options = null) | public Task DeleteAsync(RequestOptions options = null) | ||||
| => GuildHelper.DeleteAsync(this, Discord, options); | => GuildHelper.DeleteAsync(this, Discord, options); | ||||
| @@ -596,8 +596,9 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task LeaveAsync(RequestOptions options = null) | public Task LeaveAsync(RequestOptions options = null) | ||||
| => GuildHelper.LeaveAsync(this, Discord, options); | => GuildHelper.LeaveAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Bans | |||||
| #region Bans | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all users banned in this guild. | /// Gets a collection of all users banned in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -645,8 +646,9 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task RemoveBanAsync(ulong userId, RequestOptions options = null) | public Task RemoveBanAsync(ulong userId, RequestOptions options = null) | ||||
| => GuildHelper.RemoveBanAsync(this, Discord, userId, options); | => GuildHelper.RemoveBanAsync(this, Discord, userId, options); | ||||
| #endregion | |||||
| //Channels | |||||
| #region Channels | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a channel in this guild. | /// Gets a channel in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -807,8 +809,9 @@ namespace Discord.WebSocket | |||||
| _channels.Clear(); | _channels.Clear(); | ||||
| } | } | ||||
| #endregion | |||||
| //Voice Regions | |||||
| #region Voice Regions | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all the voice regions this guild can access. | /// Gets a collection of all the voice regions this guild can access. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -819,14 +822,16 @@ namespace Discord.WebSocket | |||||
| /// </returns> | /// </returns> | ||||
| public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestVoiceRegion>> GetVoiceRegionsAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetVoiceRegionsAsync(this, Discord, options); | => GuildHelper.GetVoiceRegionsAsync(this, Discord, options); | ||||
| #endregion | |||||
| //Integrations | |||||
| #region Integrations | |||||
| public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null) | ||||
| => GuildHelper.GetIntegrationsAsync(this, Discord, options); | => GuildHelper.GetIntegrationsAsync(this, Discord, options); | ||||
| public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null) | ||||
| => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options); | ||||
| #endregion | |||||
| //Interactions | |||||
| #region Interactions | |||||
| /// <summary> | /// <summary> | ||||
| /// Deletes all application commands in the current guild. | /// Deletes all application commands in the current guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -932,8 +937,9 @@ namespace Discord.WebSocket | |||||
| return entities.ToImmutableArray(); | return entities.ToImmutableArray(); | ||||
| } | } | ||||
| #endregion | |||||
| //Invites | |||||
| #region Invites | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a collection of all invites in this guild. | /// Gets a collection of all invites in this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -1040,8 +1046,9 @@ namespace Discord.WebSocket | |||||
| return sticker; | return sticker; | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| //Users | |||||
| #region Users | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public Task<RestGuildUser> AddGuildUserAsync(ulong id, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null) | public Task<RestGuildUser> AddGuildUserAsync(ulong id, string accessToken, Action<AddGuildUserProperties> func = null, RequestOptions options = null) | ||||
| => GuildHelper.AddGuildUserAsync(this, Discord, id, accessToken, func, options); | => GuildHelper.AddGuildUserAsync(this, Discord, id, accessToken, func, options); | ||||
| @@ -1240,7 +1247,24 @@ namespace Discord.WebSocket | |||||
| public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) | public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null) | ||||
| => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); | => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options); | ||||
| //Stickers | |||||
| /// <summary> | |||||
| /// Moves the user to the voice channel. | |||||
| /// </summary> | |||||
| /// <param name="user">The user to move.</param> | |||||
| /// <param name="targetChannel">the channel where the user gets moved to.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for moving a user.</returns> | |||||
| public Task MoveAsync(IGuildUser user, IVoiceChannel targetChannel) | |||||
| => user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>(targetChannel)); | |||||
| /// <summary> | |||||
| /// Disconnects the user from its current voice channel | |||||
| /// </summary> | |||||
| /// <param name="user">The user to disconnect.</param> | |||||
| /// <returns>A task that represents the asynchronous operation for disconnecting a user.</returns> | |||||
| async Task IGuild.DisconnectAsync(IGuildUser user) => await user.ModifyAsync(x => x.Channel = new Optional<IVoiceChannel>()); | |||||
| #endregion | |||||
| #region Stickers | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets a specific sticker within this guild. | /// Gets a specific sticker within this guild. | ||||
| /// </summary> | /// </summary> | ||||
| @@ -1368,8 +1392,9 @@ namespace Discord.WebSocket | |||||
| /// </returns> | /// </returns> | ||||
| public Task DeleteStickerAsync(SocketCustomSticker sticker, RequestOptions options = null) | public Task DeleteStickerAsync(SocketCustomSticker sticker, RequestOptions options = null) | ||||
| => sticker.DeleteAsync(options); | => sticker.DeleteAsync(options); | ||||
| #endregion | |||||
| //Voice States | |||||
| #region Voice States | |||||
| internal async Task<SocketVoiceState> AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model) | internal async Task<SocketVoiceState> AddOrUpdateVoiceStateAsync(ClientState state, VoiceStateModel model) | ||||
| { | { | ||||
| var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel; | var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel; | ||||
| @@ -1413,8 +1438,9 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| #endregion | |||||
| //Audio | |||||
| #region Audio | |||||
| internal AudioInStream GetAudioStream(ulong userId) | internal AudioInStream GetAudioStream(ulong userId) | ||||
| { | { | ||||
| return _audioClient?.GetInputStream(userId); | return _audioClient?.GetInputStream(userId); | ||||
| @@ -1568,8 +1594,9 @@ namespace Discord.WebSocket | |||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| private string DebuggerDisplay => $"{Name} ({Id})"; | private string DebuggerDisplay => $"{Name} ({Id})"; | ||||
| internal SocketGuild Clone() => MemberwiseClone() as SocketGuild; | internal SocketGuild Clone() => MemberwiseClone() as SocketGuild; | ||||
| #endregion | |||||
| //IGuild | |||||
| #region IGuild | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| ulong? IGuild.AFKChannelId => AFKChannelId; | ulong? IGuild.AFKChannelId => AFKChannelId; | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -1781,7 +1808,6 @@ namespace Discord.WebSocket | |||||
| _audioLock?.Dispose(); | _audioLock?.Dispose(); | ||||
| _audioClient?.Dispose(); | _audioClient?.Dispose(); | ||||
| } | } | ||||
| #endregion | |||||
| } | } | ||||
| } | } | ||||