Browse Source

Merge remote-tracking branch 'origin/docs/faq-n-patches' into docs/faq-n-patches

pull/988/head
Hsu Still 7 years ago
parent
commit
b141619737
25 changed files with 87 additions and 80 deletions
  1. +2
    -2
      docs/faq/commands/Commands.md
  2. +1
    -1
      src/Discord.Net.Commands/Attributes/OverrideTypeReaderAttribute.cs
  3. +1
    -1
      src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs
  4. +3
    -3
      src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs
  5. +0
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
  6. +1
    -1
      src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs
  7. +1
    -0
      src/Discord.Net.Commands/CommandError.cs
  8. +2
    -2
      src/Discord.Net.Commands/CommandParser.cs
  9. +30
    -18
      src/Discord.Net.Commands/CommandService.cs
  10. +2
    -2
      src/Discord.Net.Commands/Info/CommandInfo.cs
  11. +3
    -1
      src/Discord.Net.Commands/Info/ParameterInfo.cs
  12. +1
    -1
      src/Discord.Net.Commands/ModuleBase.cs
  13. +3
    -3
      src/Discord.Net.Commands/Readers/EnumTypeReader.cs
  14. +3
    -3
      src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs
  15. +2
    -4
      src/Discord.Net.Commands/Readers/RoleTypeReader.cs
  16. +2
    -3
      src/Discord.Net.Commands/Readers/UserTypeReader.cs
  17. +3
    -3
      src/Discord.Net.Commands/Results/PreconditionGroupResult.cs
  18. +0
    -3
      src/Discord.Net.Commands/Results/RuntimeResult.cs
  19. +6
    -7
      src/Discord.Net.Commands/Utilities/ReflectionUtils.cs
  20. +1
    -1
      src/Discord.Net.Core/CDN.cs
  21. +3
    -3
      src/Discord.Net.Core/DiscordConfig.cs
  22. +9
    -9
      src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs
  23. +1
    -1
      src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs
  24. +1
    -1
      src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs
  25. +6
    -6
      src/Discord.Net.Core/Entities/Roles/Color.cs

+ 2
- 2
docs/faq/commands/Commands.md View File

@@ -56,8 +56,8 @@ Service is often used to hold data externally, so that they will
persist throughout execution. Think of it like a chest that holds persist throughout execution. Think of it like a chest that holds
whatever you throw at it that won't be affected by anything unless whatever you throw at it that won't be affected by anything unless
you want it to. Note that you should also learn Microsoft's you want it to. Note that you should also learn Microsoft's
implementation of [Dependency Injection] \([video]) before proceeding, as well
as how it works in [Discord.Net](xref:Guides.Commands.DI#usage-in-modules).
implementation of [Dependency Injection] \([video]) before proceeding,
as well as how it works in [Discord.Net](xref:Guides.Commands.DI#usage-in-modules).


A brief example of service and dependency injection can be seen below. A brief example of service and dependency injection can be seen below.




+ 1
- 1
src/Discord.Net.Commands/Attributes/OverrideTypeReaderAttribute.cs View File

@@ -18,7 +18,7 @@ namespace Discord.Commands
public OverrideTypeReaderAttribute(Type overridenTypeReader) public OverrideTypeReaderAttribute(Type overridenTypeReader)
{ {
if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo()))
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}");
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}.");
TypeReader = overridenTypeReader; TypeReader = overridenTypeReader;
} }


+ 1
- 1
src/Discord.Net.Commands/Attributes/PreconditionAttribute.cs View File

