From 4d9389b3aa8a5c0930488b44078b4f637cb24cd5 Mon Sep 17 00:00:00 2001 From: Quin Lynch <49576606+quinchs@users.noreply.github.com> Date: Fri, 14 Jan 2022 07:55:57 -0400 Subject: [PATCH] Add default ratelimit callback (#2037) --- src/Discord.Net.Core/DiscordConfig.cs | 10 ++++++++++ src/Discord.Net.Rest/DiscordRestApiClient.cs | 12 +++++++----- src/Discord.Net.Rest/DiscordRestClient.cs | 2 +- src/Discord.Net.WebSocket/BaseSocketClient.cs | 4 ++-- src/Discord.Net.WebSocket/DiscordShardedClient.cs | 3 ++- src/Discord.Net.WebSocket/DiscordSocketApiClient.cs | 4 ++-- src/Discord.Net.WebSocket/DiscordSocketClient.cs | 3 ++- src/Discord.Net.Webhook/DiscordWebhookClient.cs | 2 +- 8 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/Discord.Net.Core/DiscordConfig.cs b/src/Discord.Net.Core/DiscordConfig.cs index d5951bd07..34bfc5e62 100644 --- a/src/Discord.Net.Core/DiscordConfig.cs +++ b/src/Discord.Net.Core/DiscordConfig.cs @@ -1,4 +1,6 @@ +using System; using System.Reflection; +using System.Threading.Tasks; namespace Discord { @@ -131,6 +133,14 @@ namespace Discord /// public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry; + /// + /// Gets or sets the default callback for ratelimits. + /// + /// + /// This property is mutually exclusive with . + /// + public Func DefaultRatelimitCallback { get; set; } + /// /// Gets or sets the minimum log level severity that will be sent to the Log event. /// diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs index c9a4d6c30..69f150ab6 100644 --- a/src/Discord.Net.Rest/DiscordRestApiClient.cs +++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs @@ -46,17 +46,19 @@ namespace Discord.API internal IRestClient RestClient { get; private set; } internal ulong? CurrentUserId { get; set; } internal bool UseSystemClock { get; set; } + internal Func DefaultRatelimitCallback { get; set; } internal JsonSerializer Serializer => _serializer; /// Unknown OAuth token type. public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, - JsonSerializer serializer = null, bool useSystemClock = true) + JsonSerializer serializer = null, bool useSystemClock = true, Func defaultRatelimitCallback = null) { _restClientProvider = restClientProvider; UserAgent = userAgent; DefaultRetryMode = defaultRetryMode; _serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() }; UseSystemClock = useSystemClock; + DefaultRatelimitCallback = defaultRatelimitCallback; RequestQueue = new RequestQueue(); _stateLock = new SemaphoreSlim(1, 1); @@ -279,10 +281,10 @@ namespace Discord.API { if (!request.Options.IgnoreState) CheckState(); - if (request.Options.RetryMode == null) - request.Options.RetryMode = DefaultRetryMode; - if (request.Options.UseSystemClock == null) - request.Options.UseSystemClock = UseSystemClock; + + request.Options.RetryMode ??= DefaultRetryMode; + request.Options.UseSystemClock ??= UseSystemClock; + request.Options.RatelimitCallback ??= DefaultRatelimitCallback; var stopwatch = Stopwatch.StartNew(); var responseStream = await RequestQueue.SendAsync(request).ConfigureAwait(false); diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs index cd2033c8c..3b4f7628d 100644 --- a/src/Discord.Net.Rest/DiscordRestClient.cs +++ b/src/Discord.Net.Rest/DiscordRestClient.cs @@ -37,7 +37,7 @@ namespace Discord.Rest internal DiscordRestClient(DiscordRestConfig config, API.DiscordRestApiClient api) : base(config, api) { } private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config) - => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, serializer: Serializer, useSystemClock: config.UseSystemClock); + => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, serializer: Serializer, useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback); internal override void Dispose(bool disposing) { diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs index 9e25ab382..20acd85dd 100644 --- a/src/Discord.Net.WebSocket/BaseSocketClient.cs +++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs @@ -79,8 +79,8 @@ namespace Discord.WebSocket internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client) : base(config, client) => BaseConfig = config; private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) - => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, - useSystemClock: config.UseSystemClock); + => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost, + useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback); /// /// Gets a Discord application information for the logged-in user. diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs index 6e943dde3..e573a2593 100644 --- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs +++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs @@ -107,7 +107,8 @@ namespace Discord.WebSocket } } private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) - => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent); + => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost, + useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback); internal async Task AcquireIdentifyLockAsync(int shardId, CancellationToken token) { diff --git a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs index bf15967d3..cad6e5daa 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs @@ -39,8 +39,8 @@ namespace Discord.API public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent, string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null, - bool useSystemClock = true) - : base(restClientProvider, userAgent, defaultRetryMode, serializer, useSystemClock) + bool useSystemClock = true, Func defaultRatelimitCallback = null) + : base(restClientProvider, userAgent, defaultRetryMode, serializer, useSystemClock, defaultRatelimitCallback) { _gatewayUrl = url; if (url != null) diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 10bf88d74..6c584f66e 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -195,7 +195,8 @@ namespace Discord.WebSocket _largeGuilds = new ConcurrentQueue(); } private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) - => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost); + => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost, + useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback); /// internal override void Dispose(bool disposing) { diff --git a/src/Discord.Net.Webhook/DiscordWebhookClient.cs b/src/Discord.Net.Webhook/DiscordWebhookClient.cs index cb24f9ea1..f7bc38587 100644 --- a/src/Discord.Net.Webhook/DiscordWebhookClient.cs +++ b/src/Discord.Net.Webhook/DiscordWebhookClient.cs @@ -83,7 +83,7 @@ namespace Discord.Webhook ApiClient.SentRequest += async (method, endpoint, millis) => await _restLogger.VerboseAsync($"{method} {endpoint}: {millis} ms").ConfigureAwait(false); } private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config) - => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent); + => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, useSystemClock: config.UseSystemClock, defaultRatelimitCallback: config.DefaultRatelimitCallback); /// Sends a message to the channel for this webhook. /// Returns the ID of the created message. public Task SendMessageAsync(string text = null, bool isTTS = false, IEnumerable embeds = null,