@@ -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; | ||||