@@ -9,7 +9,7 @@ namespace Discord.Commands
{ {
/// <summary> Specify a group that this precondition belongs to. </summary> /// <summary> Specify a group that this precondition belongs to. </summary>
/// <remarks> /// <remarks>
/// Preconditions of the same group require only one
/// <see cref="Preconditions"/> of the same group require only one
/// of the preconditions to pass in order to be successful (A || B). /// of the preconditions to pass in order to be successful (A || B).
/// Specifying <see cref="Group"/> = <see langword="null"/> /// Specifying <see cref="Group"/> = <see langword="null"/>
/// or not at all will require *all* preconditions to pass, just like normal (A &amp;&amp; B). /// or not at all will require *all* preconditions to pass, just like normal (A &amp;&amp; B).


+ 3
- 3
src/Discord.Net.Commands/Attributes/Preconditions/RequireBotPermissionAttribute.cs View File

@@ -50,9 +50,9 @@ namespace Discord.Commands
if (GuildPermission.HasValue) if (GuildPermission.HasValue)
{ {
if (guildUser == null) if (guildUser == null)
return PreconditionResult.FromError("Command must be used in a guild channel");
return PreconditionResult.FromError("Command must be used in a guild channel.");
if (!guildUser.GuildPermissions.Has(GuildPermission.Value)) if (!guildUser.GuildPermissions.Has(GuildPermission.Value))
return PreconditionResult.FromError($"Bot requires guild permission {GuildPermission.Value}");
return PreconditionResult.FromError($"Bot requires guild permission {GuildPermission.Value}.");
} }


if (ChannelPermission.HasValue) if (ChannelPermission.HasValue)
@@ -64,7 +64,7 @@ namespace Discord.Commands
perms = ChannelPermissions.All(context.Channel); perms = ChannelPermissions.All(context.Channel);


if (!perms.Has(ChannelPermission.Value)) if (!perms.Has(ChannelPermission.Value))
return PreconditionResult.FromError($"Bot requires channel permission {ChannelPermission.Value}");
return PreconditionResult.FromError($"Bot requires channel permission {ChannelPermission.Value}.");
} }


return PreconditionResult.FromSuccess(); return PreconditionResult.FromSuccess();


+ 0
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;


