* Change all Select(... as ...) to OfType
* Add changes according to 194a8aa427
tags/2.0
| @@ -7,13 +7,13 @@ namespace Discord.Commands | |||||
| [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] | [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] | ||||
| public class OverrideTypeReaderAttribute : Attribute | public class OverrideTypeReaderAttribute : Attribute | ||||
| { | { | ||||
| private static readonly TypeInfo _typeReaderTypeInfo = typeof(TypeReader).GetTypeInfo(); | |||||
| private static readonly TypeInfo TypeReaderTypeInfo = typeof(TypeReader).GetTypeInfo(); | |||||
| public Type TypeReader { get; } | public Type TypeReader { get; } | ||||
| public OverrideTypeReaderAttribute(Type overridenTypeReader) | public OverrideTypeReaderAttribute(Type overridenTypeReader) | ||||
| { | { | ||||
| if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) | |||||
| if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) | |||||
| throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}"); | throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}"); | ||||
| TypeReader = overridenTypeReader; | TypeReader = overridenTypeReader; | ||||
| @@ -10,7 +10,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| internal static class ModuleClassBuilder | internal static class ModuleClassBuilder | ||||
| { | { | ||||
| private static readonly TypeInfo _moduleTypeInfo = typeof(IModuleBase).GetTypeInfo(); | |||||
| private static readonly TypeInfo ModuleTypeInfo = typeof(IModuleBase).GetTypeInfo(); | |||||
| public static async Task<IReadOnlyList<TypeInfo>> SearchAsync(Assembly assembly, CommandService service) | public static async Task<IReadOnlyList<TypeInfo>> SearchAsync(Assembly assembly, CommandService service) | ||||
| { | { | ||||
| @@ -135,7 +135,7 @@ namespace Discord.Commands | |||||
| if (builder.Name == null) | if (builder.Name == null) | ||||
| builder.Name = typeInfo.Name; | builder.Name = typeInfo.Name; | ||||
| var validCommands = typeInfo.DeclaredMethods.Where(x => IsValidCommandDefinition(x)); | |||||
| var validCommands = typeInfo.DeclaredMethods.Where(IsValidCommandDefinition); | |||||
| foreach (var method in validCommands) | foreach (var method in validCommands) | ||||
| { | { | ||||
| @@ -299,7 +299,7 @@ namespace Discord.Commands | |||||
| private static bool IsValidModuleDefinition(TypeInfo typeInfo) | private static bool IsValidModuleDefinition(TypeInfo typeInfo) | ||||
| { | { | ||||
| return _moduleTypeInfo.IsAssignableFrom(typeInfo) && | |||||
| return ModuleTypeInfo.IsAssignableFrom(typeInfo) && | |||||
| !typeInfo.IsAbstract && | !typeInfo.IsAbstract && | ||||
| !typeInfo.ContainsGenericParameters; | !typeInfo.ContainsGenericParameters; | ||||
| } | } | ||||
| @@ -118,7 +118,7 @@ namespace Discord.Commands | |||||
| var typeInfo = type.GetTypeInfo(); | var typeInfo = type.GetTypeInfo(); | ||||
| if (_typedModuleDefs.ContainsKey(type)) | if (_typedModuleDefs.ContainsKey(type)) | ||||
| throw new ArgumentException($"This module has already been added."); | |||||
| throw new ArgumentException("This module has already been added."); | |||||
| var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault(); | var module = (await ModuleClassBuilder.BuildAsync(this, services, typeInfo).ConfigureAwait(false)).FirstOrDefault(); | ||||
| @@ -241,7 +241,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| if (_defaultTypeReaders.ContainsKey(type)) | if (_defaultTypeReaders.ContainsKey(type)) | ||||
| _ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." + | _ = _cmdLogger.WarningAsync($"The default TypeReader for {type.FullName} was replaced by {reader.GetType().FullName}." + | ||||
| $"To suppress this message, use AddTypeReader<T>(reader, true)."); | |||||
| "To suppress this message, use AddTypeReader<T>(reader, true)."); | |||||
| AddTypeReader(type, reader, true); | AddTypeReader(type, reader, true); | ||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -1,4 +1,4 @@ | |||||
| using Discord.Commands.Builders; | |||||
| using Discord.Commands.Builders; | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| @@ -63,7 +63,7 @@ namespace Discord.Commands | |||||
| Attributes = builder.Attributes.ToImmutableArray(); | Attributes = builder.Attributes.ToImmutableArray(); | ||||
| Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); | Parameters = builder.Parameters.Select(x => x.Build(this)).ToImmutableArray(); | ||||
| HasVarArgs = builder.Parameters.Count > 0 ? builder.Parameters[builder.Parameters.Count - 1].IsMultiple : false; | |||||
| HasVarArgs = builder.Parameters.Count > 0 && builder.Parameters[builder.Parameters.Count - 1].IsMultiple; | |||||
| IgnoreExtraArgs = builder.IgnoreExtraArgs; | IgnoreExtraArgs = builder.IgnoreExtraArgs; | ||||
| _action = builder.Callback; | _action = builder.Callback; | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System.Collections.Generic; | |||||
| using System.Collections.Generic; | |||||
| namespace Discord.Commands | namespace Discord.Commands | ||||
| { | { | ||||
| @@ -6,7 +6,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| private readonly CommandService _service; | private readonly CommandService _service; | ||||
| private readonly CommandMapNode _root; | private readonly CommandMapNode _root; | ||||
| private static readonly string[] _blankAliases = new[] { "" }; | |||||
| private static readonly string[] BlankAliases = { "" }; | |||||
| public CommandMap(CommandService service) | public CommandMap(CommandService service) | ||||
| { | { | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| @@ -7,7 +7,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| internal class CommandMapNode | internal class CommandMapNode | ||||
| { | { | ||||
| private static readonly char[] _whitespaceChars = new[] { ' ', '\r', '\n' }; | |||||
| private static readonly char[] WhitespaceChars = { ' ', '\r', '\n' }; | |||||
| private readonly ConcurrentDictionary<string, CommandMapNode> _nodes; | private readonly ConcurrentDictionary<string, CommandMapNode> _nodes; | ||||
| private readonly string _name; | private readonly string _name; | ||||
| @@ -52,7 +52,6 @@ namespace Discord.Commands | |||||
| public void RemoveCommand(CommandService service, string text, int index, CommandInfo command) | public void RemoveCommand(CommandService service, string text, int index, CommandInfo command) | ||||
| { | { | ||||
| int nextSegment = NextSegment(text, index, service._separatorChar); | int nextSegment = NextSegment(text, index, service._separatorChar); | ||||
| string name; | |||||
| lock (_lockObj) | lock (_lockObj) | ||||
| { | { | ||||
| @@ -60,13 +59,13 @@ namespace Discord.Commands | |||||
| _commands = _commands.Remove(command); | _commands = _commands.Remove(command); | ||||
| else | else | ||||
| { | { | ||||
| string name; | |||||
| if (nextSegment == -1) | if (nextSegment == -1) | ||||
| name = text.Substring(index); | name = text.Substring(index); | ||||
| else | else | ||||
| name = text.Substring(index, nextSegment - index); | name = text.Substring(index, nextSegment - index); | ||||
| CommandMapNode nextNode; | |||||
| if (_nodes.TryGetValue(name, out nextNode)) | |||||
| if (_nodes.TryGetValue(name, out var nextNode)) | |||||
| { | { | ||||
| nextNode.RemoveCommand(service, nextSegment == -1 ? "" : text, nextSegment + 1, command); | nextNode.RemoveCommand(service, nextSegment == -1 ? "" : text, nextSegment + 1, command); | ||||
| if (nextNode.IsEmpty) | if (nextNode.IsEmpty) | ||||
| @@ -100,7 +99,7 @@ namespace Discord.Commands | |||||
| } | } | ||||
| //Check if this is the last command segment before args | //Check if this is the last command segment before args | ||||
| nextSegment = NextSegment(text, index, _whitespaceChars, service._separatorChar); | |||||
| nextSegment = NextSegment(text, index, WhitespaceChars, service._separatorChar); | |||||
| if (nextSegment != -1) | if (nextSegment != -1) | ||||
| { | { | ||||
| name = text.Substring(index, nextSegment - index); | name = text.Substring(index, nextSegment - index); | ||||
| @@ -8,9 +8,9 @@ namespace Discord.Commands | |||||
| internal static class PrimitiveParsers | internal static class PrimitiveParsers | ||||
| { | { | ||||
| private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> _parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers); | |||||
| private static readonly Lazy<IReadOnlyDictionary<Type, Delegate>> Parsers = new Lazy<IReadOnlyDictionary<Type, Delegate>>(CreateParsers); | |||||
| public static IEnumerable<Type> SupportedTypes = _parsers.Value.Keys; | |||||
| public static IEnumerable<Type> SupportedTypes = Parsers.Value.Keys; | |||||
| static IReadOnlyDictionary<Type, Delegate> CreateParsers() | static IReadOnlyDictionary<Type, Delegate> CreateParsers() | ||||
| { | { | ||||
| @@ -34,7 +34,7 @@ namespace Discord.Commands | |||||
| return parserBuilder.ToImmutable(); | return parserBuilder.ToImmutable(); | ||||
| } | } | ||||
| public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)_parsers.Value[typeof(T)]; | |||||
| public static Delegate Get(Type type) => _parsers.Value[type]; | |||||
| public static TryParseDelegate<T> Get<T>() => (TryParseDelegate<T>)Parsers.Value[typeof(T)]; | |||||
| public static Delegate Get(Type type) => Parsers.Value[type]; | |||||
| } | } | ||||
| } | } | ||||
| @@ -6,8 +6,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| internal class TimeSpanTypeReader : TypeReader | internal class TimeSpanTypeReader : TypeReader | ||||
| { | { | ||||
| private static readonly string[] _formats = new[] | |||||
| { | |||||
| private static readonly string[] Formats = { | |||||
| "%d'd'%h'h'%m'm'%s's'", //4d3h2m1s | "%d'd'%h'h'%m'm'%s's'", //4d3h2m1s | ||||
| "%d'd'%h'h'%m'm'", //4d3h2m | "%d'd'%h'h'%m'm'", //4d3h2m | ||||
| "%d'd'%h'h'%s's'", //4d3h 1s | "%d'd'%h'h'%s's'", //4d3h 1s | ||||
| @@ -27,7 +26,7 @@ namespace Discord.Commands | |||||
| public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services) | public override Task<TypeReaderResult> ReadAsync(ICommandContext context, string input, IServiceProvider services) | ||||
| { | { | ||||
| return (TimeSpan.TryParseExact(input.ToLowerInvariant(), _formats, CultureInfo.InvariantCulture, out var timeSpan)) | |||||
| return (TimeSpan.TryParseExact(input.ToLowerInvariant(), Formats, CultureInfo.InvariantCulture, out var timeSpan)) | |||||
| ? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan)) | ? Task.FromResult(TypeReaderResult.FromSuccess(timeSpan)) | ||||
| : Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan")); | : Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Failed to parse TimeSpan")); | ||||
| } | } | ||||
| @@ -71,8 +71,8 @@ namespace Discord.Commands | |||||
| .Where(x => string.Equals(input, (x as IGuildUser)?.Nickname, StringComparison.OrdinalIgnoreCase)) | .Where(x => string.Equals(input, (x as IGuildUser)?.Nickname, StringComparison.OrdinalIgnoreCase)) | ||||
| .ForEachAsync(channelUser => AddResult(results, channelUser as T, (channelUser as IGuildUser).Nickname == input ? 0.65f : 0.55f)); | .ForEachAsync(channelUser => AddResult(results, channelUser as T, (channelUser as IGuildUser).Nickname == input ? 0.65f : 0.55f)); | ||||
| foreach (var guildUser in guildUsers.Where(x => string.Equals(input, (x as IGuildUser).Nickname, StringComparison.OrdinalIgnoreCase))) | |||||
| AddResult(results, guildUser as T, (guildUser as IGuildUser).Nickname == input ? 0.60f : 0.50f); | |||||
| foreach (var guildUser in guildUsers.Where(x => string.Equals(input, x.Nickname, StringComparison.OrdinalIgnoreCase))) | |||||
| AddResult(results, guildUser as T, guildUser.Nickname == input ? 0.60f : 0.50f); | |||||
| } | } | ||||
| if (results.Count > 0) | if (results.Count > 0) | ||||
| @@ -8,7 +8,7 @@ namespace Discord.Commands | |||||
| { | { | ||||
| internal static class ReflectionUtils | internal static class ReflectionUtils | ||||
| { | { | ||||
| private static readonly TypeInfo _objectTypeInfo = typeof(object).GetTypeInfo(); | |||||
| private static readonly TypeInfo ObjectTypeInfo = typeof(object).GetTypeInfo(); | |||||
| internal static T CreateObject<T>(TypeInfo typeInfo, CommandService commands, IServiceProvider services = null) | internal static T CreateObject<T>(TypeInfo typeInfo, CommandService commands, IServiceProvider services = null) | ||||
| => CreateBuilder<T>(typeInfo, commands)(services); | => CreateBuilder<T>(typeInfo, commands)(services); | ||||
| @@ -54,7 +54,7 @@ namespace Discord.Commands | |||||
| private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType) | private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType) | ||||
| { | { | ||||
| var result = new List<System.Reflection.PropertyInfo>(); | var result = new List<System.Reflection.PropertyInfo>(); | ||||
| while (ownerType != _objectTypeInfo) | |||||
| while (ownerType != ObjectTypeInfo) | |||||
| { | { | ||||
| foreach (var prop in ownerType.DeclaredProperties) | foreach (var prop in ownerType.DeclaredProperties) | ||||
| { | { | ||||
| @@ -239,7 +239,7 @@ namespace Discord | |||||
| get => _name; | get => _name; | ||||
| set | set | ||||
| { | { | ||||
| if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException($"Field name must not be null, empty or entirely whitespace.", nameof(Name)); | |||||
| if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("Field name must not be null, empty or entirely whitespace.", nameof(Name)); | |||||
| if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name)); | if (value.Length > MaxFieldNameLength) throw new ArgumentException($"Field name length must be less than or equal to {MaxFieldNameLength}.", nameof(Name)); | ||||
| _name = value; | _name = value; | ||||
| } | } | ||||
| @@ -251,7 +251,7 @@ namespace Discord | |||||
| set | set | ||||
| { | { | ||||
| var stringValue = value?.ToString(); | var stringValue = value?.ToString(); | ||||
| if (string.IsNullOrEmpty(stringValue)) throw new ArgumentException($"Field value must not be null or empty.", nameof(Value)); | |||||
| if (string.IsNullOrEmpty(stringValue)) throw new ArgumentException("Field value must not be null or empty.", nameof(Value)); | |||||
| if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException($"Field value length must be less than or equal to {MaxFieldValueLength}.", nameof(Value)); | if (stringValue.Length > MaxFieldValueLength) throw new ArgumentException($"Field value length must be less than or equal to {MaxFieldValueLength}.", nameof(Value)); | ||||
| _value = stringValue; | _value = stringValue; | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| namespace Discord | namespace Discord | ||||
| @@ -20,6 +20,6 @@ namespace Discord | |||||
| } | } | ||||
| private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | ||||
| public override string ToString() => Url.ToString(); | |||||
| public override string ToString() => Url; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| namespace Discord | namespace Discord | ||||
| @@ -20,6 +20,6 @@ namespace Discord | |||||
| } | } | ||||
| private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | ||||
| public override string ToString() => Url.ToString(); | |||||
| public override string ToString() => Url; | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| namespace Discord | namespace Discord | ||||
| @@ -18,6 +18,6 @@ namespace Discord | |||||
| } | } | ||||
| private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | private string DebuggerDisplay => $"{Url} ({(Width != null && Height != null ? $"{Width}x{Height}" : "0x0")})"; | ||||
| public override string ToString() => Url.ToString(); | |||||
| public override string ToString() => Url; | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,12 +12,12 @@ namespace Discord | |||||
| public static async Task<IDMChannel> GetDMChannelAsync(this IDiscordClient client, ulong id) | public static async Task<IDMChannel> GetDMChannelAsync(this IDiscordClient client, ulong id) | ||||
| => await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IDMChannel; | => await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IDMChannel; | ||||
| public static async Task<IEnumerable<IDMChannel>> GetDMChannelsAsync(this IDiscordClient client) | public static async Task<IEnumerable<IDMChannel>> GetDMChannelsAsync(this IDiscordClient client) | ||||
| => (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).Select(x => x as IDMChannel).Where(x => x != null); | |||||
| => (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).OfType<IDMChannel>(); | |||||
| public static async Task<IGroupChannel> GetGroupChannelAsync(this IDiscordClient client, ulong id) | public static async Task<IGroupChannel> GetGroupChannelAsync(this IDiscordClient client, ulong id) | ||||
| => await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IGroupChannel; | => await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IGroupChannel; | ||||
| public static async Task<IEnumerable<IGroupChannel>> GetGroupChannelsAsync(this IDiscordClient client) | public static async Task<IEnumerable<IGroupChannel>> GetGroupChannelsAsync(this IDiscordClient client) | ||||
| => (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).Select(x => x as IGroupChannel).Where(x => x != null); | |||||
| => (await client.GetPrivateChannelsAsync().ConfigureAwait(false)).OfType<IGroupChannel>(); | |||||
| public static async Task<IVoiceRegion> GetOptimalVoiceRegionAsync(this IDiscordClient discord) | public static async Task<IVoiceRegion> GetOptimalVoiceRegionAsync(this IDiscordClient discord) | ||||
| { | { | ||||
| @@ -1,9 +1,9 @@ | |||||
| namespace Discord | |||||
| namespace Discord | |||||
| { | { | ||||
| public static class Format | public static class Format | ||||
| { | { | ||||
| // Characters which need escaping | // Characters which need escaping | ||||
| private static string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||||
| private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||||
| /// <summary> Returns a markdown-formatted string with bold formatting. </summary> | /// <summary> Returns a markdown-formatted string with bold formatting. </summary> | ||||
| public static string Bold(string text) => $"**{text}**"; | public static string Bold(string text) => $"**{text}**"; | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Globalization; | using System.Globalization; | ||||
| using System.Text; | using System.Text; | ||||
| @@ -139,22 +139,22 @@ namespace Discord | |||||
| if (user != null) | if (user != null) | ||||
| return $"@{guildUser?.Nickname ?? user?.Username}"; | return $"@{guildUser?.Nickname ?? user?.Username}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.NameNoPrefix: | case TagHandling.NameNoPrefix: | ||||
| if (user != null) | if (user != null) | ||||
| return $"{guildUser?.Nickname ?? user?.Username}"; | return $"{guildUser?.Nickname ?? user?.Username}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.FullName: | case TagHandling.FullName: | ||||
| if (user != null) | if (user != null) | ||||
| return $"@{user.Username}#{user.Discriminator}"; | return $"@{user.Username}#{user.Discriminator}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.FullNameNoPrefix: | case TagHandling.FullNameNoPrefix: | ||||
| if (user != null) | if (user != null) | ||||
| return $"{user.Username}#{user.Discriminator}"; | return $"{user.Username}#{user.Discriminator}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.Sanitize: | case TagHandling.Sanitize: | ||||
| if (guildUser != null && guildUser.Nickname == null) | if (guildUser != null && guildUser.Nickname == null) | ||||
| return MentionUser($"{SanitizeChar}{tag.Key}", false); | return MentionUser($"{SanitizeChar}{tag.Key}", false); | ||||
| @@ -176,13 +176,13 @@ namespace Discord | |||||
| if (channel != null) | if (channel != null) | ||||
| return $"#{channel.Name}"; | return $"#{channel.Name}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.NameNoPrefix: | case TagHandling.NameNoPrefix: | ||||
| case TagHandling.FullNameNoPrefix: | case TagHandling.FullNameNoPrefix: | ||||
| if (channel != null) | if (channel != null) | ||||
| return $"{channel.Name}"; | return $"{channel.Name}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.Sanitize: | case TagHandling.Sanitize: | ||||
| return MentionChannel($"{SanitizeChar}{tag.Key}"); | return MentionChannel($"{SanitizeChar}{tag.Key}"); | ||||
| } | } | ||||
| @@ -201,13 +201,13 @@ namespace Discord | |||||
| if (role != null) | if (role != null) | ||||
| return $"@{role.Name}"; | return $"@{role.Name}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.NameNoPrefix: | case TagHandling.NameNoPrefix: | ||||
| case TagHandling.FullNameNoPrefix: | case TagHandling.FullNameNoPrefix: | ||||
| if (role != null) | if (role != null) | ||||
| return $"{role.Name}"; | return $"{role.Name}"; | ||||
| else | else | ||||
| return $""; | |||||
| return ""; | |||||
| case TagHandling.Sanitize: | case TagHandling.Sanitize: | ||||
| return MentionRole($"{SanitizeChar}{tag.Key}"); | return MentionRole($"{SanitizeChar}{tag.Key}"); | ||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Threading; | using System.Threading; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| @@ -60,7 +60,7 @@ namespace Discord | |||||
| if (Current.Count == 0) | if (Current.Count == 0) | ||||
| _info.Remaining = 0; | _info.Remaining = 0; | ||||
| } | } | ||||
| _info.PageSize = _info.Remaining != null ? (int)Math.Min(_info.Remaining.Value, _source.PageSize) : _source.PageSize; | |||||
| _info.PageSize = _info.Remaining != null ? Math.Min(_info.Remaining.Value, _source.PageSize) : _source.PageSize; | |||||
| if (_info.Remaining != 0) | if (_info.Remaining != 0) | ||||
| { | { | ||||
| @@ -74,4 +74,4 @@ namespace Discord | |||||
| public void Dispose() { Current = null; } | public void Dispose() { Current = null; } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| using System.Runtime.CompilerServices; | |||||
| using System.Runtime.CompilerServices; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -119,13 +119,11 @@ namespace Discord | |||||
| resolvedPermissions = mask; //Owners and administrators always have all permissions | resolvedPermissions = mask; //Owners and administrators always have all permissions | ||||
| else | else | ||||
| { | { | ||||
| OverwritePermissions? perms; | |||||
| //Start with this user's guild permissions | //Start with this user's guild permissions | ||||
| resolvedPermissions = guildPermissions; | resolvedPermissions = guildPermissions; | ||||
| //Give/Take Everyone permissions | //Give/Take Everyone permissions | ||||
| perms = channel.GetPermissionOverwrite(guild.EveryoneRole); | |||||
| var perms = channel.GetPermissionOverwrite(guild.EveryoneRole); | |||||
| if (perms != null) | if (perms != null) | ||||
| resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | ||||
| @@ -133,7 +131,7 @@ namespace Discord | |||||
| ulong deniedPermissions = 0UL, allowedPermissions = 0UL; | ulong deniedPermissions = 0UL, allowedPermissions = 0UL; | ||||
| foreach (var roleId in user.RoleIds) | foreach (var roleId in user.RoleIds) | ||||
| { | { | ||||
| IRole role = null; | |||||
| IRole role; | |||||
| if (roleId != guild.EveryoneRole.Id && (role = guild.GetRole(roleId)) != null) | if (roleId != guild.EveryoneRole.Id && (role = guild.GetRole(roleId)) != null) | ||||
| { | { | ||||
| perms = channel.GetPermissionOverwrite(role); | perms = channel.GetPermissionOverwrite(role); | ||||
| @@ -151,7 +149,7 @@ namespace Discord | |||||
| if (perms != null) | if (perms != null) | ||||
| resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | ||||
| if (channel is ITextChannel textChannel) | |||||
| if (channel is ITextChannel) | |||||
| { | { | ||||
| if (!GetValue(resolvedPermissions, ChannelPermission.ViewChannel)) | if (!GetValue(resolvedPermissions, ChannelPermission.ViewChannel)) | ||||
| { | { | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -198,7 +198,7 @@ namespace Discord | |||||
| for (var i = 0; i < roles.Length; i++) | for (var i = 0; i < roles.Length; i++) | ||||
| { | { | ||||
| if (roles[i] == guildId) | if (roles[i] == guildId) | ||||
| throw new ArgumentException($"The everyone role cannot be assigned to a user", name); | |||||
| throw new ArgumentException("The everyone role cannot be assigned to a user", name); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -92,7 +92,7 @@ namespace Discord.Rest | |||||
| await OnLoginAsync(tokenType, token).ConfigureAwait(false); | await OnLoginAsync(tokenType, token).ConfigureAwait(false); | ||||
| LoginState = LoginState.LoggedIn; | LoginState = LoginState.LoggedIn; | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await LogoutInternalAsync().ConfigureAwait(false); | await LogoutInternalAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -47,7 +47,7 @@ namespace Discord.Rest | |||||
| public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) | public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false); | var models = await client.ApiClient.GetMyConnectionsAsync(options).ConfigureAwait(false); | ||||
| return models.Select(x => RestConnection.Create(x)).ToImmutableArray(); | |||||
| return models.Select(RestConnection.Create).ToImmutableArray(); | |||||
| } | } | ||||
| public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client, | public static async Task<RestInviteMetadata> GetInviteAsync(BaseDiscordClient client, | ||||
| @@ -125,7 +125,7 @@ namespace Discord.API | |||||
| LoginState = LoginState.LoggedIn; | LoginState = LoginState.LoggedIn; | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await LogoutInternalAsync().ConfigureAwait(false); | await LogoutInternalAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -1394,9 +1394,9 @@ namespace Discord.API | |||||
| int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1)); | int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1)); | ||||
| string fieldName = GetFieldName(methodArgs[argId + 1]); | string fieldName = GetFieldName(methodArgs[argId + 1]); | ||||
| int? mappedId; | |||||
| mappedId = BucketIds.GetIndex(fieldName); | |||||
| var mappedId = BucketIds.GetIndex(fieldName); | |||||
| if(!mappedId.HasValue && rightIndex != endIndex && format.Length > rightIndex + 1 && format[rightIndex + 1] == '/') //Ignore the next slash | if(!mappedId.HasValue && rightIndex != endIndex && format.Length > rightIndex + 1 && format[rightIndex + 1] == '/') //Ignore the next slash | ||||
| rightIndex++; | rightIndex++; | ||||
| @@ -10,7 +10,7 @@ using Model = Discord.API.Channel; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel, IUpdateable | |||||
| public class RestDMChannel : RestChannel, IDMChannel, IRestPrivateChannel, IRestMessageChannel | |||||
| { | { | ||||
| public RestUser CurrentUser { get; private set; } | public RestUser CurrentUser { get; private set; } | ||||
| public RestUser Recipient { get; private set; } | public RestUser Recipient { get; private set; } | ||||
| @@ -11,7 +11,7 @@ using Model = Discord.API.Channel; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel, IUpdateable | |||||
| public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel | |||||
| { | { | ||||
| private string _iconId; | private string _iconId; | ||||
| private ImmutableDictionary<ulong, RestGroupUser> _users; | private ImmutableDictionary<ulong, RestGroupUser> _users; | ||||
| @@ -7,7 +7,7 @@ using Model = Discord.API.Channel; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| public class RestGuildChannel : RestChannel, IGuildChannel, IUpdateable | |||||
| public class RestGuildChannel : RestChannel, IGuildChannel | |||||
| { | { | ||||
| private ImmutableArray<Overwrite> _overwrites; | private ImmutableArray<Overwrite> _overwrites; | ||||
| @@ -168,7 +168,7 @@ namespace Discord.Rest | |||||
| public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null) | public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null) | ||||
| { | { | ||||
| var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | ||||
| return channels.Select(x => x as RestTextChannel).Where(x => x != null).ToImmutableArray(); | |||||
| return channels.OfType<RestTextChannel>().ToImmutableArray(); | |||||
| } | } | ||||
| public async Task<RestVoiceChannel> GetVoiceChannelAsync(ulong id, RequestOptions options = null) | public async Task<RestVoiceChannel> GetVoiceChannelAsync(ulong id, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -178,12 +178,12 @@ namespace Discord.Rest | |||||
| public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null) | public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null) | ||||
| { | { | ||||
| var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | ||||
| return channels.Select(x => x as RestVoiceChannel).Where(x => x != null).ToImmutableArray(); | |||||
| return channels.OfType<RestVoiceChannel>().ToImmutableArray(); | |||||
| } | } | ||||
| public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null) | public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null) | ||||
| { | { | ||||
| var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false); | ||||
| return channels.Select(x => x as RestCategoryChannel).Where(x => x != null).ToImmutableArray(); | |||||
| return channels.OfType<RestCategoryChannel>().ToImmutableArray(); | |||||
| } | } | ||||
| public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null) | public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null) | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.UserGuild; | using Model = Discord.API.UserGuild; | ||||
| @@ -6,7 +6,7 @@ using Model = Discord.API.UserGuild; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestUserGuild : RestEntity<ulong>, ISnowflakeEntity, IUserGuild | |||||
| public class RestUserGuild : RestEntity<ulong>, IUserGuild | |||||
| { | { | ||||
| private string _iconId; | private string _iconId; | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| @@ -9,7 +9,7 @@ using Model = Discord.API.GuildMember; | |||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| { | { | ||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class RestGuildUser : RestUser, IGuildUser, IUpdateable | |||||
| public class RestGuildUser : RestUser, IGuildUser | |||||
| { | { | ||||
| private long? _joinedAtTicks; | private long? _joinedAtTicks; | ||||
| private ImmutableArray<ulong> _roleIds; | private ImmutableArray<ulong> _roleIds; | ||||
| @@ -131,14 +131,14 @@ namespace Discord.Net.Rest | |||||
| return new RestResponse(response.StatusCode, headers, stream); | return new RestResponse(response.StatusCode, headers, stream); | ||||
| } | } | ||||
| private static readonly HttpMethod _patch = new HttpMethod("PATCH"); | |||||
| private static readonly HttpMethod Patch = new HttpMethod("PATCH"); | |||||
| private HttpMethod GetMethod(string method) | private HttpMethod GetMethod(string method) | ||||
| { | { | ||||
| switch (method) | switch (method) | ||||
| { | { | ||||
| case "DELETE": return HttpMethod.Delete; | case "DELETE": return HttpMethod.Delete; | ||||
| case "GET": return HttpMethod.Get; | case "GET": return HttpMethod.Get; | ||||
| case "PATCH": return _patch; | |||||
| case "PATCH": return Patch; | |||||
| case "POST": return HttpMethod.Post; | case "POST": return HttpMethod.Post; | ||||
| case "PUT": return HttpMethod.Put; | case "PUT": return HttpMethod.Put; | ||||
| default: throw new ArgumentOutOfRangeException(nameof(method), $"Unknown HttpMethod: {method}"); | default: throw new ArgumentOutOfRangeException(nameof(method), $"Unknown HttpMethod: {method}"); | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System.Collections.Immutable; | |||||
| using System.Collections.Immutable; | |||||
| namespace Discord.Net.Queue | namespace Discord.Net.Queue | ||||
| { | { | ||||
| @@ -9,8 +9,8 @@ namespace Discord.Net.Queue | |||||
| } | } | ||||
| internal struct ClientBucket | internal struct ClientBucket | ||||
| { | { | ||||
| private static readonly ImmutableDictionary<ClientBucketType, ClientBucket> _defsByType; | |||||
| private static readonly ImmutableDictionary<string, ClientBucket> _defsById; | |||||
| private static readonly ImmutableDictionary<ClientBucketType, ClientBucket> DefsByType; | |||||
| private static readonly ImmutableDictionary<string, ClientBucket> DefsById; | |||||
| static ClientBucket() | static ClientBucket() | ||||
| { | { | ||||
| @@ -23,16 +23,16 @@ namespace Discord.Net.Queue | |||||
| var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>(); | var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>(); | ||||
| foreach (var bucket in buckets) | foreach (var bucket in buckets) | ||||
| builder.Add(bucket.Type, bucket); | builder.Add(bucket.Type, bucket); | ||||
| _defsByType = builder.ToImmutable(); | |||||
| DefsByType = builder.ToImmutable(); | |||||
| var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>(); | var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>(); | ||||
| foreach (var bucket in buckets) | foreach (var bucket in buckets) | ||||
| builder2.Add(bucket.Id, bucket); | builder2.Add(bucket.Id, bucket); | ||||
| _defsById = builder2.ToImmutable(); | |||||
| DefsById = builder2.ToImmutable(); | |||||
| } | } | ||||
| public static ClientBucket Get(ClientBucketType type) => _defsByType[type]; | |||||
| public static ClientBucket Get(string id) => _defsById[id]; | |||||
| public static ClientBucket Get(ClientBucketType type) => DefsByType[type]; | |||||
| public static ClientBucket Get(string id) => DefsById[id]; | |||||
| public ClientBucketType Type { get; } | public ClientBucketType Type { get; } | ||||
| public string Id { get; } | public string Id { get; } | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| #if DEBUG_LIMITS | #if DEBUG_LIMITS | ||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| @@ -16,10 +16,10 @@ namespace Discord.Net.Queue | |||||
| private readonly ConcurrentDictionary<string, RequestBucket> _buckets; | private readonly ConcurrentDictionary<string, RequestBucket> _buckets; | ||||
| private readonly SemaphoreSlim _tokenLock; | private readonly SemaphoreSlim _tokenLock; | ||||
| private readonly CancellationTokenSource _cancelToken; //Dispose token | |||||
| private CancellationTokenSource _clearToken; | private CancellationTokenSource _clearToken; | ||||
| private CancellationToken _parentToken; | private CancellationToken _parentToken; | ||||
| private CancellationToken _requestCancelToken; //Parent token + Clear token | private CancellationToken _requestCancelToken; //Parent token + Clear token | ||||
| private CancellationTokenSource _cancelToken; //Dispose token | |||||
| private DateTimeOffset _waitUntil; | private DateTimeOffset _waitUntil; | ||||
| private Task _cleanupTask; | private Task _cleanupTask; | ||||
| @@ -115,7 +115,7 @@ namespace Discord.Net.Queue | |||||
| foreach (var bucket in _buckets.Select(x => x.Value)) | foreach (var bucket in _buckets.Select(x => x.Value)) | ||||
| { | { | ||||
| if ((now - bucket.LastAttemptAt).TotalMinutes > 1.0) | if ((now - bucket.LastAttemptAt).TotalMinutes > 1.0) | ||||
| _buckets.TryRemove(bucket.Id, out RequestBucket ignored); | |||||
| _buckets.TryRemove(bucket.Id, out _); | |||||
| } | } | ||||
| await Task.Delay(60000, _cancelToken.Token); //Runs each minute | await Task.Delay(60000, _cancelToken.Token); //Runs each minute | ||||
| } | } | ||||
| @@ -15,7 +15,7 @@ namespace Discord.Net | |||||
| internal RateLimitInfo(Dictionary<string, string> headers) | internal RateLimitInfo(Dictionary<string, string> headers) | ||||
| { | { | ||||
| IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) && | IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) && | ||||
| bool.TryParse(temp, out var isGlobal) ? isGlobal : false; | |||||
| bool.TryParse(temp, out var isGlobal) && isGlobal; | |||||
| Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) && | Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) && | ||||
| int.TryParse(temp, out var limit) ? limit : (int?)null; | int.TryParse(temp, out var limit) ? limit : (int?)null; | ||||
| Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && | Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && | ||||
| @@ -16,7 +16,7 @@ using System.Collections.Generic; | |||||
| namespace Discord.Audio | namespace Discord.Audio | ||||
| { | { | ||||
| //TODO: Add audio reconnecting | //TODO: Add audio reconnecting | ||||
| internal partial class AudioClient : IAudioClient, IDisposable | |||||
| internal partial class AudioClient : IAudioClient | |||||
| { | { | ||||
| internal struct StreamPair | internal struct StreamPair | ||||
| { | { | ||||
| @@ -65,7 +65,7 @@ namespace Discord.Audio | |||||
| ApiClient = new DiscordVoiceAPIClient(guild.Id, Discord.WebSocketProvider, Discord.UdpSocketProvider); | ApiClient = new DiscordVoiceAPIClient(guild.Id, Discord.WebSocketProvider, Discord.UdpSocketProvider); | ||||
| ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); | ApiClient.SentGatewayMessage += async opCode => await _audioLogger.DebugAsync($"Sent {opCode}").ConfigureAwait(false); | ||||
| ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync($"Sent Discovery").ConfigureAwait(false); | |||||
| ApiClient.SentDiscovery += async () => await _audioLogger.DebugAsync("Sent Discovery").ConfigureAwait(false); | |||||
| //ApiClient.SentData += async bytes => await _audioLogger.DebugAsync($"Sent {bytes} Bytes").ConfigureAwait(false); | //ApiClient.SentData += async bytes => await _audioLogger.DebugAsync($"Sent {bytes} Bytes").ConfigureAwait(false); | ||||
| ApiClient.ReceivedEvent += ProcessMessageAsync; | ApiClient.ReceivedEvent += ProcessMessageAsync; | ||||
| ApiClient.ReceivedPacket += ProcessPacketAsync; | ApiClient.ReceivedPacket += ProcessPacketAsync; | ||||
| @@ -131,7 +131,7 @@ namespace Discord.Audio | |||||
| await keepaliveTask.ConfigureAwait(false); | await keepaliveTask.ConfigureAwait(false); | ||||
| _keepaliveTask = null; | _keepaliveTask = null; | ||||
| while (_heartbeatTimes.TryDequeue(out long time)) { } | |||||
| while (_heartbeatTimes.TryDequeue(out _)) { } | |||||
| _lastMessageTime = 0; | _lastMessageTime = 0; | ||||
| await ClearInputStreamsAsync().ConfigureAwait(false); | await ClearInputStreamsAsync().ConfigureAwait(false); | ||||
| @@ -292,7 +292,7 @@ namespace Discord.Audio | |||||
| { | { | ||||
| if (packet.Length != 70) | if (packet.Length != 70) | ||||
| { | { | ||||
| await _audioLogger.DebugAsync($"Malformed Packet").ConfigureAwait(false); | |||||
| await _audioLogger.DebugAsync("Malformed Packet").ConfigureAwait(false); | |||||
| return; | return; | ||||
| } | } | ||||
| string ip; | string ip; | ||||
| @@ -304,7 +304,7 @@ namespace Discord.Audio | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| await _audioLogger.DebugAsync($"Malformed Packet", ex).ConfigureAwait(false); | |||||
| await _audioLogger.DebugAsync("Malformed Packet", ex).ConfigureAwait(false); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -331,7 +331,7 @@ namespace Discord.Audio | |||||
| { | { | ||||
| if (pair.Key == value) | if (pair.Key == value) | ||||
| { | { | ||||
| int latency = (int)(Environment.TickCount - pair.Value); | |||||
| int latency = Environment.TickCount - pair.Value; | |||||
| int before = UdpLatency; | int before = UdpLatency; | ||||
| UdpLatency = latency; | UdpLatency = latency; | ||||
| @@ -344,7 +344,7 @@ namespace Discord.Audio | |||||
| { | { | ||||
| if (!RTPReadStream.TryReadSsrc(packet, 0, out var ssrc)) | if (!RTPReadStream.TryReadSsrc(packet, 0, out var ssrc)) | ||||
| { | { | ||||
| await _audioLogger.DebugAsync($"Malformed Frame").ConfigureAwait(false); | |||||
| await _audioLogger.DebugAsync("Malformed Frame").ConfigureAwait(false); | |||||
| return; | return; | ||||
| } | } | ||||
| if (!_ssrcMap.TryGetValue(ssrc, out var userId)) | if (!_ssrcMap.TryGetValue(ssrc, out var userId)) | ||||
| @@ -363,7 +363,7 @@ namespace Discord.Audio | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| await _audioLogger.DebugAsync($"Malformed Frame", ex).ConfigureAwait(false); | |||||
| await _audioLogger.DebugAsync("Malformed Frame", ex).ConfigureAwait(false); | |||||
| return; | return; | ||||
| } | } | ||||
| //await _audioLogger.DebugAsync($"Received {packet.Length} bytes from user {userId}").ConfigureAwait(false); | //await _audioLogger.DebugAsync($"Received {packet.Length} bytes from user {userId}").ConfigureAwait(false); | ||||
| @@ -372,7 +372,7 @@ namespace Discord.Audio | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| await _audioLogger.WarningAsync($"Failed to process UDP packet", ex).ConfigureAwait(false); | |||||
| await _audioLogger.WarningAsync("Failed to process UDP packet", ex).ConfigureAwait(false); | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -116,7 +116,7 @@ namespace Discord.Audio.Streams | |||||
| timestamp += OpusEncoder.FrameSamplesPerChannel; | timestamp += OpusEncoder.FrameSamplesPerChannel; | ||||
| } | } | ||||
| #if DEBUG | #if DEBUG | ||||
| var _ = _logger?.DebugAsync($"Buffer underrun"); | |||||
| var _ = _logger?.DebugAsync("Buffer underrun"); | |||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| @@ -140,7 +140,7 @@ namespace Discord.Audio.Streams | |||||
| if (!_bufferPool.TryDequeue(out byte[] buffer)) | if (!_bufferPool.TryDequeue(out byte[] buffer)) | ||||
| { | { | ||||
| #if DEBUG | #if DEBUG | ||||
| var _ = _logger?.DebugAsync($"Buffer overflow"); //Should never happen because of the queueLock | |||||
| var _ = _logger?.DebugAsync("Buffer overflow"); //Should never happen because of the queueLock | |||||
| #endif | #endif | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -149,7 +149,7 @@ namespace Discord.Audio.Streams | |||||
| if (!_isPreloaded && _queuedFrames.Count == _queueLength) | if (!_isPreloaded && _queuedFrames.Count == _queueLength) | ||||
| { | { | ||||
| #if DEBUG | #if DEBUG | ||||
| var _ = _logger?.DebugAsync($"Preloaded"); | |||||
| var _ = _logger?.DebugAsync("Preloaded"); | |||||
| #endif | #endif | ||||
| _isPreloaded = true; | _isPreloaded = true; | ||||
| } | } | ||||
| @@ -169,8 +169,8 @@ namespace Discord.Audio.Streams | |||||
| { | { | ||||
| do | do | ||||
| cancelToken.ThrowIfCancellationRequested(); | cancelToken.ThrowIfCancellationRequested(); | ||||
| while (_queuedFrames.TryDequeue(out Frame ignored)); | |||||
| while (_queuedFrames.TryDequeue(out _)); | |||||
| return Task.Delay(0); | return Task.Delay(0); | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Linq; | using System.Linq; | ||||
| @@ -72,7 +72,7 @@ namespace Discord.WebSocket | |||||
| switch (channel) | switch (channel) | ||||
| { | { | ||||
| case SocketDMChannel dmChannel: | case SocketDMChannel dmChannel: | ||||
| _dmChannels.TryRemove(dmChannel.Recipient.Id, out var ignored); | |||||
| _dmChannels.TryRemove(dmChannel.Recipient.Id, out _); | |||||
| break; | break; | ||||
| case SocketGroupChannel groupChannel: | case SocketGroupChannel groupChannel: | ||||
| _groupChannels.TryRemove(id); | _groupChannels.TryRemove(id); | ||||
| @@ -13,11 +13,11 @@ namespace Discord.WebSocket | |||||
| { | { | ||||
| private readonly DiscordSocketConfig _baseConfig; | private readonly DiscordSocketConfig _baseConfig; | ||||
| private readonly SemaphoreSlim _connectionGroupLock; | private readonly SemaphoreSlim _connectionGroupLock; | ||||
| private readonly Dictionary<int, int> _shardIdsToIndex; | |||||
| private readonly bool _automaticShards; | |||||
| private int[] _shardIds; | private int[] _shardIds; | ||||
| private Dictionary<int, int> _shardIdsToIndex; | |||||
| private DiscordSocketClient[] _shards; | private DiscordSocketClient[] _shards; | ||||
| private int _totalShards; | private int _totalShards; | ||||
| private bool _automaticShards; | |||||
| /// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary> | /// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary> | ||||
| public override int Latency { get => GetLatency(); protected set { } } | public override int Latency { get => GetLatency(); protected set { } } | ||||
| @@ -25,8 +25,8 @@ namespace Discord.WebSocket | |||||
| public override IActivity Activity { get => _shards[0].Activity; protected set { } } | public override IActivity Activity { get => _shards[0].Activity; protected set { } } | ||||
| internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; | internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient; | ||||
| public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(() => GetGuildCount()); | |||||
| public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => GetPrivateChannels().ToReadOnlyCollection(() => GetPrivateChannelCount()); | |||||
| public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(GetGuildCount); | |||||
| public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => GetPrivateChannels().ToReadOnlyCollection(GetPrivateChannelCount); | |||||
| public IReadOnlyCollection<DiscordSocketClient> Shards => _shards; | public IReadOnlyCollection<DiscordSocketClient> Shards => _shards; | ||||
| public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _shards[0].VoiceRegions; | public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _shards[0].VoiceRegions; | ||||
| @@ -26,9 +26,9 @@ namespace Discord.API | |||||
| public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } } | public event Func<Exception, Task> Disconnected { add { _disconnectedEvent.Add(value); } remove { _disconnectedEvent.Remove(value); } } | ||||
| private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>(); | private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>(); | ||||
| private readonly bool _isExplicitUrl; | |||||
| private CancellationTokenSource _connectCancelToken; | private CancellationTokenSource _connectCancelToken; | ||||
| private string _gatewayUrl; | private string _gatewayUrl; | ||||
| private bool _isExplicitUrl; | |||||
| //Store our decompression streams for zlib shared state | //Store our decompression streams for zlib shared state | ||||
| private MemoryStream _compressed; | private MemoryStream _compressed; | ||||
| @@ -63,9 +63,9 @@ namespace Discord.WebSocket | |||||
| public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds; | public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds; | ||||
| public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels; | public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels; | ||||
| public IReadOnlyCollection<SocketDMChannel> DMChannels | public IReadOnlyCollection<SocketDMChannel> DMChannels | ||||
| => State.PrivateChannels.Select(x => x as SocketDMChannel).Where(x => x != null).ToImmutableArray(); | |||||
| => State.PrivateChannels.OfType<SocketDMChannel>().ToImmutableArray(); | |||||
| public IReadOnlyCollection<SocketGroupChannel> GroupChannels | public IReadOnlyCollection<SocketGroupChannel> GroupChannels | ||||
| => State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray(); | |||||
| => State.PrivateChannels.OfType<SocketGroupChannel>().ToImmutableArray(); | |||||
| public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection(); | public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection(); | ||||
| /// <summary> Creates a new REST/WebSocket discord client. </summary> | /// <summary> Creates a new REST/WebSocket discord client. </summary> | ||||
| @@ -207,7 +207,7 @@ namespace Discord.WebSocket | |||||
| await heartbeatTask.ConfigureAwait(false); | await heartbeatTask.ConfigureAwait(false); | ||||
| _heartbeatTask = null; | _heartbeatTask = null; | ||||
| while (_heartbeatTimes.TryDequeue(out long time)) { } | |||||
| while (_heartbeatTimes.TryDequeue(out _)) { } | |||||
| _lastMessageTime = 0; | _lastMessageTime = 0; | ||||
| await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false); | await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false); | ||||
| @@ -218,7 +218,7 @@ namespace Discord.WebSocket | |||||
| //Clear large guild queue | //Clear large guild queue | ||||
| await _gatewayLogger.DebugAsync("Clearing large guild queue").ConfigureAwait(false); | await _gatewayLogger.DebugAsync("Clearing large guild queue").ConfigureAwait(false); | ||||
| while (_largeGuilds.TryDequeue(out ulong guildId)) { } | |||||
| while (_largeGuilds.TryDequeue(out _)) { } | |||||
| //Raise virtual GUILD_UNAVAILABLEs | //Raise virtual GUILD_UNAVAILABLEs | ||||
| await _gatewayLogger.DebugAsync("Raising virtual GuildUnavailables").ConfigureAwait(false); | await _gatewayLogger.DebugAsync("Raising virtual GuildUnavailables").ConfigureAwait(false); | ||||
| @@ -351,7 +351,7 @@ namespace Discord.WebSocket | |||||
| var gameModel = new GameModel(); | var gameModel = new GameModel(); | ||||
| // Discord only accepts rich presence over RPC, don't even bother building a payload | // Discord only accepts rich presence over RPC, don't even bother building a payload | ||||
| if (Activity is RichGame game) | |||||
| if (Activity is RichGame) | |||||
| throw new NotSupportedException("Outgoing Rich Presences are not supported"); | throw new NotSupportedException("Outgoing Rich Presences are not supported"); | ||||
| if (Activity != null) | if (Activity != null) | ||||
| @@ -508,7 +508,7 @@ namespace Discord.WebSocket | |||||
| { | { | ||||
| type = "GUILD_AVAILABLE"; | type = "GUILD_AVAILABLE"; | ||||
| _lastGuildAvailableTime = Environment.TickCount; | _lastGuildAvailableTime = Environment.TickCount; | ||||
| await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_AVAILABLE)").ConfigureAwait(false); | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_AVAILABLE)").ConfigureAwait(false); | |||||
| var guild = State.GetGuild(data.Id); | var guild = State.GetGuild(data.Id); | ||||
| if (guild != null) | if (guild != null) | ||||
| @@ -533,7 +533,7 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); | |||||
| var guild = AddGuild(data, State); | var guild = AddGuild(data, State); | ||||
| if (guild != null) | if (guild != null) | ||||
| @@ -614,7 +614,7 @@ namespace Discord.WebSocket | |||||
| if (data.Unavailable == true) | if (data.Unavailable == true) | ||||
| { | { | ||||
| type = "GUILD_UNAVAILABLE"; | type = "GUILD_UNAVAILABLE"; | ||||
| await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_UNAVAILABLE)").ConfigureAwait(false); | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_UNAVAILABLE)").ConfigureAwait(false); | |||||
| var guild = State.GetGuild(data.Id); | var guild = State.GetGuild(data.Id); | ||||
| if (guild != null) | if (guild != null) | ||||
| @@ -630,7 +630,7 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_DELETE)").ConfigureAwait(false); | |||||
| await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_DELETE)").ConfigureAwait(false); | |||||
| var guild = RemoveGuild(data.Id); | var guild = RemoveGuild(data.Id); | ||||
| if (guild != null) | if (guild != null) | ||||
| @@ -1626,7 +1626,7 @@ namespace Discord.WebSocket | |||||
| var guild = State.RemoveGuild(id); | var guild = State.RemoveGuild(id); | ||||
| if (guild != null) | if (guild != null) | ||||
| { | { | ||||
| foreach (var channel in guild.Channels) | |||||
| foreach (var _ in guild.Channels) | |||||
| State.RemoveChannel(id); | State.RemoveChannel(id); | ||||
| foreach (var user in guild.Users) | foreach (var user in guild.Users) | ||||
| user.GlobalUser.RemoveRef(this); | user.GlobalUser.RemoveRef(this); | ||||
| @@ -1679,7 +1679,7 @@ namespace Discord.WebSocket | |||||
| if (eventHandler.HasSubscribers) | if (eventHandler.HasSubscribers) | ||||
| { | { | ||||
| if (HandlerTimeout.HasValue) | if (HandlerTimeout.HasValue) | ||||
| await TimeoutWrap(name, () => eventHandler.InvokeAsync()).ConfigureAwait(false); | |||||
| await TimeoutWrap(name, eventHandler.InvokeAsync).ConfigureAwait(false); | |||||
| else | else | ||||
| await eventHandler.InvokeAsync().ConfigureAwait(false); | await eventHandler.InvokeAsync().ConfigureAwait(false); | ||||
| } | } | ||||
| @@ -39,8 +39,8 @@ namespace Discord.Audio | |||||
| private readonly JsonSerializer _serializer; | private readonly JsonSerializer _serializer; | ||||
| private readonly SemaphoreSlim _connectionLock; | private readonly SemaphoreSlim _connectionLock; | ||||
| private readonly IUdpSocket _udp; | |||||
| private CancellationTokenSource _connectCancelToken; | private CancellationTokenSource _connectCancelToken; | ||||
| private IUdpSocket _udp; | |||||
| private bool _isDisposed; | private bool _isDisposed; | ||||
| private ulong _nextKeepalive; | private ulong _nextKeepalive; | ||||
| @@ -188,7 +188,7 @@ namespace Discord.Audio | |||||
| ConnectionState = ConnectionState.Connected; | ConnectionState = ConnectionState.Connected; | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await DisconnectInternalAsync().ConfigureAwait(false); | await DisconnectInternalAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -97,7 +97,7 @@ namespace Discord.WebSocket | |||||
| if (id == Recipient.Id) | if (id == Recipient.Id) | ||||
| return Recipient; | return Recipient; | ||||
| else if (id == Discord.CurrentUser.Id) | else if (id == Discord.CurrentUser.Id) | ||||
| return Discord.CurrentUser as SocketSelfUser; | |||||
| return Discord.CurrentUser; | |||||
| else | else | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -18,10 +18,10 @@ namespace Discord.WebSocket | |||||
| public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel | public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel | ||||
| { | { | ||||
| private readonly MessageCache _messages; | private readonly MessageCache _messages; | ||||
| private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||||
| private string _iconId; | private string _iconId; | ||||
| private ConcurrentDictionary<ulong, SocketGroupUser> _users; | private ConcurrentDictionary<ulong, SocketGroupUser> _users; | ||||
| private ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||||
| public string Name { get; private set; } | public string Name { get; private set; } | ||||
| @@ -129,7 +129,7 @@ namespace Discord.WebSocket | |||||
| internal SocketGroupUser GetOrAddUser(UserModel model) | internal SocketGroupUser GetOrAddUser(UserModel model) | ||||
| { | { | ||||
| if (_users.TryGetValue(model.Id, out SocketGroupUser user)) | if (_users.TryGetValue(model.Id, out SocketGroupUser user)) | ||||
| return user as SocketGroupUser; | |||||
| return user; | |||||
| else | else | ||||
| { | { | ||||
| var privateUser = SocketGroupUser.Create(this, Discord.State, model); | var privateUser = SocketGroupUser.Create(this, Discord.State, model); | ||||
| @@ -143,7 +143,7 @@ namespace Discord.WebSocket | |||||
| if (_users.TryRemove(id, out SocketGroupUser user)) | if (_users.TryRemove(id, out SocketGroupUser user)) | ||||
| { | { | ||||
| user.GlobalUser.RemoveRef(Discord); | user.GlobalUser.RemoveRef(Discord); | ||||
| return user as SocketGroupUser; | |||||
| return user; | |||||
| } | } | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -91,11 +91,11 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| } | } | ||||
| public IReadOnlyCollection<SocketTextChannel> TextChannels | public IReadOnlyCollection<SocketTextChannel> TextChannels | ||||
| => Channels.Select(x => x as SocketTextChannel).Where(x => x != null).ToImmutableArray(); | |||||
| => Channels.OfType<SocketTextChannel>().ToImmutableArray(); | |||||
| public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels | public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels | ||||
| => Channels.Select(x => x as SocketVoiceChannel).Where(x => x != null).ToImmutableArray(); | |||||
| => Channels.OfType<SocketVoiceChannel>().ToImmutableArray(); | |||||
| public IReadOnlyCollection<SocketCategoryChannel> CategoryChannels | public IReadOnlyCollection<SocketCategoryChannel> CategoryChannels | ||||
| => Channels.Select(x => x as SocketCategoryChannel).Where(x => x != null).ToImmutableArray(); | |||||
| => Channels.OfType<SocketCategoryChannel>().ToImmutableArray(); | |||||
| public SocketGuildUser CurrentUser => _members.TryGetValue(Discord.CurrentUser.Id, out SocketGuildUser member) ? member : null; | public SocketGuildUser CurrentUser => _members.TryGetValue(Discord.CurrentUser.Id, out SocketGuildUser member) ? member : null; | ||||
| public SocketRole EveryoneRole => GetRole(Id); | public SocketRole EveryoneRole => GetRole(Id); | ||||
| public IReadOnlyCollection<SocketGuildChannel> Channels | public IReadOnlyCollection<SocketGuildChannel> Channels | ||||
| @@ -563,7 +563,7 @@ namespace Discord.WebSocket | |||||
| await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false); | await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false); | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await DisconnectAudioInternalAsync().ConfigureAwait(false); | await DisconnectAudioInternalAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -580,7 +580,7 @@ namespace Discord.WebSocket | |||||
| throw new TimeoutException(); | throw new TimeoutException(); | ||||
| return await promise.Task.ConfigureAwait(false); | return await promise.Task.ConfigureAwait(false); | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await DisconnectAudioAsync().ConfigureAwait(false); | await DisconnectAudioAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -1,4 +1,4 @@ | |||||
| using System; | |||||
| using System; | |||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| @@ -28,7 +28,7 @@ namespace Discord.WebSocket | |||||
| _orderedMessages.Enqueue(message.Id); | _orderedMessages.Enqueue(message.Id); | ||||
| while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out ulong msgId)) | while (_orderedMessages.Count > _size && _orderedMessages.TryDequeue(out ulong msgId)) | ||||
| _messages.TryRemove(msgId, out SocketMessage msg); | |||||
| _messages.TryRemove(msgId, out _); | |||||
| } | } | ||||
| } | } | ||||
| @@ -12,12 +12,12 @@ namespace Discord.WebSocket | |||||
| [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
| public class SocketUserMessage : SocketMessage, IUserMessage | public class SocketUserMessage : SocketMessage, IUserMessage | ||||
| { | { | ||||
| private readonly List<SocketReaction> _reactions = new List<SocketReaction>(); | |||||
| private bool _isMentioningEveryone, _isTTS, _isPinned; | private bool _isMentioningEveryone, _isTTS, _isPinned; | ||||
| private long? _editedTimestampTicks; | private long? _editedTimestampTicks; | ||||
| private ImmutableArray<Attachment> _attachments; | private ImmutableArray<Attachment> _attachments; | ||||
| private ImmutableArray<Embed> _embeds; | private ImmutableArray<Embed> _embeds; | ||||
| private ImmutableArray<ITag> _tags; | private ImmutableArray<ITag> _tags; | ||||
| private List<SocketReaction> _reactions = new List<SocketReaction>(); | |||||
| public override bool IsTTS => _isTTS; | public override bool IsTTS => _isTTS; | ||||
| public override bool IsPinned => _isPinned; | public override bool IsPinned => _isPinned; | ||||
| @@ -22,8 +22,8 @@ namespace Discord.Net.WebSockets | |||||
| private readonly SemaphoreSlim _lock; | private readonly SemaphoreSlim _lock; | ||||
| private readonly Dictionary<string, string> _headers; | private readonly Dictionary<string, string> _headers; | ||||
| private readonly IWebProxy _proxy; | |||||
| private ClientWebSocket _client; | private ClientWebSocket _client; | ||||
| private IWebProxy _proxy; | |||||
| private Task _task; | private Task _task; | ||||
| private CancellationTokenSource _cancelTokenSource; | private CancellationTokenSource _cancelTokenSource; | ||||
| private CancellationToken _cancelToken, _parentToken; | private CancellationToken _cancelToken, _parentToken; | ||||