* RestGuildChannel regions * RestChannel * RestTextChannel * RestCategoryChannel * RestVoiceChannel * RestTextChannel * CommandService * ModuleBase * CommandBuilder * ModuleBuilder * ParameterBuilderpull/1923/head
@@ -7,6 +7,7 @@ namespace Discord.Commands.Builders | |||
{ | |||
public class CommandBuilder | |||
{ | |||
#region CommandBuilder | |||
private readonly List<PreconditionAttribute> _preconditions; | |||
private readonly List<ParameterBuilder> _parameters; | |||
private readonly List<Attribute> _attributes; | |||
@@ -27,8 +28,9 @@ namespace Discord.Commands.Builders | |||
public IReadOnlyList<ParameterBuilder> Parameters => _parameters; | |||
public IReadOnlyList<Attribute> Attributes => _attributes; | |||
public IReadOnlyList<string> Aliases => _aliases; | |||
#endregion | |||
//Automatic | |||
#region Automatic | |||
internal CommandBuilder(ModuleBuilder module) | |||
{ | |||
Module = module; | |||
@@ -38,7 +40,9 @@ namespace Discord.Commands.Builders | |||
_attributes = new List<Attribute>(); | |||
_aliases = new List<string>(); | |||
} | |||
//User-defined | |||
#endregion | |||
#region User-defined | |||
internal CommandBuilder(ModuleBuilder module, string primaryAlias, Func<ICommandContext, object[], IServiceProvider, CommandInfo, Task> callback) | |||
: this(module) | |||
{ | |||
@@ -132,7 +136,7 @@ namespace Discord.Commands.Builders | |||
var firstMultipleParam = _parameters.FirstOrDefault(x => x.IsMultiple); | |||
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}"); | |||
var firstRemainderParam = _parameters.FirstOrDefault(x => x.IsRemainder); | |||
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}"); | |||
@@ -140,5 +144,6 @@ namespace Discord.Commands.Builders | |||
return new CommandInfo(this, info, service); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -7,6 +7,7 @@ namespace Discord.Commands.Builders | |||
{ | |||
public class ModuleBuilder | |||
{ | |||
#region ModuleBuilder | |||
private readonly List<CommandBuilder> _commands; | |||
private readonly List<ModuleBuilder> _submodules; | |||
private readonly List<PreconditionAttribute> _preconditions; | |||
@@ -27,8 +28,9 @@ namespace Discord.Commands.Builders | |||
public IReadOnlyList<string> Aliases => _aliases; | |||
internal TypeInfo TypeInfo { get; set; } | |||
#endregion | |||
//Automatic | |||
#region Automatic | |||
internal ModuleBuilder(CommandService service, ModuleBuilder parent) | |||
{ | |||
Service = service; | |||
@@ -40,7 +42,9 @@ namespace Discord.Commands.Builders | |||
_attributes = new List<Attribute>(); | |||
_aliases = new List<string>(); | |||
} | |||
//User-defined | |||
#endregion | |||
#region User-defined | |||
internal ModuleBuilder(CommandService service, ModuleBuilder parent, string primaryAlias) | |||
: this(service, parent) | |||
{ | |||
@@ -132,5 +136,6 @@ namespace Discord.Commands.Builders | |||
public ModuleInfo Build(CommandService service, IServiceProvider services) => BuildImpl(service, services); | |||
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 | |||
{ | |||
#region ParameterBuilder | |||
private readonly List<ParameterPreconditionAttribute> _preconditions; | |||
private readonly List<Attribute> _attributes; | |||
@@ -24,8 +25,9 @@ namespace Discord.Commands.Builders | |||
public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions; | |||
public IReadOnlyList<Attribute> Attributes => _attributes; | |||
#endregion | |||
//Automatic | |||
#region Automatic | |||
internal ParameterBuilder(CommandBuilder command) | |||
{ | |||
_preconditions = new List<ParameterPreconditionAttribute>(); | |||
@@ -33,7 +35,9 @@ namespace Discord.Commands.Builders | |||
Command = command; | |||
} | |||
//User-defined | |||
#endregion | |||
#region User-defined | |||
internal ParameterBuilder(CommandBuilder command, string name, Type type) | |||
: this(command) | |||
{ | |||
@@ -132,5 +136,6 @@ namespace Discord.Commands.Builders | |||
return new ParameterInfo(this, info, Command.Module.Service); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -29,6 +29,7 @@ namespace Discord.Commands | |||
/// </remarks> | |||
public class CommandService : IDisposable | |||
{ | |||
#region CommandService | |||
/// <summary> | |||
/// Occurs when a command-related information is received. | |||
/// </summary> | |||
@@ -131,8 +132,9 @@ namespace Discord.Commands | |||
entityTypeReaders.Add((typeof(IUser), typeof(UserTypeReader<>))); | |||
_entityTypeReaders = entityTypeReaders.ToImmutable(); | |||
} | |||
#endregion | |||
//Modules | |||
#region Modules | |||
public async Task<ModuleInfo> CreateModuleAsync(string primaryAlias, Action<ModuleBuilder> buildFunc) | |||
{ | |||
await _moduleLock.WaitAsync().ConfigureAwait(false); | |||
@@ -322,8 +324,9 @@ namespace Discord.Commands | |||
return true; | |||
} | |||
#endregion | |||
//Type Readers | |||
#region Type Readers | |||
/// <summary> | |||
/// Adds a custom <see cref="TypeReader" /> to this <see cref="CommandService" /> for the supplied object | |||
/// type. | |||
@@ -448,8 +451,9 @@ namespace Discord.Commands | |||
} | |||
return null; | |||
} | |||
#endregion | |||
//Execution | |||
#region Execution | |||
/// <summary> | |||
/// Searches for the command. | |||
/// </summary> | |||
@@ -602,7 +606,9 @@ namespace Discord.Commands | |||
await _commandExecutedEvent.InvokeAsync(chosenOverload.Key.Command, context, result); | |||
return result; | |||
} | |||
#endregion | |||
#region Dispose | |||
protected virtual void Dispose(bool disposing) | |||
{ | |||
if (!_isDisposed) | |||
@@ -620,5 +626,6 @@ namespace Discord.Commands | |||
{ | |||
Dispose(true); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -16,6 +16,7 @@ namespace Discord.Commands | |||
public abstract class ModuleBase<T> : IModuleBase | |||
where T : class, ICommandContext | |||
{ | |||
#region ModuleBase | |||
/// <summary> | |||
/// The underlying context of the command. | |||
/// </summary> | |||
@@ -65,8 +66,9 @@ namespace Discord.Commands | |||
protected virtual void OnModuleBuilding(CommandService commandService, ModuleBuilder builder) | |||
{ | |||
} | |||
#endregion | |||
//IModuleBase | |||
#region IModuleBase | |||
void IModuleBase.SetContext(ICommandContext context) | |||
{ | |||
var newValue = context as T; | |||
@@ -75,5 +77,6 @@ namespace Discord.Commands | |||
void IModuleBase.BeforeExecute(CommandInfo command) => BeforeExecute(command); | |||
void IModuleBase.AfterExecute(CommandInfo command) => AfterExecute(command); | |||
void IModuleBase.OnModuleBuilding(CommandService commandService, ModuleBuilder builder) => OnModuleBuilding(commandService, builder); | |||
#endregion | |||
} | |||
} |
@@ -12,6 +12,7 @@ namespace Discord.Rest | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestCategoryChannel : RestGuildChannel, ICategoryChannel | |||
{ | |||
#region RestCategoryChannel | |||
internal RestCategoryChannel(BaseDiscordClient discord, IGuild guild, ulong id) | |||
: base(discord, guild, id) | |||
{ | |||
@@ -24,8 +25,9 @@ namespace Discord.Rest | |||
} | |||
private string DebuggerDisplay => $"{Name} ({Id}, Category)"; | |||
#endregion | |||
//IChannel | |||
#region IChannel | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">This method is not supported with category channels.</exception> | |||
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> | |||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> throw new NotSupportedException(); | |||
#endregion | |||
} | |||
} |
@@ -11,6 +11,7 @@ namespace Discord.Rest | |||
/// </summary> | |||
public class RestChannel : RestEntity<ulong>, IChannel, IUpdateable | |||
{ | |||
#region RestChannel | |||
/// <inheritdoc /> | |||
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); | |||
@@ -53,8 +54,9 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
public virtual Task UpdateAsync(RequestOptions options = null) => Task.Delay(0); | |||
#endregion | |||
//IChannel | |||
#region IChannel | |||
/// <inheritdoc /> | |||
string IChannel.Name => null; | |||
@@ -64,5 +66,6 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden | |||
#endregion | |||
} | |||
} |
@@ -12,6 +12,7 @@ namespace Discord.Rest | |||
/// </summary> | |||
public class RestGuildChannel : RestChannel, IGuildChannel | |||
{ | |||
#region RestGuildChannel | |||
private ImmutableArray<Overwrite> _overwrites; | |||
/// <inheritdoc /> | |||
@@ -191,8 +192,9 @@ namespace Discord.Rest | |||
/// A string that is the name of this channel. | |||
/// </returns> | |||
public override string ToString() => Name; | |||
#endregion | |||
//IGuildChannel | |||
#region IGuildChannel | |||
/// <inheritdoc /> | |||
IGuild IGuildChannel.Guild | |||
{ | |||
@@ -229,13 +231,15 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> Task.FromResult<IGuildUser>(null); //Overridden in Text/Voice | |||
#endregion | |||
//IChannel | |||
#region IChannel | |||
/// <inheritdoc /> | |||
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden in Text/Voice | |||
/// <inheritdoc /> | |||
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> Task.FromResult<IUser>(null); //Overridden in Text/Voice | |||
#endregion | |||
} | |||
} |
@@ -14,6 +14,7 @@ namespace Discord.Rest | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestTextChannel : RestGuildChannel, IRestMessageChannel, ITextChannel | |||
{ | |||
#region RestTextChannel | |||
/// <inheritdoc /> | |||
public string Topic { get; private set; } | |||
/// <inheritdoc /> | |||
@@ -210,8 +211,9 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
public Task SyncPermissionsAsync(RequestOptions options = null) | |||
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options); | |||
#endregion | |||
//Invites | |||
#region Invites | |||
/// <inheritdoc /> | |||
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); | |||
@@ -261,8 +263,9 @@ namespace Discord.Rest | |||
var model = await ThreadHelper.CreateThreadAsync(Discord, this, name, type, autoArchiveDuration, message, options); | |||
return RestThreadChannel.Create(Discord, this.Guild, model); | |||
} | |||
#endregion | |||
//ITextChannel | |||
#region ITextChannel | |||
/// <inheritdoc /> | |||
async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options) | |||
=> 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) | |||
=> await CreateThreadAsync(name, type, autoArchiveDuration, message, options); | |||
#endregion | |||
//IMessageChannel | |||
#region IMessageChannel | |||
/// <inheritdoc /> | |||
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
@@ -324,8 +328,9 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
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); | |||
#endregion | |||
//IGuildChannel | |||
#region IGuildChannel | |||
/// <inheritdoc /> | |||
async Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
@@ -342,8 +347,9 @@ namespace Discord.Rest | |||
else | |||
return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
} | |||
#endregion | |||
//IChannel | |||
#region IChannel | |||
/// <inheritdoc /> | |||
async Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
{ | |||
@@ -360,8 +366,9 @@ namespace Discord.Rest | |||
else | |||
return AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
} | |||
#endregion | |||
// INestedChannel | |||
#region ITextChannel | |||
/// <inheritdoc /> | |||
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 null; | |||
} | |||
#endregion | |||
} | |||
} |
@@ -14,6 +14,7 @@ namespace Discord.Rest | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestVoiceChannel : RestGuildChannel, IVoiceChannel, IRestAudioChannel | |||
{ | |||
#region RestVoiceChannel | |||
/// <inheritdoc /> | |||
public int Bitrate { get; private set; } | |||
/// <inheritdoc /> | |||
@@ -60,8 +61,9 @@ namespace Discord.Rest | |||
/// <inheritdoc /> | |||
public Task SyncPermissionsAsync(RequestOptions options = null) | |||
=> ChannelHelper.SyncPermissionsAsync(this, Discord, options); | |||
#endregion | |||
//Invites | |||
#region Invites | |||
/// <inheritdoc /> | |||
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); | |||
@@ -76,22 +78,25 @@ namespace Discord.Rest | |||
=> await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); | |||
private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; | |||
#endregion | |||
//IAudioChannel | |||
#region IAudioChannel | |||
/// <inheritdoc /> | |||
/// <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 IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); } | |||
#endregion | |||
//IGuildChannel | |||
#region IGuildChannel | |||
/// <inheritdoc /> | |||
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) | |||
=> Task.FromResult<IGuildUser>(null); | |||
/// <inheritdoc /> | |||
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) | |||
=> AsyncEnumerable.Empty<IReadOnlyCollection<IGuildUser>>(); | |||
#endregion | |||
// INestedChannel | |||
#region INestedChannel | |||
/// <inheritdoc /> | |||
async Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) | |||
{ | |||
@@ -99,5 +104,6 @@ namespace Discord.Rest | |||
return (await Guild.GetChannelAsync(CategoryId.Value, mode, options).ConfigureAwait(false)) as ICategoryChannel; | |||
return null; | |||
} | |||
#endregion | |||
} | |||
} |