namespace Discord.Commands namespace Discord.Commands
{ {


+ 1
- 1
src/Discord.Net.Commands/Attributes/Preconditions/RequireOwnerAttribute.cs View File

@@ -17,7 +17,7 @@ namespace Discord.Commands
case TokenType.Bot: case TokenType.Bot:
var application = await context.Client.GetApplicationInfoAsync(); var application = await context.Client.GetApplicationInfoAsync();
if (context.User.Id != application.Owner.Id) if (context.User.Id != application.Owner.Id)
return PreconditionResult.FromError("Command can only be run by the owner of the bot");
return PreconditionResult.FromError("Command can only be run by the owner of the bot.");
return PreconditionResult.FromSuccess(); return PreconditionResult.FromSuccess();
default: default:
return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}."); return PreconditionResult.FromError($"{nameof(RequireOwnerAttribute)} is not supported by this {nameof(TokenType)}.");


+ 1
- 0
src/Discord.Net.Commands/CommandError.cs View File

@@ -1,5 +1,6 @@
namespace Discord.Commands namespace Discord.Commands
{ {
/// <summary> The type of error the command throws. </summary>
public enum CommandError public enum CommandError
{ {
//Search //Search


+ 2
- 2
src/Discord.Net.Commands/CommandParser.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -148,7 +148,7 @@ namespace Discord.Commands
if (isEscaping) if (isEscaping)
return ParseResult.FromError(CommandError.ParseFailed, "Input text may not end on an incomplete escape."); return ParseResult.FromError(CommandError.ParseFailed, "Input text may not end on an incomplete escape.");
if (curPart == ParserPart.QuotedParameter) if (curPart == ParserPart.QuotedParameter)
return ParseResult.FromError(CommandError.ParseFailed, "A quoted parameter is incomplete");
return ParseResult.FromError(CommandError.ParseFailed, "A quoted parameter is incomplete.");
//Add missing optionals //Add missing optionals
for (int i = argList.Count; i < command.Parameters.Count; i++) for (int i = argList.Count; i < command.Parameters.Count; i++)


+ 30
- 18
src/Discord.Net.Commands/CommandService.cs View File

@@ -111,11 +111,11 @@ namespace Discord.Commands
} }


/// <summary> /// <summary>
/// Add a command module from a type
/// Add a command module from a <see cref="Type"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The type of module</typeparam>
/// <param name="services">An IServiceProvider for your dependency injection solution, if using one - otherwise, pass null</param>
/// <returns>A built module</returns>
/// <typeparam name="T">The type of module.</typeparam>
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>. </param>
/// <returns>A built module.</returns>
public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services); public Task<ModuleInfo> AddModuleAsync<T>(IServiceProvider services) => AddModuleAsync(typeof(T), services);
public async Task<ModuleInfo> AddModuleAsync(Type type, IServiceProvider services) public async Task<ModuleInfo> AddModuleAsync(Type type, IServiceProvider services)
{ {
@@ -127,7 +127,7 @@ namespace Discord.Commands
var typeInfo = type.GetTypeInfo(); var typeInfo = type.GetTypeInfo();


if (_typedModuleDefs.ContainsKey(type)) if (_typedModuleDefs.ContainsKey(type))
throw new ArgumentException($"This module has already been added.");
throw new ArgumentException("This module has already been added.");


var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault(); var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault();


@@ -144,11 +144,11 @@ namespace Discord.Commands
} }
} }
/// <summary> /// <summary>
/// Add command modules from an assembly
/// Add command modules from an <see cref="Assembly"/>.
/// </summary> /// </summary>
/// <param name="assembly">The assembly containing command modules</param>
/// <param name="services">An IServiceProvider for your dependency injection solution, if using one - otherwise, pass null</param>
/// <returns>A collection of built modules</returns>
/// <param name="assembly">The <see cref="Assembly"/> containing command modules.</param>
/// <param name="services">An <see cref="IServiceProvider"/> for your dependency injection solution, if using one - otherwise, pass <see langword="null"/>.</param>
/// <returns>A collection of built modules.</returns>
public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly, IServiceProvider services) public async Task<IEnumerable<ModuleInfo>> AddModulesAsync(Assembly assembly, IServiceProvider services)
{ {
services = services ?? EmptyServiceProvider.Instance; services = services ?? EmptyServiceProvider.Instance;
@@ -231,18 +231,26 @@ namespace Discord.Commands


//Type Readers //Type Readers
/// <summary> /// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// If a default <see cref="TypeReader"/> exists for <typeparamref name="T"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// <para>
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// </para>
/// <para>
/// If a default <see cref="TypeReader"/> exists for <typeparamref name="T"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// </para>
/// </summary> /// </summary>
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam> /// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> /// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
public void AddTypeReader<T>(TypeReader reader) public void AddTypeReader<T>(TypeReader reader)
=> AddTypeReader(typeof(T), reader); => AddTypeReader(typeof(T), reader);
/// <summary> /// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// If a default <see cref="TypeReader"/> exists for <paramref name="type"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// <para>
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// </para>
/// <para>
/// If a default <see cref="TypeReader"/> exists for <paramref name="type"/>, a warning will be logged and the default <see cref="TypeReader"/> will be replaced.
/// </para>
/// </summary> /// </summary>
/// <param name="type">A <see cref="Type"/> instance for the type to be read.</param> /// <param name="type">A <see cref="Type"/> instance for the type to be read.</param>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> /// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
@@ -250,12 +258,14 @@ namespace Discord.Commands
{ {
if (_defaultTypeReaders.ContainsKey(type)) if (_defaultTypeReaders.ContainsKey(type))
_ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." + _ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." +
$"To suppress this message, use AddTypeReader<T>(reader, true).");
"To suppress this message, use AddTypeReader<T>(reader, true).");
AddTypeReader(type, reader, true); AddTypeReader(type, reader, true);
} }
/// <summary> /// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. /// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// <para>
/// If <typeparamref name="T"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> will also be added.
/// </para>
/// </summary> /// </summary>
/// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam> /// <typeparam name="T">The object type to be read by the <see cref="TypeReader"/>.</typeparam>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> /// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>
@@ -264,7 +274,9 @@ namespace Discord.Commands
=> AddTypeReader(typeof(T), reader, replaceDefault); => AddTypeReader(typeof(T), reader, replaceDefault);
/// <summary> /// <summary>
/// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type. /// Adds a custom <see cref="TypeReader"/> to this <see cref="CommandService"/> for the supplied object type.
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// <para>
/// If <paramref name="type"/> is a <see cref="ValueType"/>, a <see cref="NullableTypeReader{T}"/> for the value type will also be added.
/// </para>
/// </summary> /// </summary>
/// <param name="type">A <see cref="Type"/> instance for the type to be read.</param> /// <param name="type">A <see cref="Type"/> instance for the type to be read.</param>
/// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param> /// <param name="reader">An instance of the <see cref="TypeReader"/> to be added.</param>


