diff --git a/src/Discord.Net.Rest/API/Common/Ratelimit.cs b/src/Discord.Net.Rest/API/Common/Ratelimit.cs new file mode 100644 index 000000000..a7320cbe1 --- /dev/null +++ b/src/Discord.Net.Rest/API/Common/Ratelimit.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Discord.API +{ + internal class Ratelimit + { + [JsonProperty("global")] + public bool Global { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("retry_after")] + public double RetryAfter { get; set; } + } +} diff --git a/src/Discord.Net.Rest/Net/DefaultRestClient.cs b/src/Discord.Net.Rest/Net/DefaultRestClient.cs index ce32b085b..721c7009d 100644 --- a/src/Discord.Net.Rest/Net/DefaultRestClient.cs +++ b/src/Discord.Net.Rest/Net/DefaultRestClient.cs @@ -149,7 +149,7 @@ namespace Discord.Net.Rest HttpResponseMessage response = await _client.SendAsync(request, cancelToken).ConfigureAwait(false); var headers = response.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase); - var stream = !headerOnly ? await response.Content.ReadAsStreamAsync().ConfigureAwait(false) : null; + var stream = (!headerOnly || !response.IsSuccessStatusCode) ? await response.Content.ReadAsStreamAsync().ConfigureAwait(false) : null; return new RestResponse(response.StatusCode, headers, stream); } diff --git a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs index 408c8bbdb..8130e6fac 100644 --- a/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs +++ b/src/Discord.Net.Rest/Net/Queue/RequestQueueBucket.cs @@ -75,6 +75,7 @@ namespace Discord.Net.Queue switch (response.StatusCode) { case (HttpStatusCode)429: + info.ReadRatelimitPayload(response.Stream); if (info.IsGlobal) { #if DEBUG_LIMITS diff --git a/src/Discord.Net.Rest/Net/RateLimitInfo.cs b/src/Discord.Net.Rest/Net/RateLimitInfo.cs index c08f30c7b..253343311 100644 --- a/src/Discord.Net.Rest/Net/RateLimitInfo.cs +++ b/src/Discord.Net.Rest/Net/RateLimitInfo.cs @@ -1,6 +1,10 @@ +using Discord.API; +using Discord.Net.Rest; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Globalization; +using System.IO; namespace Discord.Net { @@ -25,7 +29,7 @@ namespace Discord.Net public DateTimeOffset? Reset { get; } /// - public TimeSpan? ResetAfter { get; } + public TimeSpan? ResetAfter { get; private set; } /// public string Bucket { get; } @@ -56,5 +60,23 @@ namespace Discord.Net Lag = headers.TryGetValue("Date", out temp) && DateTimeOffset.TryParse(temp, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) ? DateTimeOffset.UtcNow - date : (TimeSpan?)null; } + + internal void ReadRatelimitPayload(Stream response) + { + try + { + if (response != null && response.Length != 0) + { + using (TextReader text = new StreamReader(response)) + using (JsonReader reader = new JsonTextReader(text)) + { + var ratelimit = Discord.Rest.DiscordRestClient.Serializer.Deserialize(reader); + + ResetAfter = TimeSpan.FromSeconds(ratelimit.RetryAfter); + } + } + } + catch { } + } } }