| @@ -1,4 +1,4 @@ | |||||
| using System.Runtime.CompilerServices; | |||||
| using System.Runtime.CompilerServices; | |||||
| namespace Discord | namespace Discord | ||||
| { | { | ||||
| @@ -151,7 +151,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)) | ||||
| { | { | ||||
| @@ -167,7 +167,7 @@ namespace Discord | |||||
| resolvedPermissions &= ~(ulong)ChannelPermission.AttachFiles; | resolvedPermissions &= ~(ulong)ChannelPermission.AttachFiles; | ||||
| } | } | ||||
| } | } | ||||
| resolvedPermissions &= mask; //Ensure we didnt get any permissions this channel doesnt support (from guildPerms, for example) | |||||
| resolvedPermissions &= mask; //Ensure we didn't get any permissions this channel doesn't support (from guildPerms, for example) | |||||
| } | } | ||||
| return resolvedPermissions; | return resolvedPermissions; | ||||
| @@ -58,7 +58,7 @@ namespace Discord.Rest | |||||
| ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false); | ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false); | ||||
| } | } | ||||
| public async Task LoginAsync(TokenType tokenType, string token, bool validateToken = true) | |||||
| public async Task LoginAsync(TokenType tokenType, string token) | |||||
| { | { | ||||
| await _stateLock.WaitAsync().ConfigureAwait(false); | await _stateLock.WaitAsync().ConfigureAwait(false); | ||||
| try | try | ||||
| @@ -85,7 +85,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; | ||||
| @@ -49,7 +49,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, | ||||
| @@ -127,7 +127,7 @@ namespace Discord.API | |||||
| LoginState = LoginState.LoggedIn; | LoginState = LoginState.LoggedIn; | ||||
| } | } | ||||
| catch (Exception) | |||||
| catch | |||||
| { | { | ||||
| await LogoutInternalAsync().ConfigureAwait(false); | await LogoutInternalAsync().ConfigureAwait(false); | ||||
| throw; | throw; | ||||
| @@ -168,7 +168,7 @@ namespace Discord.API | |||||
| //Core | //Core | ||||
| internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | internal Task SendAsync(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ||||
| => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task SendAsync(string method, string endpoint, | public async Task SendAsync(string method, string endpoint, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -182,7 +182,7 @@ namespace Discord.API | |||||
| internal Task SendJsonAsync(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids, | internal Task SendJsonAsync(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ||||
| => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task SendJsonAsync(string method, string endpoint, object payload, | public async Task SendJsonAsync(string method, string endpoint, object payload, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -197,7 +197,7 @@ namespace Discord.API | |||||
| internal Task SendMultipartAsync(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids, | internal Task SendMultipartAsync(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ||||
| => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task SendMultipartAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs, | public async Task SendMultipartAsync(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -211,7 +211,7 @@ namespace Discord.API | |||||
| internal Task<TResponse> SendAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | internal Task<TResponse> SendAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class | ||||
| => SendAsync<TResponse>(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendAsync<TResponse>(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task<TResponse> SendAsync<TResponse>(string method, string endpoint, | public async Task<TResponse> SendAsync<TResponse>(string method, string endpoint, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class | ||||
| { | { | ||||
| @@ -224,7 +224,7 @@ namespace Discord.API | |||||
| internal Task<TResponse> SendJsonAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids, | internal Task<TResponse> SendJsonAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, object payload, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class | ||||
| => SendJsonAsync<TResponse>(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendJsonAsync<TResponse>(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task<TResponse> SendJsonAsync<TResponse>(string method, string endpoint, object payload, | public async Task<TResponse> SendJsonAsync<TResponse>(string method, string endpoint, object payload, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class | ||||
| { | { | ||||
| @@ -238,7 +238,7 @@ namespace Discord.API | |||||
| internal Task<TResponse> SendMultipartAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids, | internal Task<TResponse> SendMultipartAsync<TResponse>(string method, Expression<Func<string>> endpointExpr, IReadOnlyDictionary<string, object> multipartArgs, BucketIds ids, | ||||
| ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) | ||||
| => SendMultipartAsync<TResponse>(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); | |||||
| => SendMultipartAsync<TResponse>(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, funcName), clientBucket, options); | |||||
| public async Task<TResponse> SendMultipartAsync<TResponse>(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs, | public async Task<TResponse> SendMultipartAsync<TResponse>(string method, string endpoint, IReadOnlyDictionary<string, object> multipartArgs, | ||||
| string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) | ||||
| { | { | ||||
| @@ -1354,7 +1354,7 @@ namespace Discord.API | |||||
| { | { | ||||
| return endpointExpr.Compile()(); | return endpointExpr.Compile()(); | ||||
| } | } | ||||
| private static string GetBucketId(BucketIds ids, Expression<Func<string>> endpointExpr, TokenType tokenType, string callingMethod) | |||||
| private static string GetBucketId(BucketIds ids, Expression<Func<string>> endpointExpr, string callingMethod) | |||||
| { | { | ||||
| return _bucketIdGenerators.GetOrAdd(callingMethod, x => CreateBucketId(endpointExpr))(ids); | return _bucketIdGenerators.GetOrAdd(callingMethod, x => CreateBucketId(endpointExpr))(ids); | ||||
| } | } | ||||
| @@ -1416,7 +1416,7 @@ namespace Discord.API | |||||
| } | } | ||||
| catch (Exception ex) | catch (Exception ex) | ||||
| { | { | ||||
| throw new InvalidOperationException("Failed to generate the bucket id for this operation", ex); | |||||
| throw new InvalidOperationException("Failed to generate the bucket id for this operation.", ex); | |||||
| } | } | ||||
| } | } | ||||
| @@ -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).ConfigureAwait(false); //Runs each minute | await Task.Delay(60000, _cancelToken.Token).ConfigureAwait(false); //Runs each minute | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -425,7 +425,6 @@ namespace Discord.Audio | |||||
| } | } | ||||
| private async Task RunKeepaliveAsync(int intervalMillis, CancellationToken cancelToken) | private async Task RunKeepaliveAsync(int intervalMillis, CancellationToken cancelToken) | ||||
| { | { | ||||
| var packet = new byte[8]; | |||||
| try | try | ||||
| { | { | ||||
| await _audioLogger.DebugAsync("Keepalive Started").ConfigureAwait(false); | await _audioLogger.DebugAsync("Keepalive Started").ConfigureAwait(false); | ||||
| @@ -169,7 +169,7 @@ 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); | ||||
| } | } | ||||
| } | } | ||||
| @@ -14,10 +14,10 @@ namespace Discord.WebSocket | |||||
| private readonly DiscordSocketConfig _baseConfig; | private readonly DiscordSocketConfig _baseConfig; | ||||
| private readonly SemaphoreSlim _connectionGroupLock; | private readonly SemaphoreSlim _connectionGroupLock; | ||||
| private int[] _shardIds; | private int[] _shardIds; | ||||
| private Dictionary<int, int> _shardIdsToIndex; | |||||
| private readonly Dictionary<int, int> _shardIdsToIndex; | |||||
| private DiscordSocketClient[] _shards; | private DiscordSocketClient[] _shards; | ||||
| private int _totalShards; | private int _totalShards; | ||||
| private bool _automaticShards; | |||||
| private readonly bool _automaticShards; | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override int Latency { get => GetLatency(); protected set { } } | public override int Latency { get => GetLatency(); protected set { } } | ||||
| @@ -26,7 +26,7 @@ namespace Discord.WebSocket | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| 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; | |||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(GetGuildCount); | public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(GetGuildCount); | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| @@ -95,13 +95,13 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| } | } | ||||
| //Assume threadsafe: already in a connection lock | |||||
| //Assume thread safe: already in a connection lock | |||||
| for (int i = 0; i < _shards.Length; i++) | for (int i = 0; i < _shards.Length; i++) | ||||
| await _shards[i].LoginAsync(tokenType, token, false); | |||||
| await _shards[i].LoginAsync(tokenType, token); | |||||
| } | } | ||||
| internal override async Task OnLogoutAsync() | internal override async Task OnLogoutAsync() | ||||
| { | { | ||||
| //Assume threadsafe: already in a connection lock | |||||
| //Assume thread safe: already in a connection lock | |||||
| if (_shards != null) | if (_shards != null) | ||||
| { | { | ||||
| for (int i = 0; i < _shards.Length; i++) | for (int i = 0; i < _shards.Length; i++) | ||||
| @@ -218,11 +218,11 @@ namespace Discord.WebSocket | |||||
| public override RestVoiceRegion GetVoiceRegion(string id) | public override RestVoiceRegion GetVoiceRegion(string id) | ||||
| => _shards[0].GetVoiceRegion(id); | => _shards[0].GetVoiceRegion(id); | ||||
| /// <summary> | |||||
| /// Downloads the users list for the provided guilds if they don't have a complete list. | |||||
| /// </summary> | |||||
| /// <inheritdoc /> | |||||
| /// <exception cref="ArgumentNullException"><paramref name="guilds"/> is <see langword="null"/></exception> | |||||
| public override async Task DownloadUsersAsync(IEnumerable<IGuild> guilds) | public override async Task DownloadUsersAsync(IEnumerable<IGuild> guilds) | ||||
| { | { | ||||
| if (guilds == null) throw new ArgumentNullException(nameof(guilds)); | |||||
| for (int i = 0; i < _shards.Length; i++) | for (int i = 0; i < _shards.Length; i++) | ||||
| { | { | ||||
| int id = _shardIds[i]; | int id = _shardIds[i]; | ||||
| @@ -217,7 +217,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); | ||||
| @@ -228,7 +228,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); | ||||
| @@ -1636,7 +1636,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); | ||||
| @@ -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; | ||||