+ 2
- 2
src/Discord.Net.Commands/Info/CommandInfo.cs View File

@@ -271,11 +271,11 @@ namespace Discord.Commands
foreach (object arg in argList) foreach (object arg in argList)
{ {
if (i == argCount) if (i == argCount)
throw new InvalidOperationException("Command was invoked with too many parameters");
throw new InvalidOperationException("Command was invoked with too many parameters.");
array[i++] = arg; array[i++] = arg;
} }
if (i < argCount) if (i < argCount)
throw new InvalidOperationException("Command was invoked with too few parameters");
throw new InvalidOperationException("Command was invoked with too few parameters.");


if (HasVarArgs) if (HasVarArgs)
{ {


+ 3
- 1
src/Discord.Net.Commands/Info/ParameterInfo.cs View File

@@ -2,11 +2,13 @@ using Discord.Commands.Builders;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;


namespace Discord.Commands namespace Discord.Commands
{ {
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class ParameterInfo public class ParameterInfo
{ {
private readonly TypeReader _reader; private readonly TypeReader _reader;
@@ -65,4 +67,4 @@ namespace Discord.Commands
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}"; private string DebuggerDisplay => $"{Name}{(IsOptional ? " (Optional)" : "")}{(IsRemainder ? " (Remainder)" : "")}";
} }
}
}

+ 1
- 1
src/Discord.Net.Commands/ModuleBase.cs View File

@@ -43,7 +43,7 @@ namespace Discord.Commands
void IModuleBase.SetContext(ICommandContext context) void IModuleBase.SetContext(ICommandContext context)
{ {
var newValue = context as T; var newValue = context as T;
Context = newValue ?? throw new InvalidOperationException($"Invalid context type. Expected {typeof(T).Name}, got {context.GetType().Name}");
Context = newValue ?? throw new InvalidOperationException($"Invalid context type. Expected {typeof(T).Name}, got {context.GetType().Name}.");
} }
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);


+ 3
- 3
src/Discord.Net.Commands/Readers/EnumTypeReader.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
@@ -53,14 +53,14 @@ namespace Discord.Commands
if (_enumsByValue.TryGetValue(baseValue, out enumValue)) if (_enumsByValue.TryGetValue(baseValue, out enumValue))
return Task.FromResult(TypeReaderResult.FromSuccess(enumValue)); return Task.FromResult(TypeReaderResult.FromSuccess(enumValue));
else else
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Value is not a {_enumType.Name}"));
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Value is not a {_enumType.Name}."));
} }
else else
{ {
if (_enumsByName.TryGetValue(input.ToLower(), out enumValue)) if (_enumsByName.TryGetValue(input.ToLower(), out enumValue))
return Task.FromResult(TypeReaderResult.FromSuccess(enumValue)); return Task.FromResult(TypeReaderResult.FromSuccess(enumValue));
else else
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Value is not a {_enumType.Name}"));
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Value is not a {_enumType.Name}."));
} }
} }
} }


