From 6b21b11f7d2fe4ffb93ae6c394d78bc7c7dcb75b Mon Sep 17 00:00:00 2001 From: Christopher F Date: Sun, 30 Sep 2018 17:10:10 -0400 Subject: [PATCH] feature: adjust the ratelimit for reactions (#1108) * feature: adjust the ratelimit for reactions allows users to add reactions quickly * fix: don't force DEBUG_LIMITS * fix: undefined behavior using DateTime on intel architerctures it's fine * fix: ensure add/del rxn ends up in the same bucket --- src/Discord.Net.Core/RequestOptions.cs | 3 ++- src/Discord.Net.Rest/DiscordRestApiClient.cs | 10 ++++++++-- src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs | 4 ++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Discord.Net.Core/RequestOptions.cs b/src/Discord.Net.Core/RequestOptions.cs index 5f3a8814b..40f0ebaa4 100644 --- a/src/Discord.Net.Core/RequestOptions.cs +++ b/src/Discord.Net.Core/RequestOptions.cs @@ -1,4 +1,4 @@ -using System.Threading; +using System.Threading; namespace Discord { @@ -22,6 +22,7 @@ namespace Discord internal bool IgnoreState { get; set; } internal string BucketId { get; set; } internal bool IsClientBucket { get; set; } + internal bool IsReactionBucket { get; set; } internal static RequestOptions CreateOrClone(RequestOptions options) { diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index 249e8e946..1679579b2 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -580,6 +580,7 @@ namespace Discord.API var ids = new BucketIds(channelId: channelId); return await SendJsonAsync("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false); } + public async Task AddReactionAsync(ulong channelId, ulong messageId, string emoji, RequestOptions options = null) { Preconditions.NotEqual(channelId, 0, nameof(channelId)); @@ -587,10 +588,13 @@ namespace Discord.API Preconditions.NotNullOrWhitespace(emoji, nameof(emoji)); options = RequestOptions.CreateOrClone(options); + options.IsReactionBucket = true; var ids = new BucketIds(channelId: channelId); - await SendAsync("PUT", () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}/@me", ids, options: options).ConfigureAwait(false); + // @me is non-const to fool the ratelimiter, otherwise it will put add/remove in separate buckets + var me = "@me"; + await SendAsync("PUT", () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}/{me}", ids, options: options).ConfigureAwait(false); } public async Task RemoveReactionAsync(ulong channelId, ulong messageId, ulong userId, string emoji, RequestOptions options = null) { @@ -599,10 +603,12 @@ namespace Discord.API Preconditions.NotNullOrWhitespace(emoji, nameof(emoji)); options = RequestOptions.CreateOrClone(options); + options.IsReactionBucket = true; var ids = new BucketIds(channelId: channelId); - await SendAsync("DELETE", () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}/{userId}", ids, options: options).ConfigureAwait(false); + var user = CurrentUserId.HasValue ? (userId == CurrentUserId.Value ? "@me" : userId.ToString()) : userId.ToString(); + await SendAsync("DELETE", () => $"channels/{channelId}/messages/{messageId}/reactions/{emoji}/{user}", ids, options: options).ConfigureAwait(false); } public async Task RemoveAllReactionsAsync(ulong channelId, ulong messageId, RequestOptions options = null) { diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs index c4f5996c5..d7f9779a4 100644 --- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs +++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs @@ -250,6 +250,10 @@ namespace Discord.Net.Queue else if (info.Reset.HasValue) { resetTick = info.Reset.Value.AddSeconds(info.Lag?.TotalSeconds ?? 1.0); + + if (request.Options.IsReactionBucket) + resetTick = DateTimeOffset.Now.AddMilliseconds(250); + int diff = (int)(resetTick.Value - DateTimeOffset.UtcNow).TotalMilliseconds; #if DEBUG_LIMITS Debug.WriteLine($"[{id}] X-RateLimit-Reset: {info.Reset.Value.ToUnixTimeSeconds()} ({diff} ms, {info.Lag?.TotalMilliseconds} ms lag)");