This commit is contained in:
Archi 2023-11-14 21:10:35 +01:00
parent 263c77da12
commit adbf0748f8
No known key found for this signature in database
GPG key ID: 6B138B4C64555AEA
5 changed files with 31 additions and 29 deletions

View file

@ -26,6 +26,7 @@ using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ArchiSteamFarm.Core;
using ArchiSteamFarm.Helpers;
@ -324,14 +325,14 @@ internal sealed class GlobalCache : SerializableFile {
return (depotKey.Length == 64) && Utilities.IsValidHexadecimalText(depotKey);
}
private static async Task<(bool Success, ImmutableHashSet<uint>? Result)> ResolveKnownDepotIDs() {
private static async Task<(bool Success, ImmutableHashSet<uint>? Result)> ResolveKnownDepotIDs(CancellationToken cancellationToken = default) {
if (ASF.WebBrowser == null) {
throw new InvalidOperationException(nameof(ASF.WebBrowser));
}
Uri request = new($"{SharedInfo.ServerURL}/knowndepots.csv");
StreamResponse? response = await ASF.WebBrowser.UrlGetToStream(request).ConfigureAwait(false);
StreamResponse? response = await ASF.WebBrowser.UrlGetToStream(request, cancellationToken: cancellationToken).ConfigureAwait(false);
if (response?.Content == null) {
return (false, null);
@ -341,7 +342,7 @@ internal sealed class GlobalCache : SerializableFile {
try {
using StreamReader reader = new(response.Content);
string? countText = await reader.ReadLineAsync().ConfigureAwait(false);
string? countText = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(countText) || !int.TryParse(countText, out int count) || (count <= 0)) {
ASF.ArchiLogger.LogNullError(countText);
@ -351,7 +352,7 @@ internal sealed class GlobalCache : SerializableFile {
HashSet<uint> result = new(count);
while (await reader.ReadLineAsync().ConfigureAwait(false) is { Length: > 0 } line) {
while (await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false) is { Length: > 0 } line) {
if (!uint.TryParse(line, out uint depotID) || (depotID == 0)) {
ASF.ArchiLogger.LogNullError(depotID);

View file

@ -25,6 +25,7 @@ using System.Collections.Immutable;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using AngleSharp.Dom;
using ArchiSteamFarm.Helpers;
@ -170,7 +171,7 @@ internal static class ArchiNet {
return authenticateResponse.Content?.Result == bot.SteamID ? HttpStatusCode.OK : HttpStatusCode.Unauthorized;
}
private static async Task<(bool Success, IReadOnlyCollection<ulong>? Result)> ResolveCachedBadBots() {
private static async Task<(bool Success, IReadOnlyCollection<ulong>? Result)> ResolveCachedBadBots(CancellationToken cancellationToken = default) {
if (ASF.GlobalDatabase == null) {
throw new InvalidOperationException(nameof(ASF.WebBrowser));
}
@ -181,7 +182,7 @@ internal static class ArchiNet {
Uri request = new(URL, "/Api/BadBots");
ObjectResponse<GenericResponse<ImmutableHashSet<ulong>>>? response = await ASF.WebBrowser.UrlGetToJsonObject<GenericResponse<ImmutableHashSet<ulong>>>(request).ConfigureAwait(false);
ObjectResponse<GenericResponse<ImmutableHashSet<ulong>>>? response = await ASF.WebBrowser.UrlGetToJsonObject<GenericResponse<ImmutableHashSet<ulong>>>(request, cancellationToken: cancellationToken).ConfigureAwait(false);
if (response?.Content?.Result == null) {
return (false, ASF.GlobalDatabase.CachedBadBots);

View file

@ -30,7 +30,7 @@ namespace ArchiSteamFarm.Helpers;
public sealed class ArchiCacheable<T> : IDisposable {
private readonly TimeSpan CacheLifetime;
private readonly SemaphoreSlim InitSemaphore = new(1, 1);
private readonly Func<Task<(bool Success, T? Result)>> ResolveFunction;
private readonly Func<CancellationToken, Task<(bool Success, T? Result)>> ResolveFunction;
private bool IsInitialized => InitializedAt > DateTime.MinValue;
private bool IsPermanentCache => CacheLifetime == Timeout.InfiniteTimeSpan;
@ -39,7 +39,7 @@ public sealed class ArchiCacheable<T> : IDisposable {
private DateTime InitializedAt;
private T? InitializedValue;
public ArchiCacheable(Func<Task<(bool Success, T? Result)>> resolveFunction, TimeSpan? cacheLifetime = null) {
public ArchiCacheable(Func<CancellationToken, Task<(bool Success, T? Result)>> resolveFunction, TimeSpan? cacheLifetime = null) {
ArgumentNullException.ThrowIfNull(resolveFunction);
ResolveFunction = resolveFunction;
@ -49,7 +49,7 @@ public sealed class ArchiCacheable<T> : IDisposable {
public void Dispose() => InitSemaphore.Dispose();
[PublicAPI]
public async Task<(bool Success, T? Result)> GetValue(ECacheFallback cacheFallback = ECacheFallback.DefaultForType) {
public async Task<(bool Success, T? Result)> GetValue(ECacheFallback cacheFallback = ECacheFallback.DefaultForType, CancellationToken cancellationToken = default) {
if (!Enum.IsDefined(cacheFallback)) {
throw new InvalidEnumArgumentException(nameof(cacheFallback), (int) cacheFallback, typeof(ECacheFallback));
}
@ -58,14 +58,14 @@ public sealed class ArchiCacheable<T> : IDisposable {
return (true, InitializedValue);
}
await InitSemaphore.WaitAsync().ConfigureAwait(false);
await InitSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try {
if (IsInitialized && IsRecent) {
return (true, InitializedValue);
}
(bool success, T? result) = await ResolveFunction().ConfigureAwait(false);
(bool success, T? result) = await ResolveFunction(cancellationToken).ConfigureAwait(false);
if (!success) {
return cacheFallback switch {
@ -86,12 +86,12 @@ public sealed class ArchiCacheable<T> : IDisposable {
}
[PublicAPI]
public async Task Reset() {
public async Task Reset(CancellationToken cancellationToken = default) {
if (!IsInitialized) {
return;
}
await InitSemaphore.WaitAsync().ConfigureAwait(false);
await InitSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try {
if (!IsInitialized) {

View file

@ -2275,9 +2275,9 @@ public sealed class ArchiWebHandler : IDisposable {
internal void OnDisconnected() {
Initialized = false;
Utilities.InBackground(CachedAccessToken.Reset);
Utilities.InBackground(CachedApiKey.Reset);
Utilities.InBackground(CachedEconomyBan.Reset);
Utilities.InBackground(() => CachedAccessToken.Reset());
Utilities.InBackground(() => CachedApiKey.Reset());
Utilities.InBackground(() => CachedEconomyBan.Reset());
}
internal void OnVanityURLChanged(string? vanityURL = null) => VanityURL = !string.IsNullOrEmpty(vanityURL) ? vanityURL : null;
@ -2329,10 +2329,10 @@ public sealed class ArchiWebHandler : IDisposable {
return response?.Content?.Result == EResult.OK;
}
private async Task<(ESteamApiKeyState State, string? Key)> GetApiKeyState() {
private async Task<(ESteamApiKeyState State, string? Key)> GetApiKeyState(CancellationToken cancellationToken = default) {
Uri request = new(SteamCommunityURL, "/dev/apikey?l=english");
using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false).ConfigureAwait(false);
using HtmlDocumentResponse? response = await UrlGetToHtmlDocumentWithSession(request, checkSessionPreemptively: false, cancellationToken: cancellationToken).ConfigureAwait(false);
if (response?.Content == null) {
return (ESteamApiKeyState.Timeout, null);
@ -2611,21 +2611,21 @@ public sealed class ArchiWebHandler : IDisposable {
return await UrlPostWithSession(request, data: data).ConfigureAwait(false);
}
private async Task<(bool Success, string? Result)> ResolveAccessToken() {
private async Task<(bool Success, string? Result)> ResolveAccessToken(CancellationToken cancellationToken = default) {
Uri request = new(SteamStoreURL, "/pointssummary/ajaxgetasyncconfig");
ObjectResponse<AccessTokenResponse>? response = await UrlGetToJsonObjectWithSession<AccessTokenResponse>(request).ConfigureAwait(false);
ObjectResponse<AccessTokenResponse>? response = await UrlGetToJsonObjectWithSession<AccessTokenResponse>(request, cancellationToken: cancellationToken).ConfigureAwait(false);
return !string.IsNullOrEmpty(response?.Content?.Data.WebAPIToken) ? (true, response.Content.Data.WebAPIToken) : (false, null);
}
private async Task<(bool Success, string? Result)> ResolveApiKey() {
private async Task<(bool Success, string? Result)> ResolveApiKey(CancellationToken cancellationToken = default) {
if (Bot.IsAccountLimited) {
// API key is permanently unavailable for limited accounts
return (true, null);
}
(ESteamApiKeyState State, string? Key) result = await GetApiKeyState().ConfigureAwait(false);
(ESteamApiKeyState State, string? Key) result = await GetApiKeyState(cancellationToken).ConfigureAwait(false);
switch (result.State) {
case ESteamApiKeyState.AccessDenied:
@ -2641,7 +2641,7 @@ public sealed class ArchiWebHandler : IDisposable {
}
// We should have the key ready, so let's fetch it again
result = await GetApiKeyState().ConfigureAwait(false);
result = await GetApiKeyState(cancellationToken).ConfigureAwait(false);
if (result.State == ESteamApiKeyState.Timeout) {
// Request timed out, bad luck, we'll try again later
@ -2669,8 +2669,8 @@ public sealed class ArchiWebHandler : IDisposable {
}
}
private async Task<(bool Success, bool? Result)> ResolveEconomyBan() {
(_, string? steamApiKey) = await CachedApiKey.GetValue(ECacheFallback.SuccessPreviously).ConfigureAwait(false);
private async Task<(bool Success, bool? Result)> ResolveEconomyBan(CancellationToken cancellationToken = default) {
(_, string? steamApiKey) = await CachedApiKey.GetValue(ECacheFallback.SuccessPreviously, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(steamApiKey)) {
return (false, null);
@ -2680,7 +2680,7 @@ public sealed class ArchiWebHandler : IDisposable {
byte connectionTimeout = ASF.GlobalConfig?.ConnectionTimeout ?? GlobalConfig.DefaultConnectionTimeout;
for (byte i = 0; (i < connectionTimeout) && !Initialized && Bot.IsConnectedAndLoggedOn; i++) {
await Task.Delay(1000).ConfigureAwait(false);
await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
}
if (!Initialized) {
@ -2699,7 +2699,7 @@ public sealed class ArchiWebHandler : IDisposable {
for (byte i = 0; (i < WebBrowser.MaxTries) && (response == null); i++) {
if ((i > 0) && (WebLimiterDelay > 0)) {
await Task.Delay(WebLimiterDelay).ConfigureAwait(false);
await Task.Delay(WebLimiterDelay, cancellationToken).ConfigureAwait(false);
}
using WebAPI.AsyncInterface service = Bot.SteamConfiguration.GetAsyncWebAPIInterface(SteamUserService);
@ -2711,7 +2711,7 @@ public sealed class ArchiWebHandler : IDisposable {
WebAPI.DefaultBaseAddress,
// ReSharper disable once AccessToDisposedClosure
async () => await service.CallAsync(HttpMethod.Get, "GetPlayerBans", args: arguments).ConfigureAwait(false)
async () => await service.CallAsync(HttpMethod.Get, "GetPlayerBans", args: arguments).ConfigureAwait(false), cancellationToken
).ConfigureAwait(false);
} catch (TaskCanceledException e) {
Bot.ArchiLogger.LogGenericDebuggingException(e);

View file

@ -375,7 +375,7 @@ public sealed class MobileAuthenticator : IDisposable {
);
}
private async Task<(bool Success, string? Result)> ResolveDeviceID() {
private async Task<(bool Success, string? Result)> ResolveDeviceID(CancellationToken cancellationToken = default) {
if (Bot == null) {
throw new InvalidOperationException(nameof(Bot));
}