+ 3
- 3
src/Discord.Net.Commands/Readers/PrimitiveTypeReader.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace Discord.Commands namespace Discord.Commands
@@ -24,7 +24,7 @@ namespace Discord.Commands
public PrimitiveTypeReader(TryParseDelegate<T> tryParse, float score) public PrimitiveTypeReader(TryParseDelegate<T> tryParse, float score)
{ {
if (score < 0 || score > 1) if (score < 0 || score > 1)
throw new ArgumentOutOfRangeException(nameof(score), score, "Scores must be within the range [0, 1]");
throw new ArgumentOutOfRangeException(nameof(score), score, "Scores must be within the range [0, 1].");


_tryParse = tryParse; _tryParse = tryParse;
_score = score; _score = score;
@@ -34,7 +34,7 @@ namespace Discord.Commands
{ {
if (_tryParse(input, out T value)) if (_tryParse(input, out T value))
return Task.FromResult(TypeReaderResult.FromSuccess(new TypeReaderValue(value, _score))); return Task.FromResult(TypeReaderResult.FromSuccess(new TypeReaderValue(value, _score)));
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Failed to parse {typeof(T).Name}"));
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, $"Failed to parse {typeof(T).Name}."));
} }
} }
} }

+ 2
- 4
src/Discord.Net.Commands/Readers/RoleTypeReader.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
@@ -11,15 +11,13 @@ namespace Discord.Commands
{ {
public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services) public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services)
{ {
ulong id;

if (context.Guild != null) if (context.Guild != null)
{ {
var results = new Dictionary<ulong, TypeReaderValue>(); var results = new Dictionary<ulong, TypeReaderValue>();
var roles = context.Guild.Roles; var roles = context.Guild.Roles;


//By Mention (1.0) //By Mention (1.0)
if (MentionUtils.TryParseRole(input, out id))
if (MentionUtils.TryParseRole(input, out var id))
AddResult(results, context.Guild.GetRole(id) as T, 1.00f); AddResult(results, context.Guild.GetRole(id) as T, 1.00f);


//By Id (0.9) //By Id (0.9)


+ 2
- 3
src/Discord.Net.Commands/Readers/UserTypeReader.cs View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Globalization; using System.Globalization;
@@ -15,13 +15,12 @@ namespace Discord.Commands
var results = new Dictionary<ulong, TypeReaderValue>(); var results = new Dictionary<ulong, TypeReaderValue>();
IAsyncEnumerable<IUser> channelUsers = context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten(); // it's better IAsyncEnumerable<IUser> channelUsers = context.Channel.GetUsersAsync(CacheMode.CacheOnly).Flatten(); // it's better
IReadOnlyCollection<IGuildUser> guildUsers = ImmutableArray.Create<IGuildUser>(); IReadOnlyCollection<IGuildUser> guildUsers = ImmutableArray.Create<IGuildUser>();
ulong id;


if (context.Guild != null) if (context.Guild != null)
guildUsers = await context.Guild.GetUsersAsync(CacheMode.CacheOnly).ConfigureAwait(false); guildUsers = await context.Guild.GetUsersAsync(CacheMode.CacheOnly).ConfigureAwait(false);


//By Mention (1.0) //By Mention (1.0)
if (MentionUtils.TryParseUser(input, out id))
if (MentionUtils.TryParseUser(input, out var id))
{ {
if (context.Guild != null) if (context.Guild != null)
AddResult(results, await context.Guild.GetUserAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) as T, 1.00f); AddResult(results, await context.Guild.GetUserAsync(id, CacheMode.CacheOnly).ConfigureAwait(false) as T, 1.00f);


+ 3
- 3
src/Discord.Net.Commands/Results/PreconditionGroupResult.cs View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;


namespace Discord.Commands namespace Discord.Commands
@@ -14,11 +14,11 @@ namespace Discord.Commands
PreconditionResults = (preconditions ?? new List<PreconditionResult>(0)).ToReadOnlyCollection(); PreconditionResults = (preconditions ?? new List<PreconditionResult>(0)).ToReadOnlyCollection();
} }


public static new PreconditionGroupResult FromSuccess()
public new static PreconditionGroupResult FromSuccess()
=> new PreconditionGroupResult(null, null, null); => new PreconditionGroupResult(null, null, null);
public static PreconditionGroupResult FromError(string reason, ICollection<PreconditionResult> preconditions) public static PreconditionGroupResult FromError(string reason, ICollection<PreconditionResult> preconditions)
=> new PreconditionGroupResult(CommandError.UnmetPrecondition, reason, preconditions); => new PreconditionGroupResult(CommandError.UnmetPrecondition, reason, preconditions);
public static new PreconditionGroupResult FromError(IResult result) //needed?
public new static PreconditionGroupResult FromError(IResult result) //needed?
=> new PreconditionGroupResult(result.Error, result.ErrorReason, null); => new PreconditionGroupResult(result.Error, result.ErrorReason, null);


public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}"; public override string ToString() => IsSuccess ? "Success" : $"{Error}: {ErrorReason}";


+ 0
- 3
src/Discord.Net.Commands/Results/RuntimeResult.cs View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Text;


namespace Discord.Commands namespace Discord.Commands
{ {


+ 6
- 7
src/Discord.Net.Commands/Utilities/ReflectionUtils.cs View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.Extensions.DependencyInjection;


namespace Discord.Commands namespace Discord.Commands
{ {
@@ -38,7 +37,7 @@ namespace Discord.Commands
} }
catch (Exception ex) catch (Exception ex)
{ {
throw new Exception($"Failed to create \"{ownerType.FullName}\"", ex);
throw new Exception($"Failed to create \"{ownerType.FullName}\".", ex);
} }
} }


@@ -46,14 +45,14 @@ namespace Discord.Commands
{ {
var constructors = ownerType.DeclaredConstructors.Where(x => !x.IsStatic).ToArray(); var constructors = ownerType.DeclaredConstructors.Where(x => !x.IsStatic).ToArray();
if (constructors.Length == 0) if (constructors.Length == 0)
throw new InvalidOperationException($"No constructor found for \"{ownerType.FullName}\"");
throw new InvalidOperationException($"No constructor found for \"{ownerType.FullName}\".");
else if (constructors.Length > 1) else if (constructors.Length > 1)
throw new InvalidOperationException($"Multiple constructors found for \"{ownerType.FullName}\"");
throw new InvalidOperationException($"Multiple constructors found for \"{ownerType.FullName}\".");
return constructors[0]; return constructors[0];
} }
private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType)
private static PropertyInfo[] GetProperties(TypeInfo ownerType)
{ {
var result = new List<System.Reflection.PropertyInfo>();
var result = new List<PropertyInfo>();
while (ownerType != _objectTypeInfo) while (ownerType != _objectTypeInfo)
{ {
foreach (var prop in ownerType.DeclaredProperties) foreach (var prop in ownerType.DeclaredProperties)
@@ -71,7 +70,7 @@ namespace Discord.Commands
return commands; return commands;
if (memberType == typeof(IServiceProvider) || memberType == services.GetType()) if (memberType == typeof(IServiceProvider) || memberType == services.GetType())
return services; return services;
var service = services?.GetService(memberType);
var service = services.GetService(memberType);
if (service != null) if (service != null)
return service; return service;
throw new InvalidOperationException($"Failed to create \"{ownerType.FullName}\", dependency \"{memberType.Name}\" was not found."); throw new InvalidOperationException($"Failed to create \"{ownerType.FullName}\", dependency \"{memberType.Name}\" was not found.");


+ 1
- 1
src/Discord.Net.Core/CDN.cs View File

@@ -2,7 +2,7 @@ using System;


namespace Discord namespace Discord
{ {
/// <summary> Contains the strings related to various Content Delievery Networks (CDNs). </summary>
/// <summary> A class containing the strings related to various Content Delivery Networks (CDNs). </summary>
public static class CDN public static class CDN
{ {
/// <summary> Returns the Discord developer application icon. </summary> /// <summary> Returns the Discord developer application icon. </summary>


+ 3
- 3
src/Discord.Net.Core/DiscordConfig.cs View File

@@ -4,15 +4,15 @@ namespace Discord
{ {
public class DiscordConfig public class DiscordConfig
{ {
/// <summary> Returns the gateway version Discord.NET uses. </summary>
/// <summary> Returns the gateway version Discord.Net uses. </summary>
public const int APIVersion = 6; public const int APIVersion = 6;
/// <summary> Returns the Discord.NET verion, including the build number. </summary>
/// <summary> Returns the Discord.Net version, including the build number. </summary>
public static string Version { get; } = public static string Version { get; } =
typeof(DiscordConfig).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? typeof(DiscordConfig).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ??
typeof(DiscordConfig).GetTypeInfo().Assembly.GetName().Version.ToString(3) ?? typeof(DiscordConfig).GetTypeInfo().Assembly.GetName().Version.ToString(3) ??
"Unknown"; "Unknown";
/// <summary> Returns the user agent that Discord.NET uses in its clients. </summary>
/// <summary> Returns the user agent that Discord.Net uses in its clients. </summary>
public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})"; public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})";
/// <summary> Returns the base Discord API URL. </summary> /// <summary> Returns the base Discord API URL. </summary>
public static readonly string APIUrl = $"https://discordapp.com/api/v{APIVersion}/"; public static readonly string APIUrl = $"https://discordapp.com/api/v{APIVersion}/";


+ 9
- 9
src/Discord.Net.Core/Entities/Messages/EmbedBuilder.cs View File

@@ -57,7 +57,7 @@ namespace Discord
get => _url; get => _url;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(Url));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(Url));
_url = value; _url = value;
} }
} }
@@ -67,7 +67,7 @@ namespace Discord
get => _thumbnail?.Url; get => _thumbnail?.Url;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(ThumbnailUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(ThumbnailUrl));
_thumbnail = new EmbedThumbnail(value, null, null, null); _thumbnail = new EmbedThumbnail(value, null, null, null);
} }
} }
@@ -77,7 +77,7 @@ namespace Discord
get => _image?.Url; get => _image?.Url;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(ImageUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(ImageUrl));
_image = new EmbedImage(value, null, null, null); _image = new EmbedImage(value, null, null, null);
} }
} }
@@ -87,7 +87,7 @@ namespace Discord
get => _fields; get => _fields;
set set
{ {
if (value == null) throw new ArgumentNullException("Cannot set an embed builder's fields collection to null", nameof(Fields));
if (value == null) throw new ArgumentNullException(nameof(Fields), "Cannot set an embed builder's fields collection to null.");
if (value.Count > MaxFieldCount) throw new ArgumentException($"Field count must be less than or equal to {MaxFieldCount}.", nameof(Fields)); if (value.Count > MaxFieldCount) throw new ArgumentException($"Field count must be less than or equal to {MaxFieldCount}.", nameof(Fields));
_fields = value; _fields = value;
} }
@@ -271,7 +271,7 @@ namespace Discord
public Embed Build() public Embed Build()
{ {
if (Length > MaxEmbedLength) if (Length > MaxEmbedLength)
throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}");
throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}.");


