Skip to content

Commit

Permalink
Implement support for access tokens
Browse files Browse the repository at this point in the history
A bit more work and testing is needed
  • Loading branch information
JustArchi committed Oct 19, 2023
1 parent 4106c5f commit 40dc232
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 118 deletions.
1 change: 1 addition & 0 deletions ArchiSteamFarm/ArchiSteamFarm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" />
<PackageReference Include="System.Composition" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" />
<PackageReference Include="System.Linq.Async" />
<PackageReference Include="zxcvbn-core" />
</ItemGroup>
Expand Down
185 changes: 151 additions & 34 deletions ArchiSteamFarm/Steam/Bot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Net.Http;
Expand Down Expand Up @@ -229,6 +230,8 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
internal bool PlayingBlocked { get; private set; }
internal bool PlayingWasBlocked { get; private set; }

private string? AccessToken;
private DateTime? AccessTokenValidUntil;
private string? AuthCode;

[JsonProperty]
Expand All @@ -244,6 +247,8 @@ public sealed class Bot : IAsyncDisposable, IDisposable {
private ulong MasterChatGroupID;
private Timer? PlayingWasBlockedTimer;
private bool ReconnectOnUserInitiated;
private string? RefreshToken;
private Timer? RefreshTokensTimer;
private bool SendCompleteTypesScheduled;
private Timer? SendItemsTimer;
private bool SteamParentalActive;
Expand Down Expand Up @@ -357,6 +362,7 @@ public void Dispose() {
ConnectionFailureTimer?.Dispose();
GamesRedeemerInBackgroundTimer?.Dispose();
PlayingWasBlockedTimer?.Dispose();
RefreshTokensTimer?.Dispose();
SendItemsTimer?.Dispose();
SteamSaleEvent?.Dispose();
TradeCheckTimer?.Dispose();
Expand Down Expand Up @@ -390,6 +396,10 @@ public async ValueTask DisposeAsync() {
await PlayingWasBlockedTimer.DisposeAsync().ConfigureAwait(false);
}

if (RefreshTokensTimer != null) {
await RefreshTokensTimer.DisposeAsync().ConfigureAwait(false);
}

if (SendItemsTimer != null) {
await SendItemsTimer.DisposeAsync().ConfigureAwait(false);
}
Expand Down Expand Up @@ -1492,32 +1502,57 @@ internal async Task OnFarmingStopped() {
await PluginsCore.OnBotFarmingStopped(this).ConfigureAwait(false);
}

internal async Task<bool> RefreshSession() {
internal async Task<bool> RefreshWebSession() {
if (!IsConnectedAndLoggedOn) {
return false;
}

SteamUser.WebAPIUserNonceCallback callback;
DateTime now = DateTime.UtcNow;

try {
callback = await SteamUser.RequestWebAPIUserNonce().ToLongRunningTask().ConfigureAwait(false);
} catch (Exception e) {
ArchiLogger.LogGenericWarningException(e);
if (!string.IsNullOrEmpty(AccessToken) && AccessTokenValidUntil.HasValue && (AccessTokenValidUntil.Value > now.AddMinutes(5))) {
// We can use the tokens we already have
if (await ArchiWebHandler.Init(SteamID, SteamClient.Universe, AccessToken, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) {

Check warning on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.

Check warning on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.

Check failure on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.

Check failure on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.

Check failure on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.

Check failure on line 1514 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

Possible null reference argument for parameter 'accessToken' in 'Task<bool> ArchiWebHandler.Init(ulong steamID, EUniverse universe, string accessToken, string? parentalCode = null)'.
InitRefreshTokensTimer(AccessTokenValidUntil.Value);

return true;
}
}

// We need to refresh our session, access token is no longer valid
BotDatabase.AccessToken = AccessToken = null;
BotDatabase.AccessTokenValidUntil = AccessTokenValidUntil = null;

if (string.IsNullOrEmpty(RefreshToken)) {
// Without refresh token we can't get fresh access tokens, relog needed
await Connect(true).ConfigureAwait(false);

return false;
}

if (string.IsNullOrEmpty(callback.Nonce)) {
CAuthentication_AccessToken_GenerateForApp_Response? response = await ArchiHandler.GenerateAccessTokens(RefreshToken).ConfigureAwait(false);

Check warning on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

Check warning on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

Check failure on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

Check failure on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

Check failure on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

Check failure on line 1532 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

Possible null reference argument for parameter 'refreshToken' in 'Task<CAuthentication_AccessToken_GenerateForApp_Response?> ArchiHandler.GenerateAccessTokens(string refreshToken)'.

if (response == null) {
// The request has failed, in almost all cases this means our refresh token is no longer valid, relog needed
BotDatabase.RefreshToken = RefreshToken = null;

await Connect(true).ConfigureAwait(false);

return false;
}

if (await ArchiWebHandler.Init(SteamID, SteamClient.Universe, callback.Nonce, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) {
// TODO: Handle update of refresh token with next SK2 release
UpdateTokens(response.access_token, RefreshToken);

if (await ArchiWebHandler.Init(SteamID, SteamClient.Universe, response.access_token, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) {
InitRefreshTokensTimer(AccessTokenValidUntil ?? now.AddDays(1));

return true;
}

// We got the tokens, but failed to authorize? Purge them just to be sure and reconnect
BotDatabase.AccessToken = AccessToken = null;
BotDatabase.AccessTokenValidUntil = AccessTokenValidUntil = null;

await Connect(true).ConfigureAwait(false);

return false;
Expand Down Expand Up @@ -2274,6 +2309,20 @@ private async Task InitModules() {
WalletBalance = 0;
WalletCurrency = ECurrencyCode.Invalid;

AccessToken = BotDatabase.AccessToken;
AccessTokenValidUntil = BotDatabase.AccessTokenValidUntil;
RefreshToken = BotDatabase.RefreshToken;

if (BotConfig.PasswordFormat.HasTransformation()) {
if (!string.IsNullOrEmpty(AccessToken)) {
AccessToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, AccessToken!).ConfigureAwait(false);
}

if (!string.IsNullOrEmpty(RefreshToken)) {
AccessToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, RefreshToken!).ConfigureAwait(false);
}
}

CardsFarmer.SetInitialState(BotConfig.Paused);

if (SendItemsTimer != null) {
Expand Down Expand Up @@ -2344,6 +2393,40 @@ private void InitPlayingWasBlockedTimer() {
);
}

private void InitRefreshTokensTimer(DateTime validUntil) {
if (validUntil <= DateTime.UnixEpoch) {

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 2397 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'
throw new ArgumentOutOfRangeException(nameof(validUntil));
}

if (validUntil == DateTime.MaxValue) {
// OK, tokens do not require refreshing
StopRefreshTokensTimer();

return;
}

TimeSpan delay = validUntil - DateTime.UtcNow;

// Start refreshing token 10 minutes before it's invalid
if (delay.TotalMinutes > 10) {
delay -= TimeSpan.FromMinutes(10);
}

// Timer can accept only dueTimes up to 2^32 - 2
uint dueTime = (uint) Math.Min(uint.MaxValue - 1, (ulong) delay.TotalMilliseconds);

if (RefreshTokensTimer == null) {
RefreshTokensTimer = new Timer(
OnRefreshTokensTimer,
null,
TimeSpan.FromMilliseconds(dueTime), // Delay
TimeSpan.FromMinutes(1) // Period
);
} else {
RefreshTokensTimer.Change(TimeSpan.FromMilliseconds(dueTime), TimeSpan.FromMinutes(1));
}
}

private void InitStart() {
if (!BotConfig.Enabled) {
ArchiLogger.LogGenericWarning(Strings.BotInstanceNotStartingBecauseDisabled);
Expand Down Expand Up @@ -2482,17 +2565,7 @@ private async void OnConnected(SteamClient.ConnectedCallback callback) {
}
}

string? refreshToken = BotDatabase.RefreshToken;

if (!string.IsNullOrEmpty(refreshToken)) {
// Decrypt refreshToken if needed
if (BotConfig.PasswordFormat.HasTransformation()) {
// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
refreshToken = await ArchiCryptoHelper.Decrypt(BotConfig.PasswordFormat, refreshToken!).ConfigureAwait(false);
}
}

if (!await InitLoginAndPassword(string.IsNullOrEmpty(refreshToken)).ConfigureAwait(false)) {
if (!await InitLoginAndPassword(string.IsNullOrEmpty(RefreshToken)).ConfigureAwait(false)) {
Stop();

return;
Expand Down Expand Up @@ -2537,7 +2610,7 @@ private async void OnConnected(SteamClient.ConnectedCallback callback) {

InitConnectionFailureTimer();

if (string.IsNullOrEmpty(refreshToken)) {
if (string.IsNullOrEmpty(RefreshToken)) {
AuthPollResult pollResult;

try {
Expand Down Expand Up @@ -2569,19 +2642,15 @@ private async void OnConnected(SteamClient.ConnectedCallback callback) {
return;
}

refreshToken = pollResult.RefreshToken;

if (BotConfig.UseLoginKeys) {
BotDatabase.RefreshToken = BotConfig.PasswordFormat.HasTransformation() ? ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, refreshToken) : refreshToken;

if (!string.IsNullOrEmpty(pollResult.NewGuardData)) {
BotDatabase.SteamGuardData = pollResult.NewGuardData;
}
if (!string.IsNullOrEmpty(pollResult.NewGuardData) && BotConfig.UseLoginKeys) {
BotDatabase.SteamGuardData = pollResult.NewGuardData;
}

UpdateTokens(pollResult.AccessToken, pollResult.RefreshToken);
}

SteamUser.LogOnDetails logOnDetails = new() {
AccessToken = refreshToken,
AccessToken = RefreshToken,
CellID = ASF.GlobalDatabase?.CellID,
LoginID = LoginID,
SentryFileHash = sentryFileHash,
Expand All @@ -2606,6 +2675,7 @@ private async void OnDisconnected(SteamClient.DisconnectedCallback callback) {
HeartBeatFailures = 0;
StopConnectionFailureTimer();
StopPlayingWasBlockedTimer();
StopRefreshTokensTimer();

ArchiLogger.LogGenericInfo(Strings.BotDisconnected);

Expand Down Expand Up @@ -3087,11 +3157,9 @@ private async void OnLoggedOn(SteamUser.LoggedOnCallback callback) {

ArchiWebHandler.OnVanityURLChanged(callback.VanityURL);

// ReSharper disable once RedundantSuppressNullableWarningExpression - required for .NET Framework
if (string.IsNullOrEmpty(callback.WebAPIUserNonce) || !await ArchiWebHandler.Init(SteamID, SteamClient.Universe, callback.WebAPIUserNonce!, SteamParentalActive ? BotConfig.SteamParentalCode : null).ConfigureAwait(false)) {
if (!await RefreshSession().ConfigureAwait(false)) {
return;
}
// Establish web session
if (!await RefreshWebSession().ConfigureAwait(false)) {
return;
}

// Pre-fetch API key for future usage if possible
Expand Down Expand Up @@ -3236,6 +3304,15 @@ private async void OnPlayingSessionState(SteamUser.PlayingSessionStateCallback c
await CheckOccupationStatus().ConfigureAwait(false);
}

private async void OnRefreshTokensTimer(object? state = null) {
if (AccessTokenValidUntil.HasValue && (AccessTokenValidUntil.Value > DateTime.UtcNow.AddMinutes(15))) {
// We don't need to refresh just yet
InitRefreshTokensTimer(AccessTokenValidUntil.Value);
}

await RefreshWebSession().ConfigureAwait(false);
}

private async void OnSendItemsTimer(object? state = null) => await Actions.SendInventory(filterFunction: item => BotConfig.LootableTypes.Contains(item.Type)).ConfigureAwait(false);

private async void OnServiceMethod(SteamUnifiedMessages.ServiceMethodNotification notification) {
Expand Down Expand Up @@ -3708,6 +3785,46 @@ private void StopPlayingWasBlockedTimer() {
PlayingWasBlockedTimer = null;
}

private void StopRefreshTokensTimer() {
if (RefreshTokensTimer == null) {
return;
}

RefreshTokensTimer.Dispose();
RefreshTokensTimer = null;
}

private void UpdateTokens(string accessToken, string refreshToken) {
ArgumentException.ThrowIfNullOrEmpty(accessToken);

Check failure on line 3798 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3798 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3798 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3798 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'
ArgumentException.ThrowIfNullOrEmpty(refreshToken);

Check failure on line 3799 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3799 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3799 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 3799 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

AccessToken = accessToken;
AccessTokenValidUntil = null;
RefreshToken = refreshToken;

JwtSecurityTokenHandler jwtSecurityTokenHandler = new();

try {
JwtSecurityToken? accessTokenJwt = jwtSecurityTokenHandler.ReadJwtToken(accessToken);

AccessTokenValidUntil = accessTokenJwt.ValidTo > DateTime.UnixEpoch ? accessTokenJwt.ValidTo : DateTime.MaxValue;

Check failure on line 3810 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 3810 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 3810 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'DateTime' does not contain a definition for 'UnixEpoch'

Check failure on line 3810 in ArchiSteamFarm/Steam/Bot.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'DateTime' does not contain a definition for 'UnixEpoch'
} catch (Exception e) {
ArchiLogger.LogGenericException(e);
}

if (BotConfig.UseLoginKeys) {
if (BotConfig.PasswordFormat.HasTransformation()) {
BotDatabase.AccessToken = ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, accessToken);
BotDatabase.RefreshToken = ArchiCryptoHelper.Encrypt(BotConfig.PasswordFormat, refreshToken);
} else {
BotDatabase.AccessToken = accessToken;
BotDatabase.RefreshToken = refreshToken;
}

BotDatabase.AccessTokenValidUntil = AccessTokenValidUntil;
}
}

private (bool IsSteamParentalEnabled, string? SteamParentalCode) ValidateSteamParental(ParentalSettings settings, string? steamParentalCode = null, bool allowGeneration = true) {
ArgumentNullException.ThrowIfNull(settings);

Expand Down
31 changes: 31 additions & 0 deletions ArchiSteamFarm/Steam/Integration/ArchiHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public sealed class ArchiHandler : ClientMsgHandler {
internal const byte MaxGamesPlayedConcurrently = 32; // This is limit introduced by Steam Network

private readonly ArchiLogger ArchiLogger;
private readonly SteamUnifiedMessages.UnifiedService<IAuthentication> UnifiedAuthenticationService;
private readonly SteamUnifiedMessages.UnifiedService<IChatRoom> UnifiedChatRoomService;
private readonly SteamUnifiedMessages.UnifiedService<IClanChatRooms> UnifiedClanChatRoomsService;
private readonly SteamUnifiedMessages.UnifiedService<ICredentials> UnifiedCredentialsService;
Expand All @@ -53,6 +54,7 @@ internal ArchiHandler(ArchiLogger archiLogger, SteamUnifiedMessages steamUnified
ArgumentNullException.ThrowIfNull(steamUnifiedMessages);

ArchiLogger = archiLogger ?? throw new ArgumentNullException(nameof(archiLogger));
UnifiedAuthenticationService = steamUnifiedMessages.CreateService<IAuthentication>();
UnifiedChatRoomService = steamUnifiedMessages.CreateService<IChatRoom>();
UnifiedClanChatRoomsService = steamUnifiedMessages.CreateService<IClanChatRooms>();
UnifiedCredentialsService = steamUnifiedMessages.CreateService<ICredentials>();
Expand Down Expand Up @@ -358,6 +360,35 @@ internal void AcknowledgeClanInvite(ulong steamID, bool acceptInvite) {
Client.Send(request);
}

internal async Task<CAuthentication_AccessToken_GenerateForApp_Response?> GenerateAccessTokens(string refreshToken) {
ArgumentException.ThrowIfNullOrEmpty(refreshToken);

Check failure on line 364 in ArchiSteamFarm/Steam/Integration/ArchiHandler.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 364 in ArchiSteamFarm/Steam/Integration/ArchiHandler.cs

View workflow job for this annotation

GitHub Actions / main (Debug, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 364 in ArchiSteamFarm/Steam/Integration/ArchiHandler.cs

View workflow job for this annotation

GitHub Actions / publish-asf (windows-latest, generic-netf)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

Check failure on line 364 in ArchiSteamFarm/Steam/Integration/ArchiHandler.cs

View workflow job for this annotation

GitHub Actions / main (Release, windows-latest)

'ArgumentException' does not contain a definition for 'ThrowIfNullOrEmpty'

if (Client == null) {
throw new InvalidOperationException(nameof(Client));
}

if (!Client.IsConnected || (Client.SteamID == null)) {
return null;
}

CAuthentication_AccessToken_GenerateForApp_Request request = new() {
refresh_token = refreshToken,
steamid = Client.SteamID
};

SteamUnifiedMessages.ServiceMethodResponse response;

try {
response = await UnifiedAuthenticationService.SendMessage(x => x.GenerateAccessTokenForApp(request)).ToLongRunningTask().ConfigureAwait(false);
} catch (Exception e) {
ArchiLogger.LogGenericWarningException(e);

return null;
}

return response.Result == EResult.OK ? response.GetDeserializedResponse<CAuthentication_AccessToken_GenerateForApp_Response>() : null;
}

internal async Task<ulong> GetClanChatGroupID(ulong steamID) {
if ((steamID == 0) || !new SteamID(steamID).IsClanAccount) {
throw new ArgumentOutOfRangeException(nameof(steamID));
Expand Down
Loading

0 comments on commit 40dc232

Please sign in to comment.