@@ -48,8 +48,8 @@ namespace Discord | |||
{ | |||
var result = new Override(); | |||
using(var textReader = new StringReader(json)) | |||
using(var reader = new JsonTextReader(textReader)) | |||
using (var textReader = new StringReader(json)) | |||
using (var reader = new JsonTextReader(textReader)) | |||
{ | |||
var obj = JObject.ReadFrom(reader); | |||
result.Id = obj["id"].ToObject<Guid>(); | |||
@@ -100,14 +100,14 @@ namespace Discord | |||
/// Gets a read-only dictionary containing the currently loaded overrides. | |||
/// </summary> | |||
public IReadOnlyDictionary<Override, IReadOnlyCollection<LoadedOverride>> LoadedOverrides | |||
=> _loadedOverrides.Select(x => new KeyValuePair<Override, IReadOnlyCollection<LoadedOverride>> (x.Key, x.Value)).ToDictionary(x => x.Key, x => x.Value); | |||
=> _loadedOverrides.Select(x => new KeyValuePair<Override, IReadOnlyCollection<LoadedOverride>>(x.Key, x.Value)).ToDictionary(x => x.Key, x => x.Value); | |||
private static AssemblyLoadContext _overrideDomain; | |||
private static List<Func<Override, string, Task>> _logEvents = new(); | |||
private static ConcurrentDictionary<Override, List<LoadedOverride>> _loadedOverrides = new ConcurrentDictionary<Override, List<LoadedOverride>>(); | |||
private const string ApiUrl = "https://overrides.discordnet.dev"; | |||
static BuildOverrides() | |||
{ | |||
_overrideDomain = new AssemblyLoadContext("Discord.Net.Overrides.Runtime"); | |||
@@ -258,14 +258,14 @@ namespace Discord | |||
private static async Task<Assembly> GetDependencyAsync(Guid id, string name) | |||
{ | |||
using(var client = new HttpClient()) | |||
using (var client = new HttpClient()) | |||
{ | |||
var result = await client.PostAsync($"{ApiUrl}/overrides/{id}/dependency", new StringContent($"{{ \"info\": \"{name}\"}}", Encoding.UTF8, "application/json")); | |||
if (!result.IsSuccessStatusCode) | |||
throw new Exception("Failed to get dependency"); | |||
using(var ms = new MemoryStream()) | |||
using (var ms = new MemoryStream()) | |||
{ | |||
var innerStream = await result.Content.ReadAsStreamAsync(); | |||
await innerStream.CopyToAsync(ms); | |||
@@ -1,8 +1,8 @@ | |||
using Discord; | |||
using Discord.WebSocket; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Discord; | |||
using Discord.WebSocket; | |||
namespace BasicBot | |||
{ | |||
@@ -112,7 +112,8 @@ namespace BasicBot | |||
if (component.Data.CustomId == "unique-id") | |||
await interaction.RespondAsync("Thank you for clicking my button!"); | |||
else Console.WriteLine("An ID has been received that has no handler!"); | |||
else | |||
Console.WriteLine("An ID has been received that has no handler!"); | |||
} | |||
} | |||
} | |||
@@ -30,7 +30,8 @@ namespace InteractionFramework.Attributes | |||
? Task.FromResult(PreconditionResult.FromSuccess()) | |||
: Task.FromResult(PreconditionResult.FromError("User ID does not match component ID!")); | |||
else return Task.FromResult(PreconditionResult.FromError("Parse cannot be done if no userID exists.")); | |||
else | |||
return Task.FromResult(PreconditionResult.FromError("Parse cannot be done if no userID exists.")); | |||
} | |||
} | |||
} | |||
@@ -10,7 +10,7 @@ namespace InteractionFramework.Attributes | |||
{ | |||
public class RequireOwnerAttribute : PreconditionAttribute | |||
{ | |||
public override async Task<PreconditionResult> CheckRequirementsAsync (IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services) | |||
public override async Task<PreconditionResult> CheckRequirementsAsync(IInteractionContext context, ICommandInfo commandInfo, IServiceProvider services) | |||
{ | |||
switch (context.Client.TokenType) | |||
{ | |||
@@ -26,7 +26,7 @@ namespace InteractionFramework.Modules | |||
// [Summary] lets you customize the name and the description of a parameter | |||
[SlashCommand("echo", "Repeat the input")] | |||
public async Task Echo(string echo, [Summary(description: "mention the user")]bool mention = false) | |||
public async Task Echo(string echo, [Summary(description: "mention the user")] bool mention = false) | |||
=> await RespondAsync(echo + (mention ? Context.User.Mention : string.Empty)); | |||
[SlashCommand("ping", "Pings the bot and returns its latency.")] | |||
@@ -64,11 +64,11 @@ namespace InteractionFramework | |||
public static bool IsDebug() | |||
{ | |||
#if DEBUG | |||
return true; | |||
#else | |||
#if DEBUG | |||
return true; | |||
#else | |||
return false; | |||
#endif | |||
#endif | |||
} | |||
} | |||
} |
@@ -1,11 +1,11 @@ | |||
using System; | |||
using System.Collections.Immutable; | |||
using System.Linq; | |||
using Discord.Commands; | |||
using Microsoft.CodeAnalysis; | |||
using Microsoft.CodeAnalysis.CSharp; | |||
using Microsoft.CodeAnalysis.CSharp.Syntax; | |||
using Microsoft.CodeAnalysis.Diagnostics; | |||
using Discord.Commands; | |||
using System; | |||
using System.Collections.Immutable; | |||
using System.Linq; | |||
namespace Discord.Analyzers | |||
{ | |||
@@ -13,7 +13,14 @@ namespace Discord.Analyzers | |||
public sealed class GuildAccessAnalyzer : DiagnosticAnalyzer | |||
{ | |||
private const string DiagnosticId = "DNET0001"; | |||
/* Unmerged change from project 'Discord.Net.Analyzers(netstandard2.1)' | |||
Before: | |||
private const string Title = "Limit command to Guild contexts."; | |||
After: | |||
private const string Title = "Limit command to Guild contexts"; | |||
*/ | |||
private const string Title = "Limit command to Guild contexts"; | |||
private const string MessageFormat = "Command method '{0}' is accessing 'Context.Guild' but is not restricted to Guild contexts."; | |||
private const string Description = "Accessing 'Context.Guild' in a command without limiting the command to run only in guilds."; | |||
private const string Category = "API Usage"; | |||
@@ -1,6 +1,6 @@ | |||
using System; | |||
using Microsoft.CodeAnalysis; | |||
using Discord.Commands; | |||
using Microsoft.CodeAnalysis; | |||
using System; | |||
namespace Discord.Analyzers | |||
{ | |||
@@ -43,8 +43,8 @@ namespace Discord.Commands | |||
{ | |||
if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) | |||
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}."); | |||
TypeReader = overridenTypeReader; | |||
} | |||
} | |||
} | |||
} |
@@ -61,7 +61,7 @@ namespace Discord.Commands | |||
if (GuildPermission.HasValue) | |||
{ | |||
if (guildUser == null) | |||
return Task.FromResult(PreconditionResult.FromError(NotAGuildErrorMessage ?? "Command must be used in a guild channel.")); | |||
return Task.FromResult(PreconditionResult.FromError(NotAGuildErrorMessage ?? "Command must be used in a guild channel.")); | |||
if (!guildUser.GuildPermissions.Has(GuildPermission.Value)) | |||
return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires guild permission {GuildPermission.Value}.")); | |||
} | |||
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Threading.Tasks; | |||
using System.Collections.Generic; | |||
namespace Discord.Commands.Builders | |||
{ | |||
@@ -20,7 +20,9 @@ namespace Discord.Commands.Builders | |||
public string Name { get; set; } | |||
public string Summary { get; set; } | |||
public string Remarks { get; set; } | |||
public string Group { get => _group; | |||
public string Group | |||
{ | |||
get => _group; | |||
set | |||
{ | |||
_aliases.Remove(_group); | |||
@@ -1,11 +1,10 @@ | |||
using Discord.Commands.Builders; | |||
using System; | |||
using System.Linq; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Reflection; | |||
using System.Threading.Tasks; | |||
using Discord.Commands.Builders; | |||
namespace Discord.Commands | |||
{ | |||
internal static class ModuleClassBuilder | |||
@@ -80,11 +79,11 @@ namespace Discord.Commands | |||
{ | |||
if (!IsValidModuleDefinition(typeInfo)) | |||
continue; | |||
if (builtTypes.Contains(typeInfo)) | |||
continue; | |||
builder.AddModule((module) => | |||
builder.AddModule((module) => | |||
{ | |||
BuildModule(module, typeInfo, service, services); | |||
BuildSubTypes(module, typeInfo.DeclaredNestedTypes, builtTypes, service, services); | |||
@@ -139,7 +138,7 @@ namespace Discord.Commands | |||
foreach (var method in validCommands) | |||
{ | |||
builder.AddCommand((command) => | |||
builder.AddCommand((command) => | |||
{ | |||
BuildCommand(command, typeInfo, method, service, services); | |||
}); | |||
@@ -149,7 +148,7 @@ namespace Discord.Commands | |||
private static void BuildCommand(CommandBuilder builder, TypeInfo typeInfo, MethodInfo method, CommandService service, IServiceProvider serviceprovider) | |||
{ | |||
var attributes = method.GetCustomAttributes(); | |||
foreach (var attribute in attributes) | |||
{ | |||
switch (attribute) | |||
@@ -191,7 +190,7 @@ namespace Discord.Commands | |||
int pos = 0, count = parameters.Length; | |||
foreach (var paramInfo in parameters) | |||
{ | |||
builder.AddParameter((parameter) => | |||
builder.AddParameter((parameter) => | |||
{ | |||
BuildParameter(parameter, paramInfo, pos++, count, service, serviceprovider); | |||
}); | |||
@@ -1,9 +1,8 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Reflection; | |||
using System.Collections.Generic; | |||
namespace Discord.Commands.Builders | |||
{ | |||
public class ParameterBuilder | |||
@@ -25,7 +24,7 @@ namespace Discord.Commands.Builders | |||
public IReadOnlyList<ParameterPreconditionAttribute> Preconditions => _preconditions; | |||
public IReadOnlyList<Attribute> Attributes => _attributes; | |||
#endregion | |||
#endregion | |||
#region Automatic | |||
internal ParameterBuilder(CommandBuilder command) | |||
@@ -1,3 +1,5 @@ | |||
using Discord.Commands.Builders; | |||
using Discord.Logging; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
@@ -6,8 +8,6 @@ using System.Linq; | |||
using System.Reflection; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Discord.Commands.Builders; | |||
using Discord.Logging; | |||
namespace Discord.Commands | |||
{ | |||
@@ -653,7 +653,7 @@ namespace Discord.Commands | |||
var bestCandidate = preconditionResults | |||
.OrderByDescending(x => x.Key.Command.Priority) | |||
.FirstOrDefault(x => !x.Value.IsSuccess); | |||
return MatchResult.FromSuccess(bestCandidate.Key,bestCandidate.Value); | |||
return MatchResult.FromSuccess(bestCandidate.Key, bestCandidate.Value); | |||
} | |||
var parseResults = new Dictionary<CommandMatch, ParseResult>(); | |||
@@ -685,7 +685,7 @@ namespace Discord.Commands | |||
.Where(x => x.Value.IsSuccess) | |||
.ToArray(); | |||
if(successfulParses.Length == 0) | |||
if (successfulParses.Length == 0) | |||
{ | |||
var bestMatch = parseResults | |||
.FirstOrDefault(x => !x.Value.IsSuccess); | |||
@@ -17,7 +17,7 @@ namespace Discord.Commands | |||
/// Gets or sets the <see cref="char"/> that separates an argument with another. | |||
/// </summary> | |||
public char SeparatorChar { get; set; } = ' '; | |||
/// <summary> | |||
/// Gets or sets whether commands should be case-sensitive. | |||
/// </summary> | |||
@@ -5,7 +5,7 @@ namespace Discord.Commands | |||
internal class EmptyServiceProvider : IServiceProvider | |||
{ | |||
public static readonly EmptyServiceProvider Instance = new EmptyServiceProvider(); | |||
public object GetService(Type serviceType) => null; | |||
} | |||
} |
@@ -19,4 +19,4 @@ namespace Discord.Commands | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -45,13 +45,17 @@ namespace Discord.Commands | |||
public static bool HasMentionPrefix(this IUserMessage msg, IUser user, ref int argPos) | |||
{ | |||
var text = msg.Content; | |||
if (string.IsNullOrEmpty(text) || text.Length <= 3 || text[0] != '<' || text[1] != '@') return false; | |||
if (string.IsNullOrEmpty(text) || text.Length <= 3 || text[0] != '<' || text[1] != '@') | |||
return false; | |||
int endPos = text.IndexOf('>'); | |||
if (endPos == -1) return false; | |||
if (text.Length < endPos + 2 || text[endPos + 1] != ' ') return false; //Must end in "> " | |||
if (endPos == -1) | |||
return false; | |||
if (text.Length < endPos + 2 || text[endPos + 1] != ' ') | |||
return false; //Must end in "> " | |||
if (!MentionUtils.TryParseUser(text.Substring(0, endPos + 1), out ulong userId)) return false; | |||
if (!MentionUtils.TryParseUser(text.Substring(0, endPos + 1), out ulong userId)) | |||
return false; | |||
if (userId == user.Id) | |||
{ | |||
argPos = endPos + 2; | |||
@@ -1,8 +1,8 @@ | |||
using Discord.Commands.Builders; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Collections.Concurrent; | |||
using System.Diagnostics; | |||
using System.Linq; | |||
using System.Reflection; | |||
@@ -175,7 +175,7 @@ namespace Discord.Commands | |||
return await CommandParser.ParseArgsAsync(this, context, _commandService._ignoreExtraArgs, services, input, 0, _commandService._quotationMarkAliasMap).ConfigureAwait(false); | |||
} | |||
public Task<IResult> ExecuteAsync(ICommandContext context, ParseResult parseResult, IServiceProvider services) | |||
{ | |||
if (!parseResult.IsSuccess) | |||
@@ -1,8 +1,8 @@ | |||
using Discord.Commands.Builders; | |||
using System; | |||
using System.Linq; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using Discord.Commands.Builders; | |||
using System.Linq; | |||
namespace Discord.Commands | |||
{ | |||
@@ -1,6 +1,6 @@ | |||
using Discord.Commands.Builders; | |||
using System; | |||
using System.Threading.Tasks; | |||
using Discord.Commands.Builders; | |||
namespace Discord.Commands | |||
{ | |||
@@ -23,7 +23,7 @@ namespace Discord.Commands | |||
private readonly IReadOnlyDictionary<T, object> _enumsByValue; | |||
private readonly Type _enumType; | |||
private readonly TryParseDelegate<T> _tryParse; | |||
public EnumTypeReader(Type type, TryParseDelegate<T> parser) | |||
{ | |||
_enumType = type; | |||
@@ -33,7 +33,7 @@ namespace Discord.Commands | |||
var byValueBuilder = ImmutableDictionary.CreateBuilder<T, object>(); | |||
foreach (var v in Enum.GetNames(_enumType)) | |||
{ | |||
{ | |||
var parsedValue = Enum.Parse(_enumType, v); | |||
byNameBuilder.Add(v.ToLower(), parsedValue); | |||
if (!byValueBuilder.ContainsKey((T)parsedValue)) | |||
@@ -116,7 +116,7 @@ namespace Discord.Commands | |||
argv = input.Substring(beginRead + 1, currentRead - beginRead - 1).Trim(); | |||
currentRead++; | |||
} | |||
else | |||
else | |||
argv = input.Substring(beginRead, currentRead - beginRead); | |||
return _tProps[currentParam]; | |||
@@ -27,7 +27,7 @@ namespace Discord.Commands | |||
//By Id (0.9) | |||
if (ulong.TryParse(input, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | |||
AddResult(results, context.Guild.GetRole(id) as T, 0.90f); | |||
AddResult(results, context.Guild.GetRole(id) as T, 0.90f); | |||
//By Name (0.7-0.8) | |||
foreach (var role in roles.Where(x => string.Equals(input, x.Name, StringComparison.OrdinalIgnoreCase))) | |||
@@ -65,7 +65,7 @@ namespace Discord.Commands | |||
.Where(x => string.Equals(input, x.Username, StringComparison.OrdinalIgnoreCase)) | |||
.ForEachAsync(channelUser => AddResult(results, channelUser as T, channelUser.Username == input ? 0.65f : 0.55f)) | |||
.ConfigureAwait(false); | |||
foreach (var guildUser in guildUsers.Where(x => string.Equals(input, x.Username, StringComparison.OrdinalIgnoreCase))) | |||
AddResult(results, guildUser as T, guildUser.Username == input ? 0.60f : 0.50f); | |||
} | |||
@@ -30,13 +30,13 @@ namespace Discord.Commands | |||
} | |||
public static MatchResult FromSuccess(CommandMatch match, IResult pipeline) | |||
=> new MatchResult(match,pipeline,null, null); | |||
=> new MatchResult(match, pipeline, null, null); | |||
public static MatchResult FromError(CommandError error, string reason) | |||
=> new MatchResult(null,null,error, reason); | |||
=> new MatchResult(null, null, error, reason); | |||
public static MatchResult FromError(Exception ex) | |||
=> FromError(CommandError.Exception, ex.Message); | |||
public static MatchResult FromError(IResult result) | |||
=> new MatchResult(null, null,result.Error, result.ErrorReason); | |||
=> new MatchResult(null, null, result.Error, result.ErrorReason); | |||
public static MatchResult FromError(IResult pipeline, CommandError error, string reason) | |||
=> new MatchResult(null, pipeline, error, reason); | |||
@@ -24,7 +24,7 @@ namespace Discord.Commands | |||
args[i] = GetMember(commands, services, parameters[i].ParameterType, typeInfo); | |||
var obj = InvokeConstructor<T>(constructor, args, typeInfo); | |||
foreach(var property in properties) | |||
foreach (var property in properties) | |||
property.SetValue(obj, GetMember(commands, services, property.PropertyType, typeInfo)); | |||
return obj; | |||
}; | |||
@@ -6,4 +6,4 @@ namespace Discord.Audio | |||
Music, | |||
Mixed | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
@@ -9,7 +9,7 @@ namespace Discord.Audio | |||
public abstract int AvailableFrames { get; } | |||
public override bool CanRead => true; | |||
public override bool CanWrite => true; | |||
public override bool CanWrite => true; | |||
public abstract Task<RTPFrame> ReadFrameAsync(CancellationToken cancelToken); | |||
public abstract bool TryReadFrame(CancellationToken cancelToken, out RTPFrame frame); | |||
@@ -12,7 +12,7 @@ namespace Discord.Audio | |||
public override bool CanWrite => false; | |||
/// <exception cref="InvalidOperationException">This stream does not accept headers.</exception> | |||
public virtual void WriteHeader(ushort seq, uint timestamp, bool missed) => | |||
public virtual void WriteHeader(ushort seq, uint timestamp, bool missed) => | |||
throw new InvalidOperationException("This stream does not accept headers."); | |||
public override void Write(byte[] buffer, int offset, int count) | |||
{ | |||
@@ -31,7 +31,7 @@ namespace Discord.Audio | |||
/// <inheritdoc /> | |||
/// <exception cref="NotSupportedException">Reading stream length is not supported.</exception> | |||
public override long Length => | |||
public override long Length => | |||
throw new NotSupportedException(); | |||
/// <inheritdoc /> | |||
@@ -15,4 +15,4 @@ namespace Discord.Audio | |||
Missed = missed; | |||
} | |||
} | |||
} | |||
} |
@@ -146,10 +146,10 @@ namespace Discord | |||
/// </returns> | |||
public static string GetGuildBannerUrl(ulong guildId, string bannerId, ImageFormat format, ushort? size = null) | |||
{ | |||
if (string.IsNullOrEmpty(bannerId)) | |||
return null; | |||
string extension = FormatToExtension(format, bannerId); | |||
return $"{DiscordConfig.CDNUrl}banners/{guildId}/{bannerId}.{extension}" + (size.HasValue ? $"?size={size}" : string.Empty); | |||
if (string.IsNullOrEmpty(bannerId)) | |||
return null; | |||
string extension = FormatToExtension(format, bannerId); | |||
return $"{DiscordConfig.CDNUrl}banners/{guildId}/{bannerId}.{extension}" + (size.HasValue ? $"?size={size}" : string.Empty); | |||
} | |||
/// <summary> | |||
/// Returns an emoji URL. | |||
@@ -175,23 +175,23 @@ namespace Discord | |||
/// </remarks> | |||
internal bool DisplayInitialLog { get; set; } = true; | |||
/// <summary> | |||
/// Gets or sets whether or not rate-limits should use the system clock. | |||
/// </summary> | |||
/// <remarks> | |||
/// If set to <c>false</c>, we will use the X-RateLimit-Reset-After header | |||
/// to determine when a rate-limit expires, rather than comparing the | |||
/// X-RateLimit-Reset timestamp to the system time. | |||
/// | |||
/// This should only be changed to false if the system is known to have | |||
/// a clock that is out of sync. Relying on the Reset-After header will | |||
/// incur network lag. | |||
/// | |||
/// Regardless of this property, we still rely on the system's wall-clock | |||
/// to determine if a bucket is rate-limited; we do not use any monotonic | |||
/// clock. Your system will still need a stable clock. | |||
/// </remarks> | |||
public bool UseSystemClock { get; set; } = true; | |||
/// <summary> | |||
/// Gets or sets whether or not rate-limits should use the system clock. | |||
/// </summary> | |||
/// <remarks> | |||
/// If set to <c>false</c>, we will use the X-RateLimit-Reset-After header | |||
/// to determine when a rate-limit expires, rather than comparing the | |||
/// X-RateLimit-Reset timestamp to the system time. | |||
/// | |||
/// This should only be changed to false if the system is known to have | |||
/// a clock that is out of sync. Relying on the Reset-After header will | |||
/// incur network lag. | |||
/// | |||
/// Regardless of this property, we still rely on the system's wall-clock | |||
/// to determine if a bucket is rate-limited; we do not use any monotonic | |||
/// clock. Your system will still need a stable clock. | |||
/// </remarks> | |||
public bool UseSystemClock { get; set; } = true; | |||
/// <summary> | |||
/// Gets or sets whether or not the internal experation check uses the system date | |||
@@ -30,7 +30,7 @@ namespace Discord | |||
Flags = flags; | |||
Details = details; | |||
} | |||
/// <summary> Returns the name of the <see cref="Game"/>. </summary> | |||
public override string ToString() => Name; | |||
private string DebuggerDisplay => Name; | |||
@@ -1,5 +1,5 @@ | |||
using System.Collections.Generic; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
namespace Discord; | |||
@@ -38,7 +38,7 @@ public class RoleConnectionProperties | |||
get => _platformUsername; | |||
set | |||
{ | |||
if(value is not null) | |||
if (value is not null) | |||
Preconditions.AtMost(value.Length, MaxPlatformUsernameLength, nameof(PlatformUsername), $"Platform username length must be less or equal to {MaxPlatformUsernameLength}"); | |||
_platformUsername = value; | |||
} | |||
@@ -103,7 +103,7 @@ public class RoleConnectionProperties | |||
internal RoleConnectionProperties AddMetadataRecord(string key, string value) | |||
{ | |||
Metadata ??= new Dictionary<string, string>(); | |||
if(!Metadata.ContainsKey(key)) | |||
if (!Metadata.ContainsKey(key)) | |||
Preconditions.AtMost(Metadata.Count + 1, MaxPlatformUsernameLength, nameof(Metadata), $"Metadata records count must be less or equal to {MaxMetadataRecords}"); | |||
_metadata[key] = value; | |||
@@ -126,7 +126,7 @@ public class RoleConnectionProperties | |||
/// <summary> | |||
/// Initializes a new instance of <see cref="RoleConnectionProperties"/>. | |||
/// </summary> | |||
public RoleConnectionProperties() {} | |||
public RoleConnectionProperties() { } | |||
/// <summary> | |||
/// Initializes a new <see cref="RoleConnectionProperties"/> with the data from provided <see cref="RoleConnection"/>. | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Provides properties that are used to modify an <see cref="IAudioChannel" /> with the specified changes. | |||
@@ -172,7 +172,7 @@ namespace Discord | |||
public Task<IThreadChannel> CreatePostWithFileAsync(string title, Stream stream, string filename, ThreadArchiveDuration archiveDuration = ThreadArchiveDuration.OneDay, | |||
int? slowmode = null, string text = null, Embed embed = null, RequestOptions options = null, bool isSpoiler = false, | |||
AllowedMentions allowedMentions = null, MessageComponent components = null, | |||
ISticker[] stickers = null, Embed[] embeds = null,MessageFlags flags = MessageFlags.None, ForumTag[] tags = null); | |||
ISticker[] stickers = null, Embed[] embeds = null, MessageFlags flags = MessageFlags.None, ForumTag[] tags = null); | |||
/// <summary> | |||
/// Creates a new post (thread) within the forum. | |||
@@ -222,7 +222,7 @@ namespace Discord | |||
/// <returns> | |||
/// Paged collection of messages. | |||
/// </returns> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> | |||
/// Gets a collection of messages in this channel. | |||
@@ -263,7 +263,7 @@ namespace Discord | |||
/// <returns> | |||
/// Paged collection of messages. | |||
/// </returns> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> | |||
/// Gets a collection of messages in this channel. | |||
@@ -300,7 +300,7 @@ namespace Discord | |||
/// <returns> | |||
/// Paged collection of messages. | |||
/// </returns> | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
IAsyncEnumerable<IReadOnlyCollection<IMessage>> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, | |||
CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); | |||
/// <summary> | |||
/// Gets a collection of pinned messages in this channel. | |||
@@ -1,6 +1,6 @@ | |||
using System; | |||
using System.Globalization; | |||
using System.Diagnostics; | |||
using System.Globalization; | |||
namespace Discord | |||
{ | |||
@@ -44,11 +44,14 @@ namespace Discord | |||
/// <param name="other">The object to compare with the current object.</param> | |||
public override bool Equals(object other) | |||
{ | |||
if (other == null) return false; | |||
if (other == this) return true; | |||
if (other == null) | |||
return false; | |||
if (other == this) | |||
return true; | |||
var otherEmote = other as Emote; | |||
if (otherEmote == null) return false; | |||
if (otherEmote == null) | |||
return false; | |||
return Id == otherEmote.Id; | |||
} | |||
@@ -45,7 +45,7 @@ namespace Discord | |||
} | |||
public override int GetHashCode() => (Id, Name, Emoji, IsModerated).GetHashCode(); | |||
public override bool Equals(object? obj) | |||
=> obj is ForumTag tag && Equals(tag); | |||
@@ -110,8 +110,8 @@ public class ForumTagBuilder | |||
public ForumTagBuilder(string name, ulong? id = null, bool isModerated = false, ulong? emoteId = null) | |||
{ | |||
Name = name; | |||
if(emoteId is not null) | |||
Emoji = new Emote(emoteId.Value, null, false); | |||
if (emoteId is not null) | |||
Emoji = new Emote(emoteId.Value, null, false); | |||
IsModerated = isModerated; | |||
Id = id; | |||
} | |||
@@ -180,12 +180,12 @@ public class ForumTagBuilder | |||
=> builder is not null && | |||
Id == builder.Id && | |||
Name == builder.Name && | |||
(Emoji is Emoji emoji && builder.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || | |||
(Emoji is Emoji emoji && builder.Emoji is Emoji otherEmoji && emoji.Equals(otherEmoji) || | |||
Emoji is Emote emote && builder.Emoji is Emote otherEmote && emote.Equals(otherEmote)) && | |||
IsModerated == builder.IsModerated; | |||
public static bool operator ==(ForumTagBuilder? left, ForumTagBuilder? right) | |||
=> left?.Equals(right) ?? right is null ; | |||
=> left?.Equals(right) ?? right is null; | |||
public static bool operator !=(ForumTagBuilder? left, ForumTagBuilder? right) => !(left == right); | |||
} |
@@ -19,4 +19,4 @@ namespace Discord | |||
/// </summary> | |||
AgeRestricted = 3 | |||
} | |||
} | |||
} |
@@ -50,5 +50,5 @@ public class WelcomeScreenChannelProperties : ISnowflakeEntity | |||
/// <param name="channel">A welcome screen channel to modify.</param> | |||
/// <returns>A new instance of <see cref="WelcomeScreenChannelProperties"/>.</returns> | |||
public static WelcomeScreenChannelProperties FromWelcomeScreenChannel(WelcomeScreenChannel channel) | |||
=> new (channel.Id, channel.Description, channel.Emoji); | |||
=> new(channel.Id, channel.Description, channel.Emoji); | |||
} |
@@ -34,7 +34,7 @@ namespace Discord | |||
/// <summary> | |||
/// Gets the icon URL of the application. | |||
/// </summary> | |||
string IconUrl { get; } | |||
string IconUrl { get; } | |||
/// <summary> | |||
/// Gets if the bot is public. | |||
/// </summary> | |||
@@ -90,7 +90,7 @@ namespace Discord | |||
/// Gets the bot/OAuth2 application for a discord integration. | |||
/// </summary> | |||
IIntegrationApplication Application { get; } | |||
IGuild Guild { get; } | |||
ulong GuildId { get; } | |||
} | |||
@@ -110,7 +110,7 @@ namespace Discord | |||
{ | |||
foreach (var (locale, name) in value) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidOptionName(name); | |||
@@ -134,7 +134,7 @@ namespace Discord | |||
{ | |||
foreach (var (locale, description) in value) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidOptionDescription(description); | |||
@@ -45,7 +45,7 @@ namespace Discord | |||
public object Value | |||
{ | |||
get => _value; | |||
set | |||
set | |||
{ | |||
if (value is not string && !value.IsNumericType()) | |||
throw new ArgumentException($"{nameof(value)} must be a numeric type or a string!"); | |||
@@ -49,7 +49,7 @@ namespace Discord | |||
/// <summary> | |||
/// Gets or sets whether or not this command is age restricted. | |||
/// </summary> | |||
public bool IsNsfw{ get; set; } = false; | |||
public bool IsNsfw { get; set; } = false; | |||
/// <summary> | |||
/// Gets or sets the default permission required to use this slash command. | |||
@@ -118,7 +118,7 @@ namespace Discord | |||
foreach (var (locale, name) in nameLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -159,7 +159,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public MessageCommandBuilder AddNameLocalization(string locale, string name) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -116,7 +116,7 @@ namespace Discord | |||
foreach (var (locale, name) in nameLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -125,7 +125,7 @@ namespace Discord | |||
_nameLocalizations = new Dictionary<string, string>(nameLocalizations); | |||
return this; | |||
} | |||
/// <summary> | |||
/// Sets whether or not this command can be used in dms. | |||
/// </summary> | |||
@@ -157,7 +157,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public UserCommandBuilder AddNameLocalization(string locale, string name) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -130,7 +130,7 @@ namespace Discord | |||
async Task RespondWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, | |||
AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) | |||
{ | |||
using(var file = new FileAttachment(fileStream, fileName)) | |||
using (var file = new FileAttachment(fileStream, fileName)) | |||
{ | |||
await RespondWithFileAsync(file, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false); | |||
} | |||
@@ -249,7 +249,7 @@ namespace Discord | |||
async Task<IUserMessage> FollowupWithFileAsync(Stream fileStream, string fileName, string text = null, Embed[] embeds = null, bool isTTS = false, bool ephemeral = false, | |||
AllowedMentions allowedMentions = null, MessageComponent components = null, Embed embed = null, RequestOptions options = null) | |||
{ | |||
using(var file = new FileAttachment(fileStream, fileName)) | |||
using (var file = new FileAttachment(fileStream, fileName)) | |||
{ | |||
return await FollowupWithFileAsync(file, text, embeds, isTTS, ephemeral, allowedMentions, components, embed, options).ConfigureAwait(false); | |||
} | |||
@@ -46,7 +46,7 @@ namespace Discord | |||
/// </summary> | |||
public string Value { get; } | |||
internal TextInputComponent(string customId, string label, string placeholder, int? minLength, int? maxLength, | |||
internal TextInputComponent(string customId, string label, string placeholder, int? minLength, int? maxLength, | |||
TextInputStyle style, bool? required, string value) | |||
{ | |||
CustomId = customId; | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
public enum TextInputStyle | |||
{ | |||
@@ -93,7 +93,7 @@ namespace Discord | |||
/// <param name="maxLength">The input's maximum length.</param> | |||
/// <param name="style">The input's style.</param> | |||
/// <returns>The current builder.</returns> | |||
public ModalBuilder AddTextInput(string label, string customId, TextInputStyle style = TextInputStyle.Short, | |||
public ModalBuilder AddTextInput(string label, string customId, TextInputStyle style = TextInputStyle.Short, | |||
string placeholder = "", int? minLength = null, int? maxLength = null, bool? required = null, string value = null) | |||
=> AddTextInput(new(label, customId, style, placeholder, minLength, maxLength, required, value)); | |||
@@ -204,7 +204,7 @@ namespace Discord | |||
/// <param name="maxLength">The input's maximum length.</param> | |||
/// <param name="style">The input's style.</param> | |||
/// <returns>The current builder.</returns> | |||
public ModalComponentBuilder WithTextInput(string label, string customId, TextInputStyle style = TextInputStyle.Short, | |||
public ModalComponentBuilder WithTextInput(string label, string customId, TextInputStyle style = TextInputStyle.Short, | |||
string placeholder = null, int? minLength = null, int? maxLength = null, int row = 0, bool? required = null, | |||
string value = null) | |||
=> WithTextInput(new(label, customId, style, placeholder, minLength, maxLength, required, value), row); | |||
@@ -263,6 +263,6 @@ namespace Discord | |||
/// </summary> | |||
/// <returns>A <see cref="ModalComponent"/> representing the builder.</returns> | |||
public ModalComponent Build() | |||
=> new (ActionRows?.Select(x => x.Build()).ToList()); | |||
=> new(ActionRows?.Select(x => x.Build()).ToList()); | |||
} | |||
} |
@@ -84,7 +84,7 @@ namespace Discord | |||
/// Gets or sets whether or not this command can be used in DMs. | |||
/// </summary> | |||
public bool IsDMEnabled { get; set; } = true; | |||
/// <summary> | |||
/// Gets or sets whether or not this command is age restricted. | |||
/// </summary> | |||
@@ -312,7 +312,7 @@ namespace Discord | |||
foreach (var (locale, name) in nameLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -336,7 +336,7 @@ namespace Discord | |||
foreach (var (locale, description) in descriptionLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandDescription(description); | |||
@@ -355,7 +355,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public SlashCommandBuilder AddNameLocalization(string locale, string name) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandName(name); | |||
@@ -375,7 +375,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public SlashCommandBuilder AddDescriptionLocalization(string locale, string description) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandDescription(description); | |||
@@ -549,7 +549,7 @@ namespace Discord | |||
if (isIntType && MaxValue != null && MaxValue % 1 != 0) | |||
throw new InvalidOperationException("MaxValue cannot have decimals on Integer command options."); | |||
if(isStrType && MinLength is not null && MinLength < 0) | |||
if (isStrType && MinLength is not null && MinLength < 0) | |||
throw new InvalidOperationException("MinLength cannot be smaller than 0."); | |||
if (isStrType && MaxLength is not null && MaxLength < 1) | |||
@@ -627,10 +627,10 @@ namespace Discord | |||
ChannelTypes = channelTypes, | |||
}; | |||
if(nameLocalizations is not null) | |||
if (nameLocalizations is not null) | |||
option.WithNameLocalizations(nameLocalizations); | |||
if(descriptionLocalizations is not null) | |||
if (descriptionLocalizations is not null) | |||
option.WithDescriptionLocalizations(descriptionLocalizations); | |||
return AddOption(option); | |||
@@ -749,7 +749,7 @@ namespace Discord | |||
Preconditions.AtLeast(name.Length, 1, nameof(name)); | |||
Preconditions.AtMost(name.Length, 100, nameof(name)); | |||
if(value is string str) | |||
if (value is string str) | |||
{ | |||
Preconditions.AtLeast(str.Length, 1, nameof(value)); | |||
Preconditions.AtMost(str.Length, 100, nameof(value)); | |||
@@ -904,7 +904,7 @@ namespace Discord | |||
foreach (var (locale, name) in nameLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandOptionName(name); | |||
@@ -928,7 +928,7 @@ namespace Discord | |||
foreach (var (locale, description) in descriptionLocalizations) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandOptionDescription(description); | |||
@@ -947,7 +947,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public SlashCommandOptionBuilder AddNameLocalization(string locale, string name) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandOptionName(name); | |||
@@ -967,7 +967,7 @@ namespace Discord | |||
/// <exception cref="ArgumentException">Thrown if <paramref name="locale"/> is an invalid locale string.</exception> | |||
public SlashCommandOptionBuilder AddDescriptionLocalization(string locale, string description) | |||
{ | |||
if(!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
if (!Regex.IsMatch(locale, @"^\w{2}(?:-\w{2})?$")) | |||
throw new ArgumentException($"Invalid locale: {locale}", nameof(locale)); | |||
EnsureValidCommandOptionDescription(description); | |||
@@ -81,7 +81,7 @@ public class InviteGuild : ISnowflakeEntity | |||
/// A URL pointing to the guild's icon; <see langword="null" /> if none is set. | |||
/// </returns> | |||
public string IconUrl => CDN.GetGuildIconUrl(Id, IconId); | |||
/// <summary> | |||
/// | |||
/// Gets the level of requirements a user must fulfill before being allowed to post messages in this guild. | |||
@@ -127,17 +127,17 @@ public class InviteGuild : ISnowflakeEntity | |||
public WelcomeScreen WelcomeScreen { get; private set; } | |||
internal InviteGuild( | |||
ulong id, | |||
string name, | |||
string description, | |||
string splashId, | |||
string bannerId, | |||
GuildFeatures features, | |||
string iconId, | |||
VerificationLevel verificationLevel, | |||
string vanityURLCode, | |||
int premiumSubscriptionCount, | |||
NsfwLevel nsfwLevel, | |||
ulong id, | |||
string name, | |||
string description, | |||
string splashId, | |||
string bannerId, | |||
GuildFeatures features, | |||
string iconId, | |||
VerificationLevel verificationLevel, | |||
string vanityURLCode, | |||
int premiumSubscriptionCount, | |||
NsfwLevel nsfwLevel, | |||
WelcomeScreen welcomeScreen) | |||
{ | |||
Id = id; | |||
@@ -17,18 +17,18 @@ namespace Discord | |||
/// It will always be present and does not mean mentions will not be allowed. | |||
/// </note> | |||
/// </remarks> | |||
None = 0, | |||
None = 0, | |||
/// <summary> | |||
/// Controls role mentions. | |||
/// </summary> | |||
Roles = 1, | |||
Roles = 1, | |||
/// <summary> | |||
/// Controls user mentions. | |||
/// </summary> | |||
Users = 2, | |||
Users = 2, | |||
/// <summary> | |||
/// Controls <code>@everyone</code> and <code>@here</code> mentions. | |||
/// </summary> | |||
Everyone = 4, | |||
Everyone = 4, | |||
} | |||
} |
@@ -44,7 +44,7 @@ namespace Discord | |||
Type = type; | |||
Fields = ImmutableArray.Create<EmbedField>(); | |||
} | |||
internal Embed(EmbedType type, | |||
internal Embed(EmbedType type, | |||
string title, | |||
string description, | |||
string url, | |||
@@ -52,10 +52,10 @@ namespace Discord | |||
Color? color, | |||
EmbedImage? image, | |||
EmbedVideo? video, | |||
EmbedAuthor? author, | |||
EmbedFooter? footer, | |||
EmbedProvider? provider, | |||
EmbedThumbnail? thumbnail, | |||
EmbedAuthor? author, | |||
EmbedFooter? footer, | |||
EmbedProvider? provider, | |||
EmbedThumbnail? thumbnail, | |||
ImmutableArray<EmbedField> fields) | |||
{ | |||
Type = type; | |||
@@ -128,7 +128,7 @@ namespace Discord | |||
{ | |||
var hash = 17; | |||
hash = hash * 23 + (Type, Title, Description, Timestamp, Color, Image, Video, Author, Footer, Provider, Thumbnail).GetHashCode(); | |||
foreach(var field in Fields) | |||
foreach (var field in Fields) | |||
hash = hash * 23 + field.GetHashCode(); | |||
return hash; | |||
} | |||
@@ -1,9 +1,9 @@ | |||
using Discord.Utils; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Linq; | |||
using Discord.Utils; | |||
using Newtonsoft.Json; | |||
namespace Discord | |||
{ | |||
@@ -50,7 +50,8 @@ namespace Discord | |||
get => _title; | |||
set | |||
{ | |||
if (value?.Length > MaxTitleLength) throw new ArgumentException(message: $"Title length must be less than or equal to {MaxTitleLength}.", paramName: nameof(Title)); | |||
if (value?.Length > MaxTitleLength) | |||
throw new ArgumentException(message: $"Title length must be less than or equal to {MaxTitleLength}.", paramName: nameof(Title)); | |||
_title = value; | |||
} | |||
} | |||
@@ -63,7 +64,8 @@ namespace Discord | |||
get => _description; | |||
set | |||
{ | |||
if (value?.Length > MaxDescriptionLength) throw new ArgumentException(message: $"Description length must be less than or equal to {MaxDescriptionLength}.", paramName: nameof(Description)); | |||
if (value?.Length > MaxDescriptionLength) | |||
throw new ArgumentException(message: $"Description length must be less than or equal to {MaxDescriptionLength}.", paramName: nameof(Description)); | |||
_description = value; | |||
} | |||
} | |||
@@ -100,8 +102,10 @@ namespace Discord | |||
get => _fields; | |||
set | |||
{ | |||
if (value == null) throw new ArgumentNullException(paramName: nameof(Fields), message: "Cannot set an embed builder's fields collection to null."); | |||
if (value.Count > MaxFieldCount) throw new ArgumentException(message: $"Field count must be less than or equal to {MaxFieldCount}.", paramName: nameof(Fields)); | |||
if (value == null) | |||
throw new ArgumentNullException(paramName: nameof(Fields), message: "Cannot set an embed builder's fields collection to null."); | |||
if (value.Count > MaxFieldCount) | |||
throw new ArgumentException(message: $"Field count must be less than or equal to {MaxFieldCount}.", paramName: nameof(Fields)); | |||
_fields = value; | |||
} | |||
} | |||
@@ -470,7 +474,7 @@ namespace Discord | |||
if (!string.IsNullOrEmpty(Author.IconUrl)) | |||
UrlValidation.Validate(Author.IconUrl, true); | |||
} | |||
if(Footer != null) | |||
if (Footer != null) | |||
{ | |||
if (!string.IsNullOrEmpty(Footer.IconUrl)) | |||
UrlValidation.Validate(Footer.IconUrl, true); | |||
@@ -564,8 +568,10 @@ namespace Discord | |||
get => _name; | |||
set | |||
{ | |||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(message: "Field name must not be null, empty or entirely whitespace.", paramName: nameof(Name)); | |||
if (value.Length > MaxFieldNameLength) throw new ArgumentException(message: $"Field name length must be less than or equal to {MaxFieldNameLength}.", paramName: nameof(Name)); | |||
if (string.IsNullOrWhiteSpace(value)) | |||
throw new ArgumentException(message: "Field name must not be null, empty or entirely whitespace.", paramName: nameof(Name)); | |||
if (value.Length > MaxFieldNameLength) | |||
throw new ArgumentException(message: $"Field name length must be less than or equal to {MaxFieldNameLength}.", paramName: nameof(Name)); | |||
_name = value; | |||
} | |||
} | |||
@@ -587,8 +593,10 @@ namespace Discord | |||
set | |||
{ | |||
var stringValue = value?.ToString(); | |||
if (string.IsNullOrWhiteSpace(stringValue)) throw new ArgumentException(message: "Field value must not be null or empty.", paramName: nameof(Value)); | |||
if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException(message: $"Field value length must be less than or equal to {MaxFieldValueLength}.", paramName: nameof(Value)); | |||
if (string.IsNullOrWhiteSpace(stringValue)) | |||
throw new ArgumentException(message: "Field value must not be null or empty.", paramName: nameof(Value)); | |||
if (stringValue.Length > MaxFieldValueLength) | |||
throw new ArgumentException(message: $"Field value length must be less than or equal to {MaxFieldValueLength}.", paramName: nameof(Value)); | |||
_value = stringValue; | |||
} | |||
} | |||
@@ -704,7 +712,8 @@ namespace Discord | |||
get => _name; | |||
set | |||
{ | |||
if (value?.Length > MaxAuthorNameLength) throw new ArgumentException(message: $"Author name length must be less than or equal to {MaxAuthorNameLength}.", paramName: nameof(Name)); | |||
if (value?.Length > MaxAuthorNameLength) | |||
throw new ArgumentException(message: $"Author name length must be less than or equal to {MaxAuthorNameLength}.", paramName: nameof(Name)); | |||
_name = value; | |||
} | |||
} | |||
@@ -836,7 +845,8 @@ namespace Discord | |||
get => _text; | |||
set | |||
{ | |||
if (value?.Length > MaxFooterTextLength) throw new ArgumentException(message: $"Footer text length must be less than or equal to {MaxFooterTextLength}.", paramName: nameof(Text)); | |||
if (value?.Length > MaxFooterTextLength) | |||
throw new ArgumentException(message: $"Footer text length must be less than or equal to {MaxFooterTextLength}.", paramName: nameof(Text)); | |||
_text = value; | |||
} | |||
} | |||
@@ -79,7 +79,7 @@ namespace Discord | |||
/// Time of when the message was last edited; <c>null</c> if the message is never edited. | |||
/// </returns> | |||
DateTimeOffset? EditedTimestamp { get; } | |||
/// <summary> | |||
/// Gets the source channel of the message. | |||
/// </summary> | |||
@@ -197,7 +197,7 @@ namespace Discord | |||
/// A read-only collection of sticker item objects. | |||
/// </returns> | |||
IReadOnlyCollection<IStickerItem> Stickers { get; } | |||
/// <summary> | |||
/// Gets the flags related to this message. | |||
/// </summary> | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
public interface ITag | |||
{ | |||
@@ -1,4 +1,4 @@ | |||
using System.Diagnostics; | |||
using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
@@ -10,105 +10,105 @@ namespace Discord | |||
/// <summary> | |||
/// Allows creation of instant invites. | |||
/// </summary> | |||
CreateInstantInvite = 0x00_00_00_00_01, | |||
CreateInstantInvite = 0x00_00_00_00_01, | |||
/// <summary> | |||
/// Allows management and editing of channels. | |||
/// </summary> | |||
ManageChannels = 0x00_00_00_00_10, | |||
ManageChannels = 0x00_00_00_00_10, | |||
// Text | |||
/// <summary> | |||
/// Allows for the addition of reactions to messages. | |||
/// </summary> | |||
AddReactions = 0x00_00_00_00_40, | |||
AddReactions = 0x00_00_00_00_40, | |||
/// <summary> | |||
/// Allows guild members to view a channel, which includes reading messages in text channels. | |||
/// </summary> | |||
ViewChannel = 0x00_00_00_04_00, | |||
ViewChannel = 0x00_00_00_04_00, | |||
/// <summary> | |||
/// Allows for sending messages in a channel. | |||
/// </summary> | |||
SendMessages = 0x00_00_00_08_00, | |||
SendMessages = 0x00_00_00_08_00, | |||
/// <summary> | |||
/// Allows for sending of text-to-speech messages. | |||
/// </summary> | |||
SendTTSMessages = 0x00_00_00_10_00, | |||
SendTTSMessages = 0x00_00_00_10_00, | |||
/// <summary> | |||
/// Allows for deletion of other users messages. | |||
/// </summary> | |||
ManageMessages = 0x00_00_00_20_00, | |||
ManageMessages = 0x00_00_00_20_00, | |||
/// <summary> | |||
/// Allows links sent by users with this permission will be auto-embedded. | |||
/// </summary> | |||
EmbedLinks = 0x00_00_00_40_00, | |||
EmbedLinks = 0x00_00_00_40_00, | |||
/// <summary> | |||
/// Allows for uploading images and files. | |||
/// </summary> | |||
AttachFiles = 0x00_00_00_80_00, | |||
AttachFiles = 0x00_00_00_80_00, | |||
/// <summary> | |||
/// Allows for reading of message history. | |||
/// </summary> | |||
ReadMessageHistory = 0x00_00_01_00_00, | |||
ReadMessageHistory = 0x00_00_01_00_00, | |||
/// <summary> | |||
/// Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all | |||
/// online users in a channel. | |||
/// </summary> | |||
MentionEveryone = 0x00_00_02_00_00, | |||
MentionEveryone = 0x00_00_02_00_00, | |||
/// <summary> | |||
/// Allows the usage of custom emojis from other servers. | |||
/// </summary> | |||
UseExternalEmojis = 0x00_00_04_00_00, | |||
UseExternalEmojis = 0x00_00_04_00_00, | |||
// Voice | |||
/// <summary> | |||
/// Allows for joining of a voice channel. | |||
/// </summary> | |||
Connect = 0x00_00_10_00_00, | |||
Connect = 0x00_00_10_00_00, | |||
/// <summary> | |||
/// Allows for speaking in a voice channel. | |||
/// </summary> | |||
Speak = 0x00_00_20_00_00, | |||
Speak = 0x00_00_20_00_00, | |||
/// <summary> | |||
/// Allows for muting members in a voice channel. | |||
/// </summary> | |||
MuteMembers = 0x00_00_40_00_00, | |||
MuteMembers = 0x00_00_40_00_00, | |||
/// <summary> | |||
/// Allows for deafening of members in a voice channel. | |||
/// </summary> | |||
DeafenMembers = 0x00_00_80_00_00, | |||
DeafenMembers = 0x00_00_80_00_00, | |||
/// <summary> | |||
/// Allows for moving of members between voice channels. | |||
/// </summary> | |||
MoveMembers = 0x00_01_00_00_00, | |||
MoveMembers = 0x00_01_00_00_00, | |||
/// <summary> | |||
/// Allows for using voice-activity-detection in a voice channel. | |||
/// </summary> | |||
UseVAD = 0x00_02_00_00_00, | |||
UseVAD = 0x00_02_00_00_00, | |||
/// <summary> | |||
/// Allows for using priority speaker in a voice channel. | |||
/// </summary> | |||
PrioritySpeaker = 0x00_00_00_01_00, | |||
PrioritySpeaker = 0x00_00_00_01_00, | |||
/// <summary> | |||
/// Allows video streaming in a voice channel. | |||
/// </summary> | |||
Stream = 0x00_00_00_02_00, | |||
Stream = 0x00_00_00_02_00, | |||
// More General | |||
/// <summary> | |||
/// Allows management and editing of roles. | |||
/// </summary> | |||
ManageRoles = 0x00_10_00_00_00, | |||
ManageRoles = 0x00_10_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of webhooks. | |||
/// </summary> | |||
ManageWebhooks = 0x00_20_00_00_00, | |||
ManageWebhooks = 0x00_20_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of emojis. | |||
/// </summary> | |||
ManageEmojis = 0x00_40_00_00_00, | |||
ManageEmojis = 0x00_40_00_00_00, | |||
/// <summary> | |||
/// Allows members to use slash commands in text channels. | |||
@@ -118,12 +118,12 @@ namespace Discord | |||
/// <summary> | |||
/// Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.) | |||
/// </summary> | |||
RequestToSpeak = 0x01_00_00_00_00, | |||
RequestToSpeak = 0x01_00_00_00_00, | |||
/// <summary> | |||
/// Allows for deleting and archiving threads, and viewing all private threads | |||
/// </summary> | |||
ManageThreads = 0x04_00_00_00_00, | |||
ManageThreads = 0x04_00_00_00_00, | |||
/// <summary> | |||
/// Allows for creating public threads. | |||
@@ -10,7 +10,7 @@ namespace Discord | |||
/// <summary> | |||
/// Allows creation of instant invites. | |||
/// </summary> | |||
CreateInstantInvite = 0x00_00_00_01, | |||
CreateInstantInvite = 0x00_00_00_01, | |||
/// <summary> | |||
/// Allows kicking members. | |||
/// </summary> | |||
@@ -18,7 +18,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
KickMembers = 0x00_00_00_02, | |||
KickMembers = 0x00_00_00_02, | |||
/// <summary> | |||
/// Allows banning members. | |||
/// </summary> | |||
@@ -26,7 +26,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
BanMembers = 0x00_00_00_04, | |||
BanMembers = 0x00_00_00_04, | |||
/// <summary> | |||
/// Allows all permissions and bypasses channel permission overwrites. | |||
/// </summary> | |||
@@ -34,7 +34,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
Administrator = 0x00_00_00_08, | |||
Administrator = 0x00_00_00_08, | |||
/// <summary> | |||
/// Allows management and editing of channels. | |||
/// </summary> | |||
@@ -42,7 +42,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageChannels = 0x00_00_00_10, | |||
ManageChannels = 0x00_00_00_10, | |||
/// <summary> | |||
/// Allows management and editing of the guild. | |||
/// </summary> | |||
@@ -50,33 +50,33 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageGuild = 0x00_00_00_20, | |||
ManageGuild = 0x00_00_00_20, | |||
/// <summary> | |||
/// Allows for viewing of guild insights | |||
/// </summary> | |||
ViewGuildInsights = 0x00_08_00_00, | |||
ViewGuildInsights = 0x00_08_00_00, | |||
// Text | |||
/// <summary> | |||
/// Allows for the addition of reactions to messages. | |||
/// </summary> | |||
AddReactions = 0x00_00_00_40, | |||
/// <summary> | |||
/// Allows for viewing of audit logs. | |||
/// </summary> | |||
ViewAuditLog = 0x00_00_00_80, | |||
/// <summary> | |||
/// Allows for the addition of reactions to messages. | |||
/// </summary> | |||
AddReactions = 0x00_00_00_40, | |||
/// <summary> | |||
/// Allows for viewing of audit logs. | |||
/// </summary> | |||
ViewAuditLog = 0x00_00_00_80, | |||
/// <summary> | |||
/// Allows guild members to view a channel, which includes reading messages in text channels. | |||
/// </summary> | |||
ViewChannel = 0x00_00_04_00, | |||
ViewChannel = 0x00_00_04_00, | |||
/// <summary> | |||
/// Allows for sending messages in a channel | |||
/// </summary> | |||
SendMessages = 0x00_00_08_00, | |||
/// <summary> | |||
/// Allows for sending of text-to-speech messages. | |||
/// </summary> | |||
SendTTSMessages = 0x00_00_10_00, | |||
SendMessages = 0x00_00_08_00, | |||
/// <summary> | |||
/// Allows for sending of text-to-speech messages. | |||
/// </summary> | |||
SendTTSMessages = 0x00_00_10_00, | |||
/// <summary> | |||
/// Allows for deletion of other users messages. | |||
/// </summary> | |||
@@ -84,55 +84,55 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageMessages = 0x00_00_20_00, | |||
ManageMessages = 0x00_00_20_00, | |||
/// <summary> | |||
/// Allows links sent by users with this permission will be auto-embedded. | |||
/// </summary> | |||
EmbedLinks = 0x00_00_40_00, | |||
EmbedLinks = 0x00_00_40_00, | |||
/// <summary> | |||
/// Allows for uploading images and files. | |||
/// </summary> | |||
AttachFiles = 0x00_00_80_00, | |||
AttachFiles = 0x00_00_80_00, | |||
/// <summary> | |||
/// Allows for reading of message history. | |||
/// </summary> | |||
ReadMessageHistory = 0x00_01_00_00, | |||
ReadMessageHistory = 0x00_01_00_00, | |||
/// <summary> | |||
/// Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all | |||
/// online users in a channel. | |||
/// </summary> | |||
MentionEveryone = 0x00_02_00_00, | |||
MentionEveryone = 0x00_02_00_00, | |||
/// <summary> | |||
/// Allows the usage of custom emojis from other servers. | |||
/// </summary> | |||
UseExternalEmojis = 0x00_04_00_00, | |||
UseExternalEmojis = 0x00_04_00_00, | |||
// Voice | |||
/// <summary> | |||
/// Allows for joining of a voice channel. | |||
/// </summary> | |||
Connect = 0x00_10_00_00, | |||
Connect = 0x00_10_00_00, | |||
/// <summary> | |||
/// Allows for speaking in a voice channel. | |||
/// </summary> | |||
Speak = 0x00_20_00_00, | |||
Speak = 0x00_20_00_00, | |||
/// <summary> | |||
/// Allows for muting members in a voice channel. | |||
/// </summary> | |||
MuteMembers = 0x00_40_00_00, | |||
MuteMembers = 0x00_40_00_00, | |||
/// <summary> | |||
/// Allows for deafening of members in a voice channel. | |||
/// </summary> | |||
DeafenMembers = 0x00_80_00_00, | |||
DeafenMembers = 0x00_80_00_00, | |||
/// <summary> | |||
/// Allows for moving of members between voice channels. | |||
/// </summary> | |||
MoveMembers = 0x01_00_00_00, | |||
MoveMembers = 0x01_00_00_00, | |||
/// <summary> | |||
/// Allows for using voice-activity-detection in a voice channel. | |||
/// </summary> | |||
UseVAD = 0x02_00_00_00, | |||
UseVAD = 0x02_00_00_00, | |||
/// <summary> | |||
/// Allows for using priority speaker in a voice channel. | |||
/// </summary> | |||
@@ -140,17 +140,17 @@ namespace Discord | |||
/// <summary> | |||
/// Allows video streaming in a voice channel. | |||
/// </summary> | |||
Stream = 0x00_00_02_00, | |||
Stream = 0x00_00_02_00, | |||
// General 2 | |||
/// <summary> | |||
/// Allows for modification of own nickname. | |||
/// </summary> | |||
ChangeNickname = 0x04_00_00_00, | |||
ChangeNickname = 0x04_00_00_00, | |||
/// <summary> | |||
/// Allows for modification of other users nicknames. | |||
/// </summary> | |||
ManageNicknames = 0x08_00_00_00, | |||
ManageNicknames = 0x08_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of roles. | |||
/// </summary> | |||
@@ -158,7 +158,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageRoles = 0x10_00_00_00, | |||
ManageRoles = 0x10_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of webhooks. | |||
/// </summary> | |||
@@ -166,7 +166,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageWebhooks = 0x20_00_00_00, | |||
ManageWebhooks = 0x20_00_00_00, | |||
/// <summary> | |||
/// Allows management and editing of emojis and stickers. | |||
/// </summary> | |||
@@ -182,7 +182,7 @@ namespace Discord | |||
/// <summary> | |||
/// Allows for requesting to speak in stage channels. | |||
/// </summary> | |||
RequestToSpeak = 0x01_00_00_00_00, | |||
RequestToSpeak = 0x01_00_00_00_00, | |||
/// <summary> | |||
/// Allows for creating, editing, and deleting guild scheduled events. | |||
/// </summary> | |||
@@ -194,7 +194,7 @@ namespace Discord | |||
/// This permission requires the owner account to use two-factor | |||
/// authentication when used on a guild that has server-wide 2FA enabled. | |||
/// </remarks> | |||
ManageThreads = 0x04_00_00_00_00, | |||
ManageThreads = 0x04_00_00_00_00, | |||
/// <summary> | |||
/// Allows for creating public threads. | |||
/// </summary> | |||
@@ -206,7 +206,7 @@ namespace Discord | |||
/// <summary> | |||
/// Allows the usage of custom stickers from other servers. | |||
/// </summary> | |||
UseExternalStickers = 0x20_00_00_00_00, | |||
UseExternalStickers = 0x20_00_00_00_00, | |||
/// <summary> | |||
/// Allows for sending messages in threads. | |||
/// </summary> | |||
@@ -281,7 +281,7 @@ namespace Discord | |||
manageThreads: manageThreads, | |||
createPublicThreads: createPublicThreads, | |||
createPrivateThreads: createPrivateThreads, | |||
useExternalStickers: useExternalStickers, | |||
useExternalStickers: useExternalStickers, | |||
sendMessagesInThreads: sendMessagesInThreads, | |||
startEmbeddedActivities: startEmbeddedActivities, | |||
moderateMembers: moderateMembers) | |||
@@ -19,7 +19,7 @@ namespace Discord | |||
/// Gets a <see cref="OverwritePermissions" /> that grants all permissions for the given channel. | |||
/// </summary> | |||
/// <exception cref="ArgumentException">Unknown channel type.</exception> | |||
public static OverwritePermissions AllowAll(IChannel channel) | |||
public static OverwritePermissions AllowAll(IChannel channel) | |||
=> new OverwritePermissions(ChannelPermissions.All(channel).RawValue, 0); | |||
/// <summary> | |||
/// Gets a <see cref="OverwritePermissions" /> that denies all permissions for the given channel. | |||
@@ -116,24 +116,24 @@ namespace Discord | |||
private OverwritePermissions(ulong allowValue, ulong denyValue, | |||
PermValue? createInstantInvite = null, | |||
PermValue? manageChannel = null, | |||
PermValue? manageChannel = null, | |||
PermValue? addReactions = null, | |||
PermValue? viewChannel = null, | |||
PermValue? sendMessages = null, | |||
PermValue? sendTTSMessages = null, | |||
PermValue? manageMessages = null, | |||
PermValue? manageMessages = null, | |||
PermValue? embedLinks = null, | |||
PermValue? attachFiles = null, | |||
PermValue? readMessageHistory = null, | |||
PermValue? mentionEveryone = null, | |||
PermValue? mentionEveryone = null, | |||
PermValue? useExternalEmojis = null, | |||
PermValue? connect = null, | |||
PermValue? speak = null, | |||
PermValue? muteMembers = null, | |||
PermValue? muteMembers = null, | |||
PermValue? deafenMembers = null, | |||
PermValue? moveMembers = null, | |||
PermValue? useVoiceActivation = null, | |||
PermValue? manageRoles = null, | |||
PermValue? manageRoles = null, | |||
PermValue? manageWebhooks = null, | |||
PermValue? prioritySpeaker = null, | |||
PermValue? stream = null, | |||
@@ -194,7 +194,7 @@ namespace Discord | |||
PermValue viewChannel = PermValue.Inherit, | |||
PermValue sendMessages = PermValue.Inherit, | |||
PermValue sendTTSMessages = PermValue.Inherit, | |||
PermValue manageMessages = PermValue.Inherit, | |||
PermValue manageMessages = PermValue.Inherit, | |||
PermValue embedLinks = PermValue.Inherit, | |||
PermValue attachFiles = PermValue.Inherit, | |||
PermValue readMessageHistory = PermValue.Inherit, | |||
@@ -221,11 +221,12 @@ namespace Discord | |||
PermValue useExternalStickers = PermValue.Inherit, | |||
PermValue sendMessagesInThreads = PermValue.Inherit, | |||
PermValue startEmbeddedActivities = PermValue.Inherit) | |||
: this(0, 0, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages, | |||
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, | |||
: this(0, 0, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages, | |||
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, | |||
moveMembers, useVoiceActivation, manageRoles, manageWebhooks, prioritySpeaker, stream, useSlashCommands, useApplicationCommands, | |||
requestToSpeak, manageThreads, createPublicThreads, createPrivateThreads, usePublicThreads, usePrivateThreads, useExternalStickers, | |||
sendMessagesInThreads, startEmbeddedActivities) { } | |||
sendMessagesInThreads, startEmbeddedActivities) | |||
{ } | |||
/// <summary> | |||
/// Initializes a new <see cref="OverwritePermissions" /> from the current one, changing the provided | |||
@@ -238,11 +239,11 @@ namespace Discord | |||
PermValue? viewChannel = null, | |||
PermValue? sendMessages = null, | |||
PermValue? sendTTSMessages = null, | |||
PermValue? manageMessages = null, | |||
PermValue? manageMessages = null, | |||
PermValue? embedLinks = null, | |||
PermValue? attachFiles = null, | |||
PermValue? readMessageHistory = null, | |||
PermValue? mentionEveryone = null, | |||
PermValue? mentionEveryone = null, | |||
PermValue? useExternalEmojis = null, | |||
PermValue? connect = null, | |||
PermValue? speak = null, | |||
@@ -265,8 +266,8 @@ namespace Discord | |||
PermValue? useExternalStickers = null, | |||
PermValue? sendMessagesInThreads = null, | |||
PermValue? startEmbeddedActivities = null) | |||
=> new OverwritePermissions(AllowValue, DenyValue, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages, | |||
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, | |||
=> new OverwritePermissions(AllowValue, DenyValue, createInstantInvite, manageChannel, addReactions, viewChannel, sendMessages, sendTTSMessages, manageMessages, | |||
embedLinks, attachFiles, readMessageHistory, mentionEveryone, useExternalEmojis, connect, speak, muteMembers, deafenMembers, | |||
moveMembers, useVoiceActivation, manageRoles, manageWebhooks, prioritySpeaker, stream, useSlashCommands, useApplicationCommands, | |||
requestToSpeak, manageThreads, createPublicThreads, createPrivateThreads, usePublicThreads, usePrivateThreads, useExternalStickers, | |||
sendMessagesInThreads, startEmbeddedActivities); | |||
@@ -305,7 +306,7 @@ namespace Discord | |||
} | |||
public override string ToString() => $"Allow {AllowValue}, Deny {DenyValue}"; | |||
private string DebuggerDisplay => | |||
private string DebuggerDisplay => | |||
$"Allow {string.Join(", ", ToAllowList())}, " + | |||
$"Deny {string.Join(", ", ToDenyList())}"; | |||
} | |||
@@ -10,7 +10,7 @@ namespace Discord | |||
/// <summary> | |||
/// Gets the identifier of this user's avatar. | |||
/// </summary> | |||
string AvatarId { get; } | |||
string AvatarId { get; } | |||
/// <summary> | |||
/// Gets the avatar URL for this user. | |||
/// </summary> | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
@@ -1,7 +1,7 @@ | |||
using System; | |||
using System.Threading.Tasks; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Threading.Tasks; | |||
namespace Discord | |||
{ | |||
@@ -80,7 +80,7 @@ namespace Discord | |||
return result.ToString(); | |||
} | |||
/// <summary> | |||
/// Formats a string as a block quote. | |||
/// </summary> | |||
@@ -34,7 +34,7 @@ namespace Discord.Logging | |||
try | |||
{ | |||
if (severity <= Level) | |||
await _messageEvent.InvokeAsync(new LogMessage(severity, source, message, ex)).ConfigureAwait(false); | |||
await _messageEvent.InvokeAsync(new LogMessage(severity, source, message, ex)).ConfigureAwait(false); | |||
} | |||
catch | |||
{ | |||
@@ -52,7 +52,7 @@ namespace Discord | |||
Message = message; | |||
Exception = exception; | |||
} | |||
public override string ToString() => ToString(); | |||
public string ToString(StringBuilder builder = null, bool fullException = true, bool prependTimestamp = true, DateTimeKind timestampKind = DateTimeKind.Local, int? padSource = 11) | |||
{ | |||
@@ -60,9 +60,9 @@ namespace Discord | |||
string message = Message; | |||
string exMessage = fullException ? Exception?.ToString() : Exception?.Message; | |||
int maxLength = 1 + | |||
int maxLength = 1 + | |||
(prependTimestamp ? 8 : 0) + 1 + | |||
(padSource.HasValue ? padSource.Value : sourceName?.Length ?? 0) + 1 + | |||
(padSource.HasValue ? padSource.Value : sourceName?.Length ?? 0) + 1 + | |||
(message?.Length ?? 0) + | |||
(exMessage?.Length ?? 0) + 3; | |||
@@ -9,7 +9,7 @@ namespace Discord.Net | |||
public ApplicationCommandException(HttpException httpError) | |||
: base(httpError.HttpCode, httpError.Request, httpError.DiscordCode, httpError.Reason, httpError.Errors.ToArray()) | |||
{ | |||
} | |||
} | |||
} |
@@ -99,7 +99,7 @@ namespace Discord.Net | |||
=> Equals(obj as BucketId); | |||
public override int GetHashCode() | |||
=> IsHashBucket ? (BucketHash, string.Join("/", MajorParameters.Select(x => x.Value))).GetHashCode() : (HttpMethod, Endpoint).GetHashCode(); | |||
=> IsHashBucket ? (BucketHash, string.Join("/", MajorParameters.Select(x => x.Value))).GetHashCode() : (HttpMethod, Endpoint).GetHashCode(); | |||
public override string ToString() | |||
=> GetBucketHash() ?? GetUniqueEndpoint(); | |||
@@ -113,6 +113,6 @@ namespace Discord.Net | |||
if (GetType() != other.GetType()) | |||
return false; | |||
return ToString() == other.ToString(); | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
namespace Discord.Net.Rest | |||
namespace Discord.Net.Rest | |||
{ | |||
public delegate IRestClient RestClientProvider(string baseUrl); | |||
} |
@@ -1,4 +1,4 @@ | |||
using System.Collections.Generic; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Net; | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord.Net.Udp | |||
namespace Discord.Net.Udp | |||
{ | |||
public delegate IUdpSocket UdpSocketProvider(); | |||
} |
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord.Net.WebSockets | |||
namespace Discord.Net.WebSockets | |||
{ | |||
public delegate IWebSocketClient WebSocketProvider(); | |||
} |
@@ -48,17 +48,17 @@ namespace Discord | |||
/// to all actions. | |||
/// </remarks> | |||
public string AuditLogReason { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether or not this request should use the system | |||
/// clock for rate-limiting. Defaults to <c>true</c>. | |||
/// </summary> | |||
/// <remarks> | |||
/// This property can also be set in <see cref="DiscordConfig"/>. | |||
/// On a per-request basis, the system clock should only be disabled | |||
/// when millisecond precision is especially important, and the | |||
/// hosting system is known to have a desynced clock. | |||
/// </remarks> | |||
public bool? UseSystemClock { get; set; } | |||
/// <summary> | |||
/// Gets or sets whether or not this request should use the system | |||
/// clock for rate-limiting. Defaults to <c>true</c>. | |||
/// </summary> | |||
/// <remarks> | |||
/// This property can also be set in <see cref="DiscordConfig"/>. | |||
/// On a per-request basis, the system clock should only be disabled | |||
/// when millisecond precision is especially important, and the | |||
/// hosting system is known to have a desynced clock. | |||
/// </remarks> | |||
public bool? UseSystemClock { get; set; } | |||
/// <summary> | |||
/// Gets or sets the callback to execute regarding ratelimits for this request. | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Threading.Tasks; | |||
@@ -34,7 +34,7 @@ namespace Discord | |||
} | |||
internal static class EventExtensions | |||
{ | |||
{ | |||
public static async Task InvokeAsync(this AsyncEvent<Func<Task>> eventHandler) | |||
{ | |||
var subscribers = eventHandler.Subscriptions; | |||
@@ -30,7 +30,7 @@ namespace Discord | |||
public TEntity Value { get; } | |||
private Func<Task<TEntity>> DownloadFunc { get; } | |||
internal Cacheable(TEntity value, TId id, bool hasValue , Func<Task<TEntity>> downloadFunc) | |||
internal Cacheable(TEntity value, TId id, bool hasValue, Func<Task<TEntity>> downloadFunc) | |||
{ | |||
Value = value; | |||
Id = id; | |||
@@ -38,9 +38,9 @@ namespace Discord | |||
return (x, y) switch | |||
{ | |||
(null, null) => true, | |||
(null, _) => false, | |||
(_, null) => false, | |||
_ => x.Id.Equals(y.Id) | |||
(null, _) => false, | |||
(_, null) => false, | |||
_ => x.Id.Equals(y.Id) | |||
}; | |||
} | |||
@@ -79,9 +79,9 @@ namespace Discord | |||
private static int DefaultConcurrencyLevel => ConcurrentHashSet.DefaultConcurrencyLevel; | |||
private volatile Tables _tables; | |||
private readonly IEqualityComparer<T> _comparer; | |||
private readonly IEqualityComparer<T> _comparer; | |||
private readonly bool _growLockArray; | |||
private int _budget; | |||
private int _budget; | |||
public int Count | |||
{ | |||
@@ -149,19 +149,20 @@ namespace Discord | |||
} | |||
} | |||
public ConcurrentHashSet() | |||
public ConcurrentHashSet() | |||
: this(DefaultConcurrencyLevel, DefaultCapacity, true, EqualityComparer<T>.Default) { } | |||
public ConcurrentHashSet(int concurrencyLevel, int capacity) | |||
public ConcurrentHashSet(int concurrencyLevel, int capacity) | |||
: this(concurrencyLevel, capacity, false, EqualityComparer<T>.Default) { } | |||
public ConcurrentHashSet(IEnumerable<T> collection) | |||
public ConcurrentHashSet(IEnumerable<T> collection) | |||
: this(collection, EqualityComparer<T>.Default) { } | |||
public ConcurrentHashSet(IEqualityComparer<T> comparer) | |||
public ConcurrentHashSet(IEqualityComparer<T> comparer) | |||
: this(DefaultConcurrencyLevel, DefaultCapacity, true, comparer) { } | |||
/// <exception cref="ArgumentNullException"><paramref name="collection"/> is <c>null</c></exception> | |||
public ConcurrentHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer) | |||
public ConcurrentHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer) | |||
: this(comparer) | |||
{ | |||
if (collection == null) throw new ArgumentNullException(paramName: nameof(collection)); | |||
if (collection == null) | |||
throw new ArgumentNullException(paramName: nameof(collection)); | |||
InitializeFromCollection(collection); | |||
} | |||
/// <exception cref="ArgumentNullException"> | |||
@@ -170,18 +171,23 @@ namespace Discord | |||
public ConcurrentHashSet(int concurrencyLevel, IEnumerable<T> collection, IEqualityComparer<T> comparer) | |||
: this(concurrencyLevel, DefaultCapacity, false, comparer) | |||
{ | |||
if (collection == null) throw new ArgumentNullException(paramName: nameof(collection)); | |||
if (comparer == null) throw new ArgumentNullException(paramName: nameof(comparer)); | |||
if (collection == null) | |||
throw new ArgumentNullException(paramName: nameof(collection)); | |||
if (comparer == null) | |||
throw new ArgumentNullException(paramName: nameof(comparer)); | |||
InitializeFromCollection(collection); | |||
} | |||
} | |||
public ConcurrentHashSet(int concurrencyLevel, int capacity, IEqualityComparer<T> comparer) | |||
: this(concurrencyLevel, capacity, false, comparer) { } | |||
internal ConcurrentHashSet(int concurrencyLevel, int capacity, bool growLockArray, IEqualityComparer<T> comparer) | |||
{ | |||
if (concurrencyLevel < 1) throw new ArgumentOutOfRangeException(paramName: nameof(concurrencyLevel)); | |||
if (capacity < 0) throw new ArgumentOutOfRangeException(paramName: nameof(capacity)); | |||
if (comparer == null) throw new ArgumentNullException(paramName: nameof(comparer)); | |||
if (concurrencyLevel < 1) | |||
throw new ArgumentOutOfRangeException(paramName: nameof(concurrencyLevel)); | |||
if (capacity < 0) | |||
throw new ArgumentOutOfRangeException(paramName: nameof(capacity)); | |||
if (comparer == null) | |||
throw new ArgumentNullException(paramName: nameof(comparer)); | |||
if (capacity < concurrencyLevel) | |||
capacity = concurrencyLevel; | |||
@@ -201,7 +207,8 @@ namespace Discord | |||
{ | |||
foreach (var value in collection) | |||
{ | |||
if (value == null) throw new ArgumentNullException(paramName: "key"); | |||
if (value == null) | |||
throw new ArgumentNullException(paramName: "key"); | |||
if (!TryAddInternal(value, _comparer.GetHashCode(value), false)) | |||
throw new ArgumentException(); | |||
@@ -213,7 +220,8 @@ namespace Discord | |||
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c></exception> | |||
public bool ContainsKey(T value) | |||
{ | |||
if (value == null) throw new ArgumentNullException(paramName: "key"); | |||
if (value == null) | |||
throw new ArgumentNullException(paramName: "key"); | |||
return ContainsKeyInternal(value, _comparer.GetHashCode(value)); | |||
} | |||
private bool ContainsKeyInternal(T value, int hashcode) | |||
@@ -221,7 +229,7 @@ namespace Discord | |||
Tables tables = _tables; | |||
int bucketNo = GetBucket(hashcode, tables._buckets.Length); | |||
Node n = Volatile.Read(ref tables._buckets[bucketNo]); | |||
while (n != null) | |||
@@ -230,14 +238,15 @@ namespace Discord | |||
return true; | |||
n = n._next; | |||
} | |||
return false; | |||
} | |||
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c></exception> | |||
public bool TryAdd(T value) | |||
{ | |||
if (value == null) throw new ArgumentNullException(paramName: "key"); | |||
if (value == null) | |||
throw new ArgumentNullException(paramName: "key"); | |||
return TryAddInternal(value, _comparer.GetHashCode(value), true); | |||
} | |||
private bool TryAddInternal(T value, int hashcode, bool acquireLock) | |||
@@ -266,7 +275,8 @@ namespace Discord | |||
} | |||
Volatile.Write(ref tables._buckets[bucketNo], new Node(value, hashcode, tables._buckets[bucketNo])); | |||
checked { tables._countPerLock[lockNo]++; } | |||
checked | |||
{ tables._countPerLock[lockNo]++; } | |||
if (tables._countPerLock[lockNo] > _budget) | |||
resizeDesired = true; | |||
@@ -279,7 +289,7 @@ namespace Discord | |||
if (resizeDesired) | |||
GrowTable(tables); | |||
return true; | |||
} | |||
} | |||
@@ -287,9 +297,10 @@ namespace Discord | |||
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c></exception> | |||
public bool TryRemove(T value) | |||
{ | |||
if (value == null) throw new ArgumentNullException(paramName: "key"); | |||
if (value == null) | |||
throw new ArgumentNullException(paramName: "key"); | |||
return TryRemoveInternal(value); | |||
} | |||
} | |||
private bool TryRemoveInternal(T value) | |||
{ | |||
int hashcode = _comparer.GetHashCode(value); | |||
@@ -325,7 +336,7 @@ namespace Discord | |||
return false; | |||
} | |||
} | |||
public void Clear() | |||
{ | |||
int locksAcquired = 0; | |||
@@ -342,7 +353,7 @@ namespace Discord | |||
ReleaseLocks(0, locksAcquired); | |||
} | |||
} | |||
public IEnumerator<T> GetEnumerator() | |||
{ | |||
Node[] buckets = _tables._buckets; | |||
@@ -432,7 +443,8 @@ namespace Discord | |||
newBuckets[newBucketNo] = new Node(current._value, current._hashcode, newBuckets[newBucketNo]); | |||
checked { newCountPerLock[newLockNo]++; } | |||
checked | |||
{ newCountPerLock[newLockNo]++; } | |||
current = next; | |||
} | |||
@@ -471,6 +483,6 @@ namespace Discord | |||
{ | |||
for (int i = fromInclusive; i < toExclusive; i++) | |||
Monitor.Exit(_tables._locks[i]); | |||
} | |||
} | |||
} | |||
} |
@@ -61,7 +61,7 @@ namespace Discord | |||
text = text.Substring(3, text.Length - 4); //<@!123> | |||
else | |||
text = text.Substring(2, text.Length - 3); //<@123> | |||
if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out userId)) | |||
return true; | |||
} | |||
@@ -87,7 +87,7 @@ namespace Discord | |||
if (text.Length >= 3 && text[0] == '<' && text[1] == '#' && text[text.Length - 1] == '>') | |||
{ | |||
text = text.Substring(2, text.Length - 3); //<#123> | |||
if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out channelId)) | |||
return true; | |||
} | |||
@@ -113,7 +113,7 @@ namespace Discord | |||
if (text.Length >= 4 && text[0] == '<' && text[1] == '@' && text[2] == '&' && text[text.Length - 1] == '>') | |||
{ | |||
text = text.Substring(3, text.Length - 4); //<@&123> | |||
if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out roleId)) | |||
return true; | |||
} | |||
@@ -136,27 +136,33 @@ namespace Discord | |||
switch (tag.Type) | |||
{ | |||
case TagType.UserMention: | |||
if (userHandling == TagHandling.Ignore) continue; | |||
if (userHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveUserMention(tag, userHandling); | |||
break; | |||
case TagType.ChannelMention: | |||
if (channelHandling == TagHandling.Ignore) continue; | |||
if (channelHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveChannelMention(tag, channelHandling); | |||
break; | |||
case TagType.RoleMention: | |||
if (roleHandling == TagHandling.Ignore) continue; | |||
if (roleHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveRoleMention(tag, roleHandling); | |||
break; | |||
case TagType.EveryoneMention: | |||
if (everyoneHandling == TagHandling.Ignore) continue; | |||
if (everyoneHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveEveryoneMention(tag, everyoneHandling); | |||
break; | |||
case TagType.HereMention: | |||
if (everyoneHandling == TagHandling.Ignore) continue; | |||
if (everyoneHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveHereMention(tag, everyoneHandling); | |||
break; | |||
case TagType.Emoji: | |||
if (emojiHandling == TagHandling.Ignore) continue; | |||
if (emojiHandling == TagHandling.Ignore) | |||
continue; | |||
newText = ResolveEmoji(tag, emojiHandling); | |||
break; | |||
} | |||
@@ -36,8 +36,10 @@ namespace Discord | |||
public override bool Equals(object other) | |||
{ | |||
if (!IsSpecified) return other == null; | |||
if (other == null) return false; | |||
if (!IsSpecified) | |||
return other == null; | |||
if (other == null) | |||
return false; | |||
return _value.Equals(other); | |||
} | |||
public override int GetHashCode() => IsSpecified ? _value.GetHashCode() : 0; | |||
@@ -1,4 +1,4 @@ | |||
using System.Collections; | |||
using System.Collections; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -1,4 +1,4 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
internal class PageInfo | |||
{ | |||
@@ -72,7 +72,7 @@ namespace Discord | |||
return true; | |||
} | |||
public ValueTask DisposeAsync() | |||
{ | |||
Current = null; | |||
@@ -147,7 +147,7 @@ namespace Discord | |||
//Give/Take User permissions | |||
perms = channel.GetPermissionOverwrite(user); | |||
if (perms != null) | |||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | |||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | |||
if (channel is ITextChannel) | |||
{ | |||
@@ -12,8 +12,10 @@ namespace Discord | |||
private static ArgumentNullException CreateNotNullException(string name, string msg) | |||
{ | |||
if (msg == null) return new ArgumentNullException(paramName: name); | |||
else return new ArgumentNullException(paramName: name, message: msg); | |||
if (msg == null) | |||
return new ArgumentNullException(paramName: name); | |||
else | |||
return new ArgumentNullException(paramName: name, message: msg); | |||
} | |||
#endregion | |||
@@ -26,8 +28,10 @@ namespace Discord | |||
/// <exception cref="ArgumentNullException"><paramref name="obj"/> must not be <see langword="null"/>.</exception> | |||
public static void NotNullOrEmpty(string obj, string name, string msg = null) | |||
{ | |||
if (obj == null) throw CreateNotNullException(name, msg); | |||
if (obj.Length == 0) throw CreateNotEmptyException(name, msg); | |||
if (obj == null) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Length == 0) | |||
throw CreateNotEmptyException(name, msg); | |||
} | |||
/// <exception cref="ArgumentException"><paramref name="obj"/> cannot be blank.</exception> | |||
/// <exception cref="ArgumentNullException"><paramref name="obj"/> must not be <see langword="null"/>.</exception> | |||
@@ -35,16 +39,20 @@ namespace Discord | |||
{ | |||
if (obj.IsSpecified) | |||
{ | |||
if (obj.Value == null) throw CreateNotNullException(name, msg); | |||
if (obj.Value.Length == 0) throw CreateNotEmptyException(name, msg); | |||
if (obj.Value == null) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Value.Length == 0) | |||
throw CreateNotEmptyException(name, msg); | |||
} | |||
} | |||
/// <exception cref="ArgumentException"><paramref name="obj"/> cannot be blank.</exception> | |||
/// <exception cref="ArgumentNullException"><paramref name="obj"/> must not be <see langword="null"/>.</exception> | |||
public static void NotNullOrWhitespace(string obj, string name, string msg = null) | |||
{ | |||
if (obj == null) throw CreateNotNullException(name, msg); | |||
if (obj.Trim().Length == 0) throw CreateNotEmptyException(name, msg); | |||
if (obj == null) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Trim().Length == 0) | |||
throw CreateNotEmptyException(name, msg); | |||
} | |||
/// <exception cref="ArgumentException"><paramref name="obj"/> cannot be blank.</exception> | |||
/// <exception cref="ArgumentNullException"><paramref name="obj"/> must not be <see langword="null"/>.</exception> | |||
@@ -52,8 +60,10 @@ namespace Discord | |||
{ | |||
if (obj.IsSpecified) | |||
{ | |||
if (obj.Value == null) throw CreateNotNullException(name, msg); | |||
if (obj.Value.Trim().Length == 0) throw CreateNotEmptyException(name, msg); | |||
if (obj.Value == null) | |||
throw CreateNotNullException(name, msg); | |||
if (obj.Value.Trim().Length == 0) | |||
throw CreateNotEmptyException(name, msg); | |||
} | |||
} | |||
@@ -282,7 +292,8 @@ namespace Discord | |||
var minimum = SnowflakeUtils.ToSnowflake(DateTimeOffset.UtcNow.Subtract(TimeSpan.FromDays(14))); | |||
for (var i = 0; i < collection.Length; i++) | |||
{ | |||
if (collection[i] == 0) continue; | |||
if (collection[i] == 0) | |||
continue; | |||
if (collection[i] <= minimum) | |||
throw new ArgumentOutOfRangeException(name, "Messages must be younger than two weeks old."); | |||
} | |||
@@ -19,7 +19,7 @@ namespace Discord.Interactions | |||
/// Specify the target channel types for a <see cref="ApplicationCommandOptionType.Channel"/> option. | |||
/// </summary> | |||
/// <param name="channelTypes">The allowed channel types for this option.</param> | |||
public ChannelTypesAttribute (params ChannelType[] channelTypes) | |||
public ChannelTypesAttribute(params ChannelType[] channelTypes) | |||
{ | |||
if (channelTypes is null) | |||
throw new ArgumentNullException(nameof(channelTypes)); | |||
@@ -23,7 +23,7 @@ namespace Discord.Interactions | |||
/// </summary> | |||
public object Value { get; } | |||
private ChoiceAttribute (string name) | |||
private ChoiceAttribute(string name) | |||
{ | |||
Name = name; | |||
} | |||
@@ -33,7 +33,7 @@ namespace Discord.Interactions | |||
/// </summary> | |||
/// <param name="name">Name of the choice.</param> | |||
/// <param name="value">Predefined value of the choice.</param> | |||
public ChoiceAttribute (string name, string value) : this(name) | |||
public ChoiceAttribute(string name, string value) : this(name) | |||
{ | |||
Type = SlashCommandChoiceType.String; | |||
Value = value; | |||
@@ -44,7 +44,7 @@ namespace Discord.Interactions | |||
/// </summary> | |||
/// <param name="name">Name of the choice.</param> | |||
/// <param name="value">Predefined value of the choice.</param> | |||
public ChoiceAttribute (string name, int value) : this(name) | |||
public ChoiceAttribute(string name, int value) : this(name) | |||
{ | |||
Type = SlashCommandChoiceType.Integer; | |||
Value = value; | |||
@@ -55,7 +55,7 @@ namespace Discord.Interactions | |||
/// </summary> | |||
/// <param name="name">Name of the choice.</param> | |||
/// <param name="value">Predefined value of the choice.</param> | |||
public ChoiceAttribute (string name, double value) : this(name) | |||
public ChoiceAttribute(string name, double value) : this(name) | |||
{ | |||
Type = SlashCommandChoiceType.Number; | |||
Value = value; | |||
@@ -43,7 +43,7 @@ namespace Discord.Interactions | |||
/// <param name="customId">String to compare the Message Component CustomIDs with.</param> | |||
/// <param name="ignoreGroupNames">If <see langword="true"/> <see cref="GroupAttribute"/>s will be ignored while creating this command and this method will be treated as a top level command.</param> | |||
/// <param name="runMode">Set the run mode of the command.</param> | |||
public ComponentInteractionAttribute (string customId, bool ignoreGroupNames = false, RunMode runMode = RunMode.Default) | |||
public ComponentInteractionAttribute(string customId, bool ignoreGroupNames = false, RunMode runMode = RunMode.Default) | |||
{ | |||
CustomId = customId; | |||
IgnoreGroupNames = ignoreGroupNames; | |||
@@ -24,13 +24,13 @@ namespace Discord.Interactions | |||
/// </summary> | |||
public RunMode RunMode { get; } | |||
internal ContextCommandAttribute (string name, ApplicationCommandType commandType, RunMode runMode = RunMode.Default) | |||
internal ContextCommandAttribute(string name, ApplicationCommandType commandType, RunMode runMode = RunMode.Default) | |||
{ | |||
Name = name; | |||
CommandType = commandType; | |||
RunMode = runMode; | |||
} | |||
internal virtual void CheckMethodDefinition (MethodInfo methodInfo) { } | |||
internal virtual void CheckMethodDefinition(MethodInfo methodInfo) { } | |||
} | |||
} |
@@ -16,9 +16,9 @@ namespace Discord.Interactions | |||
/// Register a method as a Message Context Command. | |||
/// </summary> | |||
/// <param name="name">Name of the context command.</param> | |||
public MessageCommandAttribute (string name) : base(name, ApplicationCommandType.Message) { } | |||
public MessageCommandAttribute(string name) : base(name, ApplicationCommandType.Message) { } | |||
internal override void CheckMethodDefinition (MethodInfo methodInfo) | |||
internal override void CheckMethodDefinition(MethodInfo methodInfo) | |||
{ | |||
var parameters = methodInfo.GetParameters(); | |||
@@ -17,7 +17,7 @@ namespace Discord.Interactions | |||
/// Gets the string to compare the Modal CustomIDs with. | |||
/// </summary> | |||
public string CustomId { get; } | |||
/// <summary> | |||
/// Gets <see langword="true"/> if <see cref="GroupAttribute"/>s will be ignored while creating this command and this method will be treated as a top level command. | |||
/// </summary> | |||
@@ -38,7 +38,7 @@ namespace Discord.Interactions | |||
/// <param name="description">Description of the command.</param> | |||
/// <param name="ignoreGroupNames"> If <see langword="true"/>, <see cref="GroupAttribute"/>s will be ignored while creating this command and this method will be treated as a top level command.</param> | |||
/// <param name="runMode">Set the run mode of the command.</param> | |||
public SlashCommandAttribute (string name, string description, bool ignoreGroupNames = false, RunMode runMode = RunMode.Default) | |||
public SlashCommandAttribute(string name, string description, bool ignoreGroupNames = false, RunMode runMode = RunMode.Default) | |||
{ | |||
Name = name; | |||
Description = description; | |||