var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count); var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count);
for (int i = 0; i < Fields.Count; i++) for (int i = 0; i < Fields.Count; i++)
@@ -294,7 +294,7 @@ namespace Discord
get => _name; get => _name;
set set
{ {
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException($"Field name must not be null, empty or entirely whitespace.", nameof(Name));
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Field name must not be null, empty or entirely whitespace.", nameof(Name));
if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name)); if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name));
_name = value; _name = value;
} }
@@ -354,7 +354,7 @@ namespace Discord
get => _url; get => _url;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(Url));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(Url));
_url = value; _url = value;
} }
} }
@@ -363,7 +363,7 @@ namespace Discord
get => _iconUrl; get => _iconUrl;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(IconUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(IconUrl));
_iconUrl = value; _iconUrl = value;
} }
} }
@@ -409,7 +409,7 @@ namespace Discord
get => _iconUrl; get => _iconUrl;
set set
{ {
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI", nameof(IconUrl));
if (!value.IsNullOrUri()) throw new ArgumentException("Url must be a well-formed URI.", nameof(IconUrl));
_iconUrl = value; _iconUrl = value;
} }
} }


+ 1
- 1
src/Discord.Net.Core/Entities/Permissions/ChannelPermission.cs View File

@@ -3,7 +3,7 @@ using System;
namespace Discord namespace Discord
{ {
/// <summary> Defines the available permissions for a channel. </summary> /// <summary> Defines the available permissions for a channel. </summary>
[FlagsAttribute]
[Flags]
public enum ChannelPermission : ulong public enum ChannelPermission : ulong
{ {
// General // General


+ 1
- 1
src/Discord.Net.Core/Entities/Permissions/ChannelPermissions.cs View File

@@ -29,7 +29,7 @@ namespace Discord
case ICategoryChannel _: return Category; case ICategoryChannel _: return Category;
case IDMChannel _: return DM; case IDMChannel _: return DM;
case IGroupChannel _: return Group; case IGroupChannel _: return Group;
default: throw new ArgumentException("Unknown channel type", nameof(channel));
default: throw new ArgumentException("Unknown channel type.", nameof(channel));
} }
} }




