* Change all Select(... as ...) to OfType
* Add changes according to 194a8aa427
pull/1139/head
@@ -7,13 +7,13 @@ namespace Discord.Commands | |||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] | |||
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 OverrideTypeReaderAttribute(Type overridenTypeReader) | |||
{ | |||
if (!_typeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) | |||
if (!TypeReaderTypeInfo.IsAssignableFrom(overridenTypeReader.GetTypeInfo())) | |||
throw new ArgumentException($"{nameof(overridenTypeReader)} must inherit from {nameof(TypeReader)}"); | |||
TypeReader = overridenTypeReader; | |||
@@ -10,7 +10,7 @@ namespace Discord.Commands | |||
{ | |||
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) | |||
{ | |||
@@ -135,7 +135,7 @@ namespace Discord.Commands | |||
if (builder.Name == null) | |||
builder.Name = typeInfo.Name; | |||
var validCommands = typeInfo.DeclaredMethods.Where(x => IsValidCommandDefinition(x)); | |||
var validCommands = typeInfo.DeclaredMethods.Where(IsValidCommandDefinition); | |||
foreach (var method in validCommands) | |||
{ | |||
@@ -299,7 +299,7 @@ namespace Discord.Commands | |||
private static bool IsValidModuleDefinition(TypeInfo typeInfo) | |||
{ | |||
return _moduleTypeInfo.IsAssignableFrom(typeInfo) && | |||
return ModuleTypeInfo.IsAssignableFrom(typeInfo) && | |||
!typeInfo.IsAbstract && | |||
!typeInfo.ContainsGenericParameters; | |||
} | |||
@@ -118,7 +118,7 @@ namespace Discord.Commands | |||
var typeInfo = type.GetTypeInfo(); | |||
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(); | |||
@@ -241,7 +241,7 @@ namespace Discord.Commands | |||
{ | |||
if (_defaultTypeReaders.ContainsKey(type)) | |||
_ = _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); | |||
} | |||
/// <summary> | |||
@@ -1,4 +1,4 @@ | |||
using Discord.Commands.Builders; | |||
using Discord.Commands.Builders; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -63,7 +63,7 @@ namespace Discord.Commands | |||
Attributes = builder.Attributes.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; | |||
_action = builder.Callback; | |||
@@ -1,4 +1,4 @@ | |||
using System.Collections.Generic; | |||
using System.Collections.Generic; | |||
namespace Discord.Commands | |||
{ | |||
@@ -6,7 +6,7 @@ namespace Discord.Commands | |||
{ | |||
private readonly CommandService _service; | |||
private readonly CommandMapNode _root; | |||
private static readonly string[] _blankAliases = new[] { "" }; | |||
private static readonly string[] BlankAliases = { "" }; | |||
public CommandMap(CommandService service) | |||
{ | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -7,7 +7,7 @@ namespace Discord.Commands | |||
{ | |||
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 string _name; | |||
@@ -52,7 +52,6 @@ namespace Discord.Commands | |||
public void RemoveCommand(CommandService service, string text, int index, CommandInfo command) | |||
{ | |||
int nextSegment = NextSegment(text, index, service._separatorChar); | |||
string name; | |||
lock (_lockObj) | |||
{ | |||
@@ -60,13 +59,13 @@ namespace Discord.Commands | |||
_commands = _commands.Remove(command); | |||
else | |||
{ | |||
string name; | |||
if (nextSegment == -1) | |||
name = text.Substring(index); | |||
else | |||
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); | |||
if (nextNode.IsEmpty) | |||
@@ -100,7 +99,7 @@ namespace Discord.Commands | |||
} | |||
//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) | |||
{ | |||
name = text.Substring(index, nextSegment - index); | |||
@@ -8,9 +8,9 @@ namespace Discord.Commands | |||
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() | |||
{ | |||
@@ -34,7 +34,7 @@ namespace Discord.Commands | |||
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 | |||
{ | |||
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'", //4d3h2m | |||
"%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) | |||
{ | |||
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.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)) | |||
.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) | |||
@@ -8,7 +8,7 @@ namespace Discord.Commands | |||
{ | |||
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) | |||
=> CreateBuilder<T>(typeInfo, commands)(services); | |||
@@ -54,7 +54,7 @@ namespace Discord.Commands | |||
private static System.Reflection.PropertyInfo[] GetProperties(TypeInfo ownerType) | |||
{ | |||
var result = new List<System.Reflection.PropertyInfo>(); | |||
while (ownerType != _objectTypeInfo) | |||
while (ownerType != ObjectTypeInfo) | |||
{ | |||
foreach (var prop in ownerType.DeclaredProperties) | |||
{ | |||
@@ -239,7 +239,7 @@ namespace Discord | |||
get => _name; | |||
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)); | |||
_name = value; | |||
} | |||
@@ -251,7 +251,7 @@ namespace Discord | |||
set | |||
{ | |||
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)); | |||
_value = stringValue; | |||
} | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Diagnostics; | |||
namespace Discord | |||
@@ -20,6 +20,6 @@ namespace Discord | |||
} | |||
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; | |||
namespace Discord | |||
@@ -20,6 +20,6 @@ namespace Discord | |||
} | |||
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; | |||
namespace Discord | |||
@@ -18,6 +18,6 @@ namespace Discord | |||
} | |||
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) | |||
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IDMChannel; | |||
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) | |||
=> await client.GetPrivateChannelAsync(id).ConfigureAwait(false) as IGroupChannel; | |||
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) | |||
{ | |||
@@ -1,9 +1,9 @@ | |||
namespace Discord | |||
namespace Discord | |||
{ | |||
public static class Format | |||
{ | |||
// Characters which need escaping | |||
private static string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||
private static readonly string[] SensitiveCharacters = { "\\", "*", "_", "~", "`" }; | |||
/// <summary> Returns a markdown-formatted string with bold formatting. </summary> | |||
public static string Bold(string text) => $"**{text}**"; | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Globalization; | |||
using System.Text; | |||
@@ -139,22 +139,22 @@ namespace Discord | |||
if (user != null) | |||
return $"@{guildUser?.Nickname ?? user?.Username}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.NameNoPrefix: | |||
if (user != null) | |||
return $"{guildUser?.Nickname ?? user?.Username}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.FullName: | |||
if (user != null) | |||
return $"@{user.Username}#{user.Discriminator}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.FullNameNoPrefix: | |||
if (user != null) | |||
return $"{user.Username}#{user.Discriminator}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.Sanitize: | |||
if (guildUser != null && guildUser.Nickname == null) | |||
return MentionUser($"{SanitizeChar}{tag.Key}", false); | |||
@@ -176,13 +176,13 @@ namespace Discord | |||
if (channel != null) | |||
return $"#{channel.Name}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.NameNoPrefix: | |||
case TagHandling.FullNameNoPrefix: | |||
if (channel != null) | |||
return $"{channel.Name}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.Sanitize: | |||
return MentionChannel($"{SanitizeChar}{tag.Key}"); | |||
} | |||
@@ -201,13 +201,13 @@ namespace Discord | |||
if (role != null) | |||
return $"@{role.Name}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.NameNoPrefix: | |||
case TagHandling.FullNameNoPrefix: | |||
if (role != null) | |||
return $"{role.Name}"; | |||
else | |||
return $""; | |||
return ""; | |||
case TagHandling.Sanitize: | |||
return MentionRole($"{SanitizeChar}{tag.Key}"); | |||
} | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
@@ -60,7 +60,7 @@ namespace Discord | |||
if (Current.Count == 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) | |||
{ | |||
@@ -74,4 +74,4 @@ namespace Discord | |||
public void Dispose() { Current = null; } | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.CompilerServices; | |||
namespace Discord | |||
{ | |||
@@ -119,13 +119,11 @@ namespace Discord | |||
resolvedPermissions = mask; //Owners and administrators always have all permissions | |||
else | |||
{ | |||
OverwritePermissions? perms; | |||
//Start with this user's guild permissions | |||
resolvedPermissions = guildPermissions; | |||
//Give/Take Everyone permissions | |||
perms = channel.GetPermissionOverwrite(guild.EveryoneRole); | |||
var perms = channel.GetPermissionOverwrite(guild.EveryoneRole); | |||
if (perms != null) | |||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | |||
@@ -133,7 +131,7 @@ namespace Discord | |||
ulong deniedPermissions = 0UL, allowedPermissions = 0UL; | |||
foreach (var roleId in user.RoleIds) | |||
{ | |||
IRole role = null; | |||
IRole role; | |||
if (roleId != guild.EveryoneRole.Id && (role = guild.GetRole(roleId)) != null) | |||
{ | |||
perms = channel.GetPermissionOverwrite(role); | |||
@@ -151,7 +149,7 @@ namespace Discord | |||
if (perms != null) | |||
resolvedPermissions = (resolvedPermissions & ~perms.Value.DenyValue) | perms.Value.AllowValue; | |||
if (channel is ITextChannel textChannel) | |||
if (channel is ITextChannel) | |||
{ | |||
if (!GetValue(resolvedPermissions, ChannelPermission.ViewChannel)) | |||
{ | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
namespace Discord | |||
{ | |||
@@ -198,7 +198,7 @@ namespace Discord | |||
for (var i = 0; i < roles.Length; i++) | |||
{ | |||
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); | |||
LoginState = LoginState.LoggedIn; | |||
} | |||
catch (Exception) | |||
catch | |||
{ | |||
await LogoutInternalAsync().ConfigureAwait(false); | |||
throw; | |||
@@ -47,7 +47,7 @@ namespace Discord.Rest | |||
public static async Task<IReadOnlyCollection<RestConnection>> GetConnectionsAsync(BaseDiscordClient client, RequestOptions options) | |||
{ | |||
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, | |||
@@ -125,7 +125,7 @@ namespace Discord.API | |||
LoginState = LoginState.LoggedIn; | |||
} | |||
catch (Exception) | |||
catch | |||
{ | |||
await LogoutInternalAsync().ConfigureAwait(false); | |||
throw; | |||
@@ -1394,9 +1394,9 @@ namespace Discord.API | |||
int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 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 | |||
rightIndex++; | |||
@@ -10,7 +10,7 @@ using Model = Discord.API.Channel; | |||
namespace Discord.Rest | |||
{ | |||
[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 Recipient { get; private set; } | |||
@@ -11,7 +11,7 @@ using Model = Discord.API.Channel; | |||
namespace Discord.Rest | |||
{ | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel, IUpdateable | |||
public class RestGroupChannel : RestChannel, IGroupChannel, IRestPrivateChannel, IRestMessageChannel, IRestAudioChannel | |||
{ | |||
private string _iconId; | |||
private ImmutableDictionary<ulong, RestGroupUser> _users; | |||
@@ -7,7 +7,7 @@ using Model = Discord.API.Channel; | |||
namespace Discord.Rest | |||
{ | |||
public class RestGuildChannel : RestChannel, IGuildChannel, IUpdateable | |||
public class RestGuildChannel : RestChannel, IGuildChannel | |||
{ | |||
private ImmutableArray<Overwrite> _overwrites; | |||
@@ -168,7 +168,7 @@ namespace Discord.Rest | |||
public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null) | |||
{ | |||
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) | |||
{ | |||
@@ -178,12 +178,12 @@ namespace Discord.Rest | |||
public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null) | |||
{ | |||
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) | |||
{ | |||
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) | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Diagnostics; | |||
using System.Threading.Tasks; | |||
using Model = Discord.API.UserGuild; | |||
@@ -6,7 +6,7 @@ using Model = Discord.API.UserGuild; | |||
namespace Discord.Rest | |||
{ | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestUserGuild : RestEntity<ulong>, ISnowflakeEntity, IUserGuild | |||
public class RestUserGuild : RestEntity<ulong>, IUserGuild | |||
{ | |||
private string _iconId; | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Diagnostics; | |||
@@ -9,7 +9,7 @@ using Model = Discord.API.GuildMember; | |||
namespace Discord.Rest | |||
{ | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class RestGuildUser : RestUser, IGuildUser, IUpdateable | |||
public class RestGuildUser : RestUser, IGuildUser | |||
{ | |||
private long? _joinedAtTicks; | |||
private ImmutableArray<ulong> _roleIds; | |||
@@ -131,14 +131,14 @@ namespace Discord.Net.Rest | |||
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) | |||
{ | |||
switch (method) | |||
{ | |||
case "DELETE": return HttpMethod.Delete; | |||
case "GET": return HttpMethod.Get; | |||
case "PATCH": return _patch; | |||
case "PATCH": return Patch; | |||
case "POST": return HttpMethod.Post; | |||
case "PUT": return HttpMethod.Put; | |||
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 | |||
{ | |||
@@ -9,8 +9,8 @@ namespace Discord.Net.Queue | |||
} | |||
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() | |||
{ | |||
@@ -23,16 +23,16 @@ namespace Discord.Net.Queue | |||
var builder = ImmutableDictionary.CreateBuilder<ClientBucketType, ClientBucket>(); | |||
foreach (var bucket in buckets) | |||
builder.Add(bucket.Type, bucket); | |||
_defsByType = builder.ToImmutable(); | |||
DefsByType = builder.ToImmutable(); | |||
var builder2 = ImmutableDictionary.CreateBuilder<string, ClientBucket>(); | |||
foreach (var bucket in buckets) | |||
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 string Id { get; } | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Concurrent; | |||
#if DEBUG_LIMITS | |||
using System.Diagnostics; | |||
@@ -16,10 +16,10 @@ namespace Discord.Net.Queue | |||
private readonly ConcurrentDictionary<string, RequestBucket> _buckets; | |||
private readonly SemaphoreSlim _tokenLock; | |||
private readonly CancellationTokenSource _cancelToken; //Dispose token | |||
private CancellationTokenSource _clearToken; | |||
private CancellationToken _parentToken; | |||
private CancellationToken _requestCancelToken; //Parent token + Clear token | |||
private CancellationTokenSource _cancelToken; //Dispose token | |||
private DateTimeOffset _waitUntil; | |||
private Task _cleanupTask; | |||
@@ -115,7 +115,7 @@ namespace Discord.Net.Queue | |||
foreach (var bucket in _buckets.Select(x => x.Value)) | |||
{ | |||
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 | |||
} | |||
@@ -15,7 +15,7 @@ namespace Discord.Net | |||
internal RateLimitInfo(Dictionary<string, string> headers) | |||
{ | |||
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) && | |||
int.TryParse(temp, out var limit) ? limit : (int?)null; | |||
Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && | |||
@@ -16,7 +16,7 @@ using System.Collections.Generic; | |||
namespace Discord.Audio | |||
{ | |||
//TODO: Add audio reconnecting | |||
internal partial class AudioClient : IAudioClient, IDisposable | |||
internal partial class AudioClient : IAudioClient | |||
{ | |||
internal struct StreamPair | |||
{ | |||
@@ -65,7 +65,7 @@ namespace Discord.Audio | |||
ApiClient = new DiscordVoiceAPIClient(guild.Id, Discord.WebSocketProvider, Discord.UdpSocketProvider); | |||
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.ReceivedEvent += ProcessMessageAsync; | |||
ApiClient.ReceivedPacket += ProcessPacketAsync; | |||
@@ -131,7 +131,7 @@ namespace Discord.Audio | |||
await keepaliveTask.ConfigureAwait(false); | |||
_keepaliveTask = null; | |||
while (_heartbeatTimes.TryDequeue(out long time)) { } | |||
while (_heartbeatTimes.TryDequeue(out _)) { } | |||
_lastMessageTime = 0; | |||
await ClearInputStreamsAsync().ConfigureAwait(false); | |||
@@ -292,7 +292,7 @@ namespace Discord.Audio | |||
{ | |||
if (packet.Length != 70) | |||
{ | |||
await _audioLogger.DebugAsync($"Malformed Packet").ConfigureAwait(false); | |||
await _audioLogger.DebugAsync("Malformed Packet").ConfigureAwait(false); | |||
return; | |||
} | |||
string ip; | |||
@@ -304,7 +304,7 @@ namespace Discord.Audio | |||
} | |||
catch (Exception ex) | |||
{ | |||
await _audioLogger.DebugAsync($"Malformed Packet", ex).ConfigureAwait(false); | |||
await _audioLogger.DebugAsync("Malformed Packet", ex).ConfigureAwait(false); | |||
return; | |||
} | |||
@@ -331,7 +331,7 @@ namespace Discord.Audio | |||
{ | |||
if (pair.Key == value) | |||
{ | |||
int latency = (int)(Environment.TickCount - pair.Value); | |||
int latency = Environment.TickCount - pair.Value; | |||
int before = UdpLatency; | |||
UdpLatency = latency; | |||
@@ -344,7 +344,7 @@ namespace Discord.Audio | |||
{ | |||
if (!RTPReadStream.TryReadSsrc(packet, 0, out var ssrc)) | |||
{ | |||
await _audioLogger.DebugAsync($"Malformed Frame").ConfigureAwait(false); | |||
await _audioLogger.DebugAsync("Malformed Frame").ConfigureAwait(false); | |||
return; | |||
} | |||
if (!_ssrcMap.TryGetValue(ssrc, out var userId)) | |||
@@ -363,7 +363,7 @@ namespace Discord.Audio | |||
} | |||
catch (Exception ex) | |||
{ | |||
await _audioLogger.DebugAsync($"Malformed Frame", ex).ConfigureAwait(false); | |||
await _audioLogger.DebugAsync("Malformed Frame", ex).ConfigureAwait(false); | |||
return; | |||
} | |||
//await _audioLogger.DebugAsync($"Received {packet.Length} bytes from user {userId}").ConfigureAwait(false); | |||
@@ -372,7 +372,7 @@ namespace Discord.Audio | |||
} | |||
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; | |||
} | |||
} | |||
@@ -116,7 +116,7 @@ namespace Discord.Audio.Streams | |||
timestamp += OpusEncoder.FrameSamplesPerChannel; | |||
} | |||
#if DEBUG | |||
var _ = _logger?.DebugAsync($"Buffer underrun"); | |||
var _ = _logger?.DebugAsync("Buffer underrun"); | |||
#endif | |||
} | |||
} | |||
@@ -140,7 +140,7 @@ namespace Discord.Audio.Streams | |||
if (!_bufferPool.TryDequeue(out byte[] buffer)) | |||
{ | |||
#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 | |||
return; | |||
} | |||
@@ -149,7 +149,7 @@ namespace Discord.Audio.Streams | |||
if (!_isPreloaded && _queuedFrames.Count == _queueLength) | |||
{ | |||
#if DEBUG | |||
var _ = _logger?.DebugAsync($"Preloaded"); | |||
var _ = _logger?.DebugAsync("Preloaded"); | |||
#endif | |||
_isPreloaded = true; | |||
} | |||
@@ -169,8 +169,8 @@ namespace Discord.Audio.Streams | |||
{ | |||
do | |||
cancelToken.ThrowIfCancellationRequested(); | |||
while (_queuedFrames.TryDequeue(out Frame ignored)); | |||
while (_queuedFrames.TryDequeue(out _)); | |||
return Task.Delay(0); | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -72,7 +72,7 @@ namespace Discord.WebSocket | |||
switch (channel) | |||
{ | |||
case SocketDMChannel dmChannel: | |||
_dmChannels.TryRemove(dmChannel.Recipient.Id, out var ignored); | |||
_dmChannels.TryRemove(dmChannel.Recipient.Id, out _); | |||
break; | |||
case SocketGroupChannel groupChannel: | |||
_groupChannels.TryRemove(id); | |||
@@ -13,11 +13,11 @@ namespace Discord.WebSocket | |||
{ | |||
private readonly DiscordSocketConfig _baseConfig; | |||
private readonly SemaphoreSlim _connectionGroupLock; | |||
private readonly Dictionary<int, int> _shardIdsToIndex; | |||
private readonly bool _automaticShards; | |||
private int[] _shardIds; | |||
private Dictionary<int, int> _shardIdsToIndex; | |||
private DiscordSocketClient[] _shards; | |||
private int _totalShards; | |||
private bool _automaticShards; | |||
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary> | |||
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 { } } | |||
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 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); } } | |||
private readonly AsyncEvent<Func<Exception, Task>> _disconnectedEvent = new AsyncEvent<Func<Exception, Task>>(); | |||
private readonly bool _isExplicitUrl; | |||
private CancellationTokenSource _connectCancelToken; | |||
private string _gatewayUrl; | |||
private bool _isExplicitUrl; | |||
//Store our decompression streams for zlib shared state | |||
private MemoryStream _compressed; | |||
@@ -63,9 +63,9 @@ namespace Discord.WebSocket | |||
public override IReadOnlyCollection<SocketGuild> Guilds => State.Guilds; | |||
public override IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels => State.PrivateChannels; | |||
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 | |||
=> State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray(); | |||
=> State.PrivateChannels.OfType<SocketGroupChannel>().ToImmutableArray(); | |||
public override IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection(); | |||
/// <summary> Creates a new REST/WebSocket discord client. </summary> | |||
@@ -207,7 +207,7 @@ namespace Discord.WebSocket | |||
await heartbeatTask.ConfigureAwait(false); | |||
_heartbeatTask = null; | |||
while (_heartbeatTimes.TryDequeue(out long time)) { } | |||
while (_heartbeatTimes.TryDequeue(out _)) { } | |||
_lastMessageTime = 0; | |||
await _gatewayLogger.DebugAsync("Waiting for guild downloader").ConfigureAwait(false); | |||
@@ -218,7 +218,7 @@ namespace Discord.WebSocket | |||
//Clear large guild queue | |||
await _gatewayLogger.DebugAsync("Clearing large guild queue").ConfigureAwait(false); | |||
while (_largeGuilds.TryDequeue(out ulong guildId)) { } | |||
while (_largeGuilds.TryDequeue(out _)) { } | |||
//Raise virtual GUILD_UNAVAILABLEs | |||
await _gatewayLogger.DebugAsync("Raising virtual GuildUnavailables").ConfigureAwait(false); | |||
@@ -351,7 +351,7 @@ namespace Discord.WebSocket | |||
var gameModel = new GameModel(); | |||
// 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"); | |||
if (Activity != null) | |||
@@ -508,7 +508,7 @@ namespace Discord.WebSocket | |||
{ | |||
type = "GUILD_AVAILABLE"; | |||
_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); | |||
if (guild != null) | |||
@@ -533,7 +533,7 @@ namespace Discord.WebSocket | |||
} | |||
else | |||
{ | |||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); | |||
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_CREATE)").ConfigureAwait(false); | |||
var guild = AddGuild(data, State); | |||
if (guild != null) | |||
@@ -614,7 +614,7 @@ namespace Discord.WebSocket | |||
if (data.Unavailable == true) | |||
{ | |||
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); | |||
if (guild != null) | |||
@@ -630,7 +630,7 @@ namespace Discord.WebSocket | |||
} | |||
else | |||
{ | |||
await _gatewayLogger.DebugAsync($"Received Dispatch (GUILD_DELETE)").ConfigureAwait(false); | |||
await _gatewayLogger.DebugAsync("Received Dispatch (GUILD_DELETE)").ConfigureAwait(false); | |||
var guild = RemoveGuild(data.Id); | |||
if (guild != null) | |||
@@ -1626,7 +1626,7 @@ namespace Discord.WebSocket | |||
var guild = State.RemoveGuild(id); | |||
if (guild != null) | |||
{ | |||
foreach (var channel in guild.Channels) | |||
foreach (var _ in guild.Channels) | |||
State.RemoveChannel(id); | |||
foreach (var user in guild.Users) | |||
user.GlobalUser.RemoveRef(this); | |||
@@ -1679,7 +1679,7 @@ namespace Discord.WebSocket | |||
if (eventHandler.HasSubscribers) | |||
{ | |||
if (HandlerTimeout.HasValue) | |||
await TimeoutWrap(name, () => eventHandler.InvokeAsync()).ConfigureAwait(false); | |||
await TimeoutWrap(name, eventHandler.InvokeAsync).ConfigureAwait(false); | |||
else | |||
await eventHandler.InvokeAsync().ConfigureAwait(false); | |||
} | |||
@@ -39,8 +39,8 @@ namespace Discord.Audio | |||
private readonly JsonSerializer _serializer; | |||
private readonly SemaphoreSlim _connectionLock; | |||
private readonly IUdpSocket _udp; | |||
private CancellationTokenSource _connectCancelToken; | |||
private IUdpSocket _udp; | |||
private bool _isDisposed; | |||
private ulong _nextKeepalive; | |||
@@ -188,7 +188,7 @@ namespace Discord.Audio | |||
ConnectionState = ConnectionState.Connected; | |||
} | |||
catch (Exception) | |||
catch | |||
{ | |||
await DisconnectInternalAsync().ConfigureAwait(false); | |||
throw; | |||
@@ -97,7 +97,7 @@ namespace Discord.WebSocket | |||
if (id == Recipient.Id) | |||
return Recipient; | |||
else if (id == Discord.CurrentUser.Id) | |||
return Discord.CurrentUser as SocketSelfUser; | |||
return Discord.CurrentUser; | |||
else | |||
return null; | |||
} | |||
@@ -18,10 +18,10 @@ namespace Discord.WebSocket | |||
public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel | |||
{ | |||
private readonly MessageCache _messages; | |||
private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||
private string _iconId; | |||
private ConcurrentDictionary<ulong, SocketGroupUser> _users; | |||
private ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; | |||
public string Name { get; private set; } | |||
@@ -129,7 +129,7 @@ namespace Discord.WebSocket | |||
internal SocketGroupUser GetOrAddUser(UserModel model) | |||
{ | |||
if (_users.TryGetValue(model.Id, out SocketGroupUser user)) | |||
return user as SocketGroupUser; | |||
return user; | |||
else | |||
{ | |||
var privateUser = SocketGroupUser.Create(this, Discord.State, model); | |||
@@ -143,7 +143,7 @@ namespace Discord.WebSocket | |||
if (_users.TryRemove(id, out SocketGroupUser user)) | |||
{ | |||
user.GlobalUser.RemoveRef(Discord); | |||
return user as SocketGroupUser; | |||
return user; | |||
} | |||
return null; | |||
} | |||
@@ -91,11 +91,11 @@ namespace Discord.WebSocket | |||
} | |||
} | |||
public IReadOnlyCollection<SocketTextChannel> TextChannels | |||
=> Channels.Select(x => x as SocketTextChannel).Where(x => x != null).ToImmutableArray(); | |||
=> Channels.OfType<SocketTextChannel>().ToImmutableArray(); | |||
public IReadOnlyCollection<SocketVoiceChannel> VoiceChannels | |||
=> Channels.Select(x => x as SocketVoiceChannel).Where(x => x != null).ToImmutableArray(); | |||
=> Channels.OfType<SocketVoiceChannel>().ToImmutableArray(); | |||
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 SocketRole EveryoneRole => GetRole(Id); | |||
public IReadOnlyCollection<SocketGuildChannel> Channels | |||
@@ -563,7 +563,7 @@ namespace Discord.WebSocket | |||
await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false); | |||
} | |||
catch (Exception) | |||
catch | |||
{ | |||
await DisconnectAudioInternalAsync().ConfigureAwait(false); | |||
throw; | |||
@@ -580,7 +580,7 @@ namespace Discord.WebSocket | |||
throw new TimeoutException(); | |||
return await promise.Task.ConfigureAwait(false); | |||
} | |||
catch (Exception) | |||
catch | |||
{ | |||
await DisconnectAudioAsync().ConfigureAwait(false); | |||
throw; | |||
@@ -1,4 +1,4 @@ | |||
using System; | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
@@ -28,7 +28,7 @@ namespace Discord.WebSocket | |||
_orderedMessages.Enqueue(message.Id); | |||
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}")] | |||
public class SocketUserMessage : SocketMessage, IUserMessage | |||
{ | |||
private readonly List<SocketReaction> _reactions = new List<SocketReaction>(); | |||
private bool _isMentioningEveryone, _isTTS, _isPinned; | |||
private long? _editedTimestampTicks; | |||
private ImmutableArray<Attachment> _attachments; | |||
private ImmutableArray<Embed> _embeds; | |||
private ImmutableArray<ITag> _tags; | |||
private List<SocketReaction> _reactions = new List<SocketReaction>(); | |||
public override bool IsTTS => _isTTS; | |||
public override bool IsPinned => _isPinned; | |||
@@ -22,8 +22,8 @@ namespace Discord.Net.WebSockets | |||
private readonly SemaphoreSlim _lock; | |||
private readonly Dictionary<string, string> _headers; | |||
private readonly IWebProxy _proxy; | |||
private ClientWebSocket _client; | |||
private IWebProxy _proxy; | |||
private Task _task; | |||
private CancellationTokenSource _cancelTokenSource; | |||
private CancellationToken _cancelToken, _parentToken; | |||