diff --git a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs index 09bfdf104..c98b026ed 100644 --- a/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs +++ b/ArchiSteamFarm.CustomPlugins.ExamplePlugin/CatController.cs @@ -21,6 +21,7 @@ using System; using System.Net; +using System.Threading; using System.Threading.Tasks; using ArchiSteamFarm.Core; using ArchiSteamFarm.IPC.Controllers.Api; @@ -45,7 +46,9 @@ public sealed class CatController : ArchiController { throw new InvalidOperationException(nameof(ASF.WebBrowser)); } - Uri? url = await CatAPI.GetRandomCatURL(ASF.WebBrowser).ConfigureAwait(false); + CancellationToken cancellationToken = HttpContext.RequestAborted; + + Uri? url = await CatAPI.GetRandomCatURL(ASF.WebBrowser, cancellationToken).ConfigureAwait(false); return url != null ? Ok(new GenericResponse(url)) : StatusCode((int) HttpStatusCode.ServiceUnavailable, new GenericResponse(false)); } diff --git a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs index 8afde37c0..ea912010a 100644 --- a/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs +++ b/ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SteamTokenDumperPlugin.cs @@ -56,7 +56,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC private static readonly ConcurrentDictionary BotSubscriptions = new(); private static readonly ConcurrentDictionary BotSynchronizations = new(); private static readonly SemaphoreSlim SubmissionSemaphore = new(1, 1); - private static readonly Timer SubmissionTimer = new(SubmitData); + private static readonly Timer SubmissionTimer = new(OnSubmissionTimer); private static GlobalCache? GlobalCache; private static DateTimeOffset LastUploadAt = DateTimeOffset.MinValue; @@ -311,6 +311,8 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC await Refresh(bot, packageTokens.Keys).ConfigureAwait(false); } + private static async void OnSubmissionTimer(object? state = null) => await SubmitData().ConfigureAwait(false); + private static async Task Refresh(Bot bot, IReadOnlyCollection? packageIDs = null) { ArgumentNullException.ThrowIfNull(bot); @@ -544,7 +546,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC } } - private static async void SubmitData(object? state = null) { + private static async Task SubmitData(CancellationToken cancellationToken = default) { if (Bot.Bots == null) { throw new InvalidOperationException(nameof(Bot.Bots)); } @@ -565,7 +567,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC return; } - if (!await SubmissionSemaphore.WaitAsync(0).ConfigureAwait(false)) { + if (!await SubmissionSemaphore.WaitAsync(0, cancellationToken).ConfigureAwait(false)) { return; } @@ -593,7 +595,7 @@ internal sealed class SteamTokenDumperPlugin : OfficialPlugin, IASF, IBot, IBotC ASF.ArchiLogger.LogGenericInfo(string.Format(CultureInfo.CurrentCulture, Strings.SubmissionInProgress, appTokens.Count, packageTokens.Count, depotKeys.Count)); - ObjectResponse? response = await ASF.WebBrowser.UrlPostToJsonObject(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false); + ObjectResponse? response = await ASF.WebBrowser.UrlPostToJsonObject(request, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors, cancellationToken: cancellationToken).ConfigureAwait(false); if (response == null) { ASF.ArchiLogger.LogGenericWarning(ArchiSteamFarm.Localization.Strings.WarningFailed); diff --git a/ArchiSteamFarm/Core/ArchiNet.cs b/ArchiSteamFarm/Core/ArchiNet.cs index c2d77dd55..e410174c5 100644 --- a/ArchiSteamFarm/Core/ArchiNet.cs +++ b/ArchiSteamFarm/Core/ArchiNet.cs @@ -43,7 +43,7 @@ internal static class ArchiNet { private static readonly ArchiCacheable> CachedBadBots = new(ResolveCachedBadBots, TimeSpan.FromDays(1)); - internal static async Task FetchBuildChecksum(Version version, string variant) { + internal static async Task FetchBuildChecksum(Version version, string variant, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(version); ArgumentException.ThrowIfNullOrEmpty(variant); @@ -53,7 +53,7 @@ internal static class ArchiNet { Uri request = new(URL, $"/Api/Checksum/{version}/{variant}"); - ObjectResponse>? response = await ASF.WebBrowser.UrlGetToJsonObject>(request).ConfigureAwait(false); + ObjectResponse>? response = await ASF.WebBrowser.UrlGetToJsonObject>(request, cancellationToken: cancellationToken).ConfigureAwait(false); if (response?.Content == null) { return null; @@ -62,17 +62,17 @@ internal static class ArchiNet { return response.Content.Result ?? ""; } - internal static async Task IsBadBot(ulong steamID) { + internal static async Task IsBadBot(ulong steamID, CancellationToken cancellationToken = default) { if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) { throw new ArgumentOutOfRangeException(nameof(steamID)); } - (_, IReadOnlyCollection? badBots) = await CachedBadBots.GetValue(ECacheFallback.FailedNow).ConfigureAwait(false); + (_, IReadOnlyCollection? badBots) = await CachedBadBots.GetValue(ECacheFallback.FailedNow, cancellationToken).ConfigureAwait(false); return badBots?.Contains(steamID); } - internal static async Task SignInWithSteam(Bot bot, WebBrowser webBrowser) { + internal static async Task SignInWithSteam(Bot bot, WebBrowser webBrowser, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(bot); ArgumentNullException.ThrowIfNull(webBrowser); @@ -83,7 +83,7 @@ internal static class ArchiNet { // We expect data or redirection to Steam OpenID Uri authenticateRequest = new(URL, $"/Api/Steam/Authenticate?steamID={bot.SteamID}"); - ObjectResponse>? authenticateResponse = await webBrowser.UrlGetToJsonObject>(authenticateRequest, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections | WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false); + ObjectResponse>? authenticateResponse = await webBrowser.UrlGetToJsonObject>(authenticateRequest, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections | WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors, cancellationToken: cancellationToken).ConfigureAwait(false); if (authenticateResponse == null) { return null; @@ -98,7 +98,7 @@ internal static class ArchiNet { } // We've got a redirection, initiate OpenID procedure by following it - using HtmlDocumentResponse? challengeResponse = await bot.ArchiWebHandler.UrlGetToHtmlDocumentWithSession(authenticateResponse.FinalUri).ConfigureAwait(false); + using HtmlDocumentResponse? challengeResponse = await bot.ArchiWebHandler.UrlGetToHtmlDocumentWithSession(authenticateResponse.FinalUri, cancellationToken: cancellationToken).ConfigureAwait(false); if (challengeResponse?.Content == null) { return null; @@ -151,14 +151,14 @@ internal static class ArchiNet { data.Add(nonceContent, "nonce"); // Accept OpenID request presented and follow redirection back to the data we initially expected - BasicResponse? loginResponse = await bot.ArchiWebHandler.WebBrowser.UrlPost(loginRequest, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections).ConfigureAwait(false); + BasicResponse? loginResponse = await bot.ArchiWebHandler.WebBrowser.UrlPost(loginRequest, data: data, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections, cancellationToken: cancellationToken).ConfigureAwait(false); if (loginResponse == null) { return null; } // We've got a final redirection, follow it and complete login procedure - authenticateResponse = await webBrowser.UrlGetToJsonObject>(loginResponse.FinalUri, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors).ConfigureAwait(false); + authenticateResponse = await webBrowser.UrlGetToJsonObject>(loginResponse.FinalUri, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors, cancellationToken: cancellationToken).ConfigureAwait(false); if (authenticateResponse == null) { return null;