diff --git a/src/Discord.Net.Core/API/DiscordRestApiClient.cs b/src/Discord.Net.Core/API/DiscordRestApiClient.cs index 553cbd1c3..1a5b5b2fd 100644 --- a/src/Discord.Net.Core/API/DiscordRestApiClient.cs +++ b/src/Discord.Net.Core/API/DiscordRestApiClient.cs @@ -165,14 +165,14 @@ namespace Discord.API //Core internal Task SendAsync(string method, Expression> endpointExpr, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) - => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) + => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendAsync(string method, string endpoint, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) { options = options ?? new RequestOptions(); options.HeaderOnly = true; - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var request = new RestRequest(_restClient, method, endpoint, options); @@ -180,14 +180,14 @@ namespace Discord.API } internal Task SendJsonAsync(string method, Expression> endpointExpr, object payload, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) - => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) + => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendJsonAsync(string method, string endpoint, object payload, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) { options = options ?? new RequestOptions(); options.HeaderOnly = true; - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var json = payload != null ? SerializeJson(payload) : null; @@ -196,14 +196,14 @@ namespace Discord.API } internal Task SendMultipartAsync(string method, Expression> endpointExpr, IReadOnlyDictionary multipartArgs, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) - => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) + => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendMultipartAsync(string method, string endpoint, IReadOnlyDictionary multipartArgs, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) { options = options ?? new RequestOptions(); options.HeaderOnly = true; - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options); @@ -211,13 +211,13 @@ namespace Discord.API } internal Task SendAsync(string method, Expression> endpointExpr, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class - => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class + => SendAsync(method, GetEndpoint(endpointExpr), GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendAsync(string method, string endpoint, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) where TResponse : class + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class { options = options ?? new RequestOptions(); - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var request = new RestRequest(_restClient, method, endpoint, options); @@ -225,13 +225,13 @@ namespace Discord.API } internal Task SendJsonAsync(string method, Expression> endpointExpr, object payload, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class - => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) where TResponse : class + => SendJsonAsync(method, GetEndpoint(endpointExpr), payload, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendJsonAsync(string method, string endpoint, object payload, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) where TResponse : class + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) where TResponse : class { options = options ?? new RequestOptions(); - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var json = payload != null ? SerializeJson(payload) : null; @@ -240,13 +240,13 @@ namespace Discord.API } internal Task SendMultipartAsync(string method, Expression> endpointExpr, IReadOnlyDictionary multipartArgs, BucketIds ids, - string clientBucketId = null, RequestOptions options = null, [CallerMemberName] string funcName = null) - => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucketId, options); + ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null, [CallerMemberName] string funcName = null) + => SendMultipartAsync(method, GetEndpoint(endpointExpr), multipartArgs, GetBucketId(ids, endpointExpr, AuthTokenType, funcName), clientBucket, options); public async Task SendMultipartAsync(string method, string endpoint, IReadOnlyDictionary multipartArgs, - string bucketId = null, string clientBucketId = null, RequestOptions options = null) + string bucketId = null, ClientBucketType clientBucket = ClientBucketType.Unbucketed, RequestOptions options = null) { options = options ?? new RequestOptions(); - options.BucketId = AuthTokenType == TokenType.User ? clientBucketId : bucketId; + options.BucketId = AuthTokenType == TokenType.User ? ClientBucket.Get(clientBucket).Id : bucketId; options.IsClientBucket = AuthTokenType == TokenType.User; var request = new MultipartRestRequest(_restClient, method, endpoint, multipartArgs, options); @@ -445,7 +445,7 @@ namespace Discord.API options = RequestOptions.CreateOrClone(options); var ids = new BucketIds(channelId: channelId); - return await SendJsonAsync("POST", () => $"channels/{channelId}/messages", args, ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false); + return await SendJsonAsync("POST", () => $"channels/{channelId}/messages", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); } public async Task UploadFileAsync(ulong channelId, UploadFileParams args, RequestOptions options = null) { @@ -464,7 +464,7 @@ namespace Discord.API } var ids = new BucketIds(channelId: channelId); - return await SendMultipartAsync("POST", () => $"channels/{channelId}/messages", args.ToDictionary(), ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false); + return await SendMultipartAsync("POST", () => $"channels/{channelId}/messages", args.ToDictionary(), ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); } public async Task DeleteMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null) { @@ -510,7 +510,7 @@ namespace Discord.API options = RequestOptions.CreateOrClone(options); var ids = new BucketIds(channelId: channelId); - return await SendJsonAsync("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucketId: ClientBucket.SendEditId, options: options).ConfigureAwait(false); + return await SendJsonAsync("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); } public async Task AckMessageAsync(ulong channelId, ulong messageId, RequestOptions options = null) { diff --git a/src/Discord.Net.Core/Net/Queue/ClientBucket.cs b/src/Discord.Net.Core/Net/Queue/ClientBucket.cs index 14d3c3207..f32df1bcf 100644 --- a/src/Discord.Net.Core/Net/Queue/ClientBucket.cs +++ b/src/Discord.Net.Core/Net/Queue/ClientBucket.cs @@ -2,25 +2,47 @@ namespace Discord.Net.Queue { - public struct ClientBucket + public enum ClientBucketType { - public const string SendEditId = ""; + Unbucketed = 0, + SendEdit = 1 + } + internal struct ClientBucket + { + private static readonly ImmutableDictionary _defsByType; + private static readonly ImmutableDictionary _defsById; - private static readonly ImmutableDictionary _defs; static ClientBucket() { - var builder = ImmutableDictionary.CreateBuilder(); - builder.Add(SendEditId, new ClientBucket(10, 10)); - _defs = builder.ToImmutable(); - } + var buckets = new[] + { + new ClientBucket(ClientBucketType.Unbucketed, "", 10, 10), + new ClientBucket(ClientBucketType.SendEdit, "", 10, 10) + }; - public static ClientBucket Get(string id) =>_defs[id]; + var builder = ImmutableDictionary.CreateBuilder(); + foreach (var bucket in buckets) + builder.Add(bucket.Type, bucket); + _defsByType = builder.ToImmutable(); + + var builder2 = ImmutableDictionary.CreateBuilder(); + foreach (var bucket in buckets) + builder2.Add(bucket.Id, bucket); + _defsById = builder2.ToImmutable(); + } + public static ClientBucket Get(ClientBucketType type) => _defsByType[type]; + public static ClientBucket Get(string id) => _defsById[id]; + + public ClientBucketType Type { get; } + public string Id { get; } public int WindowCount { get; } public int WindowSeconds { get; } - public ClientBucket(int count, int seconds) + public ClientBucket(ClientBucketType type, string id, int count, int seconds) { + Type = type; + Id = id; WindowCount = count; WindowSeconds = seconds; }