Skip to content

Commit

Permalink
Fix RateLimits errors; Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
SeRi0uS007 committed Nov 4, 2023
1 parent b069247 commit 1d5b62a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 43 deletions.
2 changes: 1 addition & 1 deletion SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<Authors>Andrii Lavrenko</Authors>
<Description>Utility for collecting Steam account information</Description>
<Copyright>Andrii Lavrenko</Copyright>
<Version>3.0.1</Version>
<Version>3.0.2</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
90 changes: 54 additions & 36 deletions SteamAccountDataFetcher/SteamDataClient/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<PackageInfo>? _packagesInfo = null;

Expand Down Expand Up @@ -94,13 +96,7 @@ internal async Task<AccountInfo> 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();
Expand All @@ -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()
Expand Down Expand Up @@ -178,22 +179,18 @@ 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.");

_isRunning = false;
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();
}

Expand Down Expand Up @@ -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 = "") =>
Expand Down
5 changes: 3 additions & 2 deletions SteamAccountDataFetcher/SteamDataClient/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
10 changes: 6 additions & 4 deletions SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 1d5b62a

Please sign in to comment.