+ 6
- 6
src/Discord.Net.Core/Entities/Roles/Color.cs View File

@@ -74,11 +74,11 @@ namespace Discord
public Color(int r, int g, int b) public Color(int r, int g, int b)
{ {
if (r < 0 || r > 255) if (r < 0 || r > 255)
throw new ArgumentOutOfRangeException(nameof(r), "Value must be within [0,255]");
throw new ArgumentOutOfRangeException(nameof(r), "Value must be within [0,255].");
if (g < 0 || g > 255) if (g < 0 || g > 255)
throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,255]");
throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,255].");
if (b < 0 || b > 255) if (b < 0 || b > 255)
throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,255]");
throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,255].");
RawValue = RawValue =
((uint)r << 16) | ((uint)r << 16) |
((uint)g << 8) | ((uint)g << 8) |
@@ -87,11 +87,11 @@ namespace Discord
public Color(float r, float g, float b) public Color(float r, float g, float b)
{ {
if (r < 0.0f || r > 1.0f) if (r < 0.0f || r > 1.0f)
throw new ArgumentOutOfRangeException(nameof(r), "Value must be within [0,1]");
throw new ArgumentOutOfRangeException(nameof(r), "Value must be within [0,1].");
if (g < 0.0f || g > 1.0f) if (g < 0.0f || g > 1.0f)
throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,1]");
throw new ArgumentOutOfRangeException(nameof(g), "Value must be within [0,1].");
if (b < 0.0f || b > 1.0f) if (b < 0.0f || b > 1.0f)
throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,1]");
throw new ArgumentOutOfRangeException(nameof(b), "Value must be within [0,1].");
RawValue = RawValue =
((uint)(r * 255.0f) << 16) | ((uint)(r * 255.0f) << 16) |
((uint)(g * 255.0f) << 8) | ((uint)(g * 255.0f) << 8) |


Loading…
Cancel
Save