diff --git a/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj b/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
index acb414a..a793b6b 100644
--- a/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
+++ b/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
@@ -9,7 +9,7 @@
Andrii Lavrenko
Utility for collecting Steam account information
Andrii Lavrenko
- 3.0.1
+ 3.0.2
diff --git a/SteamAccountDataFetcher/SteamDataClient/Client.cs b/SteamAccountDataFetcher/SteamDataClient/Client.cs
index b8becee..e39add5 100644
--- a/SteamAccountDataFetcher/SteamDataClient/Client.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/Client.cs
@@ -14,6 +14,7 @@ public class Client : IDisposable
private SteamApps _steamApps;
private bool _isRunning = false;
+ private bool _isAuthUnsuccess = false;
private bool _isLicensesProcessed = false;
private bool _isWebAPIProcessed = false;
@@ -31,6 +32,7 @@ internal SteamID? SteamID
internal string RefreshToken { get; private set; } = string.Empty;
private static uint _instance = 0;
+ private static bool _rateLimitReached = false;
private static DateTime _lastConnectionTime = DateTime.MinValue;
private static List? _packagesInfo = null;
@@ -94,13 +96,7 @@ internal async Task GetResponseDataAsync()
internal async Task RunAsync()
{
- var secondsBetweenLastConnect = DateTime.Now - _lastConnectionTime;
- if (secondsBetweenLastConnect < Configuration.DefaultLoginTimeout)
- {
- var timeToWait = Configuration.DefaultLoginTimeout - secondsBetweenLastConnect;
- Log($"Last connection was {secondsBetweenLastConnect.Seconds} seconds ago, wait {timeToWait.Seconds} seconds.");
- await Task.Delay(timeToWait);
- }
+ await WaitOrProceed();
_isRunning = true;
_steamClient.Connect();
@@ -117,33 +113,38 @@ internal async Task RunAsync()
private async Task LoginAsync()
{
- while (true)
+ try
{
- try
+ CredentialsAuthSession authSession = await _steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new()
{
- CredentialsAuthSession authSession = await _steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new()
- {
- Username = Username,
- Password = Password,
- Authenticator = _autoTwoFactorAuthenticator
- });
- AuthPollResult authPollResult = await authSession.PollingWaitForResultAsync();
- AccessToken = authPollResult.AccessToken;
- RefreshToken = authPollResult.RefreshToken;
- break;
- }
- catch (AuthenticationException e)
+ Username = Username,
+ Password = Password,
+ Authenticator = _autoTwoFactorAuthenticator
+ });
+ AuthPollResult authPollResult = await authSession.PollingWaitForResultAsync();
+ AccessToken = authPollResult.AccessToken;
+ RefreshToken = authPollResult.RefreshToken;
+ }
+ catch (AuthenticationException e)
+ {
+ if (e.Result == EResult.AccountLoginDeniedThrottle || e.Result == EResult.RateLimitExceeded)
{
- Log($"Unable to authenticate user to Steam Client with error {e.Message}.", Logger.Level.Error);
+ Log("RateLimit reached.", Logger.Level.Warning);
+ _rateLimitReached = true;
_steamClient.Disconnect();
return;
}
- catch (TaskCanceledException)
- {
- Log("Failure to authenticate user to Steam Client. Retrying...", Logger.Level.Warning);
- await Task.Delay(1000);
- continue;
- }
+
+ Log($"Unable to authenticate user to Steam Client with error {e.Message}.", Logger.Level.Error);
+ _steamClient.Disconnect();
+ return;
+ }
+ catch (TaskCanceledException)
+ {
+ Log("Failure to authenticate user to Steam Client. Retrying...", Logger.Level.Warning);
+ _isAuthUnsuccess = true;
+ _steamClient.Disconnect();
+ return;
}
_steamUser.LogOn(new()
@@ -178,7 +179,7 @@ private async void OnConnectedAsync(SteamClient.ConnectedCallback callback)
private async void OnDisconnectedAsync(SteamClient.DisconnectedCallback callback)
{
- if (callback.UserInitiated)
+ if (callback.UserInitiated && !_rateLimitReached && !_isAuthUnsuccess)
{
Log("Disconnected from Steam Network by user.");
@@ -186,14 +187,10 @@ private async void OnDisconnectedAsync(SteamClient.DisconnectedCallback callback
return;
}
+ _isAuthUnsuccess = false;
Log("Disconnected from Steam Network.", Logger.Level.Error);
- var secondsBetweenLastConnect = DateTime.Now - _lastConnectionTime;
- if (secondsBetweenLastConnect < Configuration.DefaultLoginTimeout)
- {
- var timeToWait = Configuration.DefaultLoginTimeout - secondsBetweenLastConnect;
- Log($"Last connection was {secondsBetweenLastConnect.Seconds} seconds ago, wait {timeToWait.Seconds} seconds.");
- await Task.Delay(timeToWait);
- }
+ await WaitOrProceed();
+
_steamClient.Connect();
}
@@ -349,6 +346,27 @@ private async void OnLicenseListAsync(SteamApps.LicenseListCallback callback)
_isLicensesProcessed = true;
}
+ private async Task WaitOrProceed()
+ {
+ if (_lastConnectionTime == DateTime.MinValue)
+ return;
+
+ TimeSpan deltaBetweenLastConnect = DateTime.Now - _lastConnectionTime;
+ TimeSpan timeToWait = Configuration.DefaultLoginTimeout - deltaBetweenLastConnect;
+
+ if (_rateLimitReached)
+ {
+ _rateLimitReached = false;
+ timeToWait += Configuration.DefaultRateLimitTimeout;
+ }
+
+ if (timeToWait.TotalSeconds > 1)
+ {
+ Log($"Waiting {timeToWait.TotalSeconds:N2} seconds.");
+ await Task.Delay(timeToWait);
+ }
+ }
+
public void Dispose() => _steamWebClient?.Dispose();
internal void Log(string message, Logger.Level level = Logger.Level.Info, [CallerMemberName] string callerName = "") =>
diff --git a/SteamAccountDataFetcher/SteamDataClient/Configuration.cs b/SteamAccountDataFetcher/SteamDataClient/Configuration.cs
index 75b6e00..db43dc0 100644
--- a/SteamAccountDataFetcher/SteamDataClient/Configuration.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/Configuration.cs
@@ -11,6 +11,7 @@ internal static class Configuration
internal static string ReadCSVFilePath { get; } = "SteamAccountsLogin.txt";
internal static string WriteJSONFilePath { get; } = "SteamAccounts.json";
internal static string ApiDomain { get; } = "serious-re.com"; //"sadf.localhost";
- internal static TimeSpan DefaultLoginTimeout { get; } = TimeSpan.FromSeconds(20);
- internal static TimeSpan DefaultWebRequestTimeout { get; } = TimeSpan.FromSeconds(1);
+ internal static TimeSpan DefaultLoginTimeout { get; } = TimeSpan.FromSeconds(30);
+ internal static TimeSpan DefaultRateLimitTimeout { get; } = TimeSpan.FromMinutes(30);
+ internal static TimeSpan DefaultWebRequestTimeout { get; } = TimeSpan.FromSeconds(3);
}
diff --git a/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs b/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
index d82fec4..e1f6a6b 100644
--- a/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
@@ -18,7 +18,7 @@ internal class SteamWebClient: IDisposable
private SemaphoreSlim _webAPISemaphore = new(1);
internal string SessionID { get; private set; } = string.Empty;
- private static DateTime _lastRequestTime = DateTime.MinValue;
+ private static bool _isFirstRequestBefore = false;
internal SteamWebClient(Client steamClient)
{
@@ -223,10 +223,12 @@ internal void InitAsync()
private async Task RunOrSleep()
{
- while (DateTime.Now - _lastRequestTime < Configuration.DefaultWebRequestTimeout)
+ if (_isFirstRequestBefore)
+ {
await Task.Delay(Configuration.DefaultWebRequestTimeout);
-
- _lastRequestTime = DateTime.Now;
+ return;
+ }
+ _isFirstRequestBefore = true;
}
public void Dispose()