From 0112ca749d88f9d02f2740495386aa609f6e2729 Mon Sep 17 00:00:00 2001 From: Yaakov Date: Thu, 23 Mar 2023 23:20:53 +1100 Subject: [PATCH 1/5] Rudimentary support for new access tokens --- DepotDownloader/AccountSettingsStore.cs | 8 ++- DepotDownloader/ContentDownloader.cs | 9 ++- DepotDownloader/DepotDownloader.csproj | 2 +- DepotDownloader/DownloadConfig.cs | 1 - DepotDownloader/Program.cs | 5 +- DepotDownloader/Steam3Session.cs | 94 +++++++++++-------------- 6 files changed, 53 insertions(+), 66 deletions(-) diff --git a/DepotDownloader/AccountSettingsStore.cs b/DepotDownloader/AccountSettingsStore.cs index c6c9a251..8bed9622 100644 --- a/DepotDownloader/AccountSettingsStore.cs +++ b/DepotDownloader/AccountSettingsStore.cs @@ -17,8 +17,10 @@ namespace DepotDownloader [ProtoMember(2, IsRequired = false)] public ConcurrentDictionary ContentServerPenalty { get; private set; } - [ProtoMember(3, IsRequired = false)] - public Dictionary LoginKeys { get; private set; } + // Member 3 was a Dictionary for LoginKeys. + + [ProtoMember(4, IsRequired = false)] + public Dictionary LoginTokens { get; private set; } string FileName; @@ -26,7 +28,7 @@ namespace DepotDownloader { SentryData = new Dictionary(); ContentServerPenalty = new ConcurrentDictionary(); - LoginKeys = new Dictionary(); + LoginTokens = new Dictionary(); } static bool Loaded diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index 7cee83f7..1a57dc6e 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -341,20 +341,20 @@ namespace DepotDownloader public static bool InitializeSteam3(string username, string password) { - string loginKey = null; + string loginToken = null; if (username != null && Config.RememberPassword) { - _ = AccountSettingsStore.Instance.LoginKeys.TryGetValue(username, out loginKey); + _ = AccountSettingsStore.Instance.LoginTokens.TryGetValue(username, out loginToken); } steam3 = new Steam3Session( new SteamUser.LogOnDetails { Username = username, - Password = loginKey == null ? password : null, + Password = loginToken == null ? password : null, ShouldRememberPassword = Config.RememberPassword, - LoginKey = loginKey, + AccessToken = loginToken, LoginID = Config.LoginID ?? 0x534B32, // "SK2" } ); @@ -381,7 +381,6 @@ namespace DepotDownloader if (steam3 == null) return; - steam3.TryWaitForLoginKey(); steam3.Disconnect(); } diff --git a/DepotDownloader/DepotDownloader.csproj b/DepotDownloader/DepotDownloader.csproj index 3fadc13d..c64d0054 100644 --- a/DepotDownloader/DepotDownloader.csproj +++ b/DepotDownloader/DepotDownloader.csproj @@ -12,6 +12,6 @@ - + diff --git a/DepotDownloader/DownloadConfig.cs b/DepotDownloader/DownloadConfig.cs index 448e589f..bcb46cb1 100644 --- a/DepotDownloader/DownloadConfig.cs +++ b/DepotDownloader/DownloadConfig.cs @@ -22,7 +22,6 @@ namespace DepotDownloader public int MaxServers { get; set; } public int MaxDownloads { get; set; } - public string SuppliedPassword { get; set; } public bool RememberPassword { get; set; } // A Steam LoginID to allow multiple concurrent connections diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs index e4ceb006..9c07fbbd 100644 --- a/DepotDownloader/Program.cs +++ b/DepotDownloader/Program.cs @@ -268,7 +268,7 @@ namespace DepotDownloader static bool InitializeSteam(string username, string password) { - if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginKeys.ContainsKey(username))) + if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginTokens.ContainsKey(username))) { do { @@ -291,9 +291,6 @@ namespace DepotDownloader Console.WriteLine("No username given. Using anonymous account with dedicated server subscription."); } - // capture the supplied password in case we need to re-use it after checking the login key - ContentDownloader.Config.SuppliedPassword = password; - return ContentDownloader.InitializeSteam3(username, password); } diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 071981fb..d88feccc 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using SteamKit2; +using SteamKit2.Authentication; using SteamKit2.Internal; namespace DepotDownloader @@ -53,7 +54,6 @@ namespace DepotDownloader bool bAborted; bool bExpectingDisconnectRemote; bool bDidDisconnect; - bool bDidReceiveLoginKey; bool bIsConnectionRecovery; int connectionBackoff; int seq; // more hack fixes @@ -79,7 +79,6 @@ namespace DepotDownloader this.bAborted = false; this.bExpectingDisconnectRemote = false; this.bDidDisconnect = false; - this.bDidReceiveLoginKey = false; this.seq = 0; this.AppTokens = new Dictionary(); @@ -112,7 +111,6 @@ namespace DepotDownloader this.callbacks.Subscribe(SessionTokenCallback); this.callbacks.Subscribe(LicenseListCallback); this.callbacks.Subscribe(UpdateMachineAuthCallback); - this.callbacks.Subscribe(LoginKeyCallback); Console.Write("Connecting to Steam3..."); @@ -419,7 +417,6 @@ namespace DepotDownloader bExpectingDisconnectRemote = false; bDidDisconnect = false; bIsConnectionRecovery = false; - bDidReceiveLoginKey = false; } void Connect() @@ -466,23 +463,6 @@ namespace DepotDownloader steamClient.Disconnect(); } - public void TryWaitForLoginKey() - { - if (logonDetails.Username == null || !credentials.LoggedOn || !ContentDownloader.Config.RememberPassword) return; - - var totalWaitPeriod = DateTime.Now.AddSeconds(3); - - while (true) - { - var now = DateTime.Now; - if (now >= totalWaitPeriod) break; - - if (bDidReceiveLoginKey) break; - - callbacks.RunWaitAllCallbacks(TimeSpan.FromMilliseconds(100)); - } - } - private void WaitForCallbacks() { callbacks.RunWaitCallbacks(TimeSpan.FromSeconds(1)); @@ -496,7 +476,7 @@ namespace DepotDownloader } } - private void ConnectedCallback(SteamClient.ConnectedCallback connected) + private async void ConnectedCallback(SteamClient.ConnectedCallback connected) { Console.WriteLine(" Done!"); bConnecting = false; @@ -508,7 +488,37 @@ namespace DepotDownloader } else { - Console.Write("Logging '{0}' into Steam3...", logonDetails.Username); + Console.WriteLine("Logging '{0}' into Steam3...", logonDetails.Username); + + if (logonDetails.Username != null && logonDetails.Password != null && logonDetails.AccessToken is null) + { + try + { + var session = await steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new SteamKit2.Authentication.AuthSessionDetails + { + Username = logonDetails.Username, + Password = logonDetails.Password, + IsPersistentSession = ContentDownloader.Config.RememberPassword, + Authenticator = new UserConsoleAuthenticator(), + }); + + var result = await session.PollingWaitForResultAsync(); + + DebugLog.WriteLine(nameof(Steam3Session), "Completed authentication initialization, got access token."); + + // Assume that we get back the same username, no need to reset it. + logonDetails.Password = null; + logonDetails.AccessToken = result.RefreshToken; + + AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; + AccountSettingsStore.Save(); + } + catch (Exception ex) + { + Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); + Abort(false); + } + } steamUser.LogOn(logonDetails); } } @@ -553,14 +563,14 @@ namespace DepotDownloader { var isSteamGuard = loggedOn.Result == EResult.AccountLogonDenied; var is2FA = loggedOn.Result == EResult.AccountLoginDeniedNeedTwoFactor; - var isLoginKey = ContentDownloader.Config.RememberPassword && logonDetails.LoginKey != null && loggedOn.Result == EResult.InvalidPassword; + var isAccessToken = ContentDownloader.Config.RememberPassword && logonDetails.AccessToken != null && loggedOn.Result == EResult.InvalidPassword; // TODO: Get EResult for bad access token - if (isSteamGuard || is2FA || isLoginKey) + if (isSteamGuard || is2FA || isAccessToken) { bExpectingDisconnectRemote = true; Abort(false); - if (!isLoginKey) + if (!isAccessToken) { Console.WriteLine("This account is protected by Steam Guard."); } @@ -573,23 +583,15 @@ namespace DepotDownloader logonDetails.TwoFactorCode = Console.ReadLine(); } while (String.Empty == logonDetails.TwoFactorCode); } - else if (isLoginKey) + else if (isAccessToken) { - AccountSettingsStore.Instance.LoginKeys.Remove(logonDetails.Username); + AccountSettingsStore.Instance.LoginTokens.Remove(logonDetails.Username); AccountSettingsStore.Save(); - logonDetails.LoginKey = null; - - if (ContentDownloader.Config.SuppliedPassword != null) - { - Console.WriteLine("Login key was expired. Connecting with supplied password."); - logonDetails.Password = ContentDownloader.Config.SuppliedPassword; - } - else - { - Console.Write("Login key was expired. Please enter your password: "); - logonDetails.Password = Util.ReadPassword(); - } + // TODO: Handle gracefully by falling back to password prompt? + Console.WriteLine("Access token was rejected."); + Abort(false); + return; } else { @@ -699,17 +701,5 @@ namespace DepotDownloader // send off our response steamUser.SendMachineAuthResponse(authResponse); } - - private void LoginKeyCallback(SteamUser.LoginKeyCallback loginKey) - { - Console.WriteLine("Accepted new login key for account {0}", logonDetails.Username); - - AccountSettingsStore.Instance.LoginKeys[logonDetails.Username] = loginKey.LoginKey; - AccountSettingsStore.Save(); - - steamUser.AcceptNewLoginKey(loginKey); - - bDidReceiveLoginKey = true; - } } } From 6ffa0948a494798a138d3689dff0e3e9500525c5 Mon Sep 17 00:00:00 2001 From: Yaakov Date: Fri, 24 Mar 2023 15:00:27 +1100 Subject: [PATCH 2/5] Implement -qr CLI arg to log in with a QR code --- DepotDownloader/DepotDownloader.csproj | 1 + DepotDownloader/DownloadConfig.cs | 2 + DepotDownloader/Program.cs | 38 ++++++++------- DepotDownloader/Steam3Session.cs | 64 ++++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/DepotDownloader/DepotDownloader.csproj b/DepotDownloader/DepotDownloader.csproj index c64d0054..a2e07dd3 100644 --- a/DepotDownloader/DepotDownloader.csproj +++ b/DepotDownloader/DepotDownloader.csproj @@ -12,6 +12,7 @@ + diff --git a/DepotDownloader/DownloadConfig.cs b/DepotDownloader/DownloadConfig.cs index bcb46cb1..1022aac4 100644 --- a/DepotDownloader/DownloadConfig.cs +++ b/DepotDownloader/DownloadConfig.cs @@ -26,5 +26,7 @@ namespace DepotDownloader // A Steam LoginID to allow multiple concurrent connections public uint? LoginID { get; set; } + + public bool UseQrCode { get; set; } } } diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs index 9c07fbbd..baae3e8e 100644 --- a/DepotDownloader/Program.cs +++ b/DepotDownloader/Program.cs @@ -47,6 +47,7 @@ namespace DepotDownloader var username = GetParameter(args, "-username") ?? GetParameter(args, "-user"); var password = GetParameter(args, "-password") ?? GetParameter(args, "-pass"); ContentDownloader.Config.RememberPassword = HasParameter(args, "-remember-password"); + ContentDownloader.Config.UseQrCode = HasParameter(args, "-qr"); ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); @@ -268,27 +269,30 @@ namespace DepotDownloader static bool InitializeSteam(string username, string password) { - if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginTokens.ContainsKey(username))) + if (!ContentDownloader.Config.UseQrCode) { - do + if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginTokens.ContainsKey(username))) { - Console.Write("Enter account password for \"{0}\": ", username); - if (Console.IsInputRedirected) + do { - password = Console.ReadLine(); - } - else - { - // Avoid console echoing of password - password = Util.ReadPassword(); - } + Console.Write("Enter account password for \"{0}\": ", username); + if (Console.IsInputRedirected) + { + password = Console.ReadLine(); + } + else + { + // Avoid console echoing of password + password = Util.ReadPassword(); + } - Console.WriteLine(); - } while (string.Empty == password); - } - else if (username == null) - { - Console.WriteLine("No username given. Using anonymous account with dedicated server subscription."); + Console.WriteLine(); + } while (string.Empty == password); + } + else if (username == null) + { + Console.WriteLine("No username given. Using anonymous account with dedicated server subscription."); + } } return ContentDownloader.InitializeSteam3(username, password); diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index d88feccc..e30ff64e 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using QRCoder; using SteamKit2; using SteamKit2.Authentication; using SteamKit2.Internal; @@ -72,7 +73,7 @@ namespace DepotDownloader { this.logonDetails = details; - this.authenticatedUser = details.Username != null; + this.authenticatedUser = details.Username != null || ContentDownloader.Config.UseQrCode; this.credentials = new Credentials(); this.bConnected = false; this.bConnecting = false; @@ -114,7 +115,7 @@ namespace DepotDownloader Console.Write("Connecting to Steam3..."); - if (authenticatedUser) + if (details.Username != null) { var fi = new FileInfo(String.Format("{0}.sentryFile", logonDetails.Username)); if (AccountSettingsStore.Instance.SentryData != null && AccountSettingsStore.Instance.SentryData.ContainsKey(logonDetails.Username)) @@ -488,7 +489,10 @@ namespace DepotDownloader } else { - Console.WriteLine("Logging '{0}' into Steam3...", logonDetails.Username); + if (logonDetails.Username != null) + { + Console.WriteLine("Logging '{0}' into Steam3...", logonDetails.Username); + } if (logonDetails.Username != null && logonDetails.Password != null && logonDetails.AccessToken is null) { @@ -504,8 +508,6 @@ namespace DepotDownloader var result = await session.PollingWaitForResultAsync(); - DebugLog.WriteLine(nameof(Steam3Session), "Completed authentication initialization, got access token."); - // Assume that we get back the same username, no need to reset it. logonDetails.Password = null; logonDetails.AccessToken = result.RefreshToken; @@ -519,6 +521,46 @@ namespace DepotDownloader Abort(false); } } + else if (ContentDownloader.Config.UseQrCode) + { + Console.WriteLine("Logging in with QR code..."); + + try + { + var session = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails + { + IsPersistentSession = ContentDownloader.Config.RememberPassword, + Authenticator = new UserConsoleAuthenticator(), + }); + + // Steam will periodically refresh the challenge url, so we need a new QR code. + session.ChallengeURLChanged = () => + { + Console.WriteLine(); + Console.WriteLine("The QR code has changed:"); + + DisplayQrCode(session.ChallengeURL); + }; + + // Draw initial QR code immediately + DisplayQrCode(session.ChallengeURL); + + var result = await session.PollingWaitForResultAsync(); + + logonDetails.Username = result.AccountName; + logonDetails.Password = null; + logonDetails.AccessToken = result.RefreshToken; + + AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; + AccountSettingsStore.Save(); + } + catch (Exception ex) + { + Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); + Abort(false); + } + } + steamUser.LogOn(logonDetails); } } @@ -701,5 +743,17 @@ namespace DepotDownloader // send off our response steamUser.SendMachineAuthResponse(authResponse); } + + private static void DisplayQrCode(string challengeUrl) + { + // Encode the link as a QR code + var qrGenerator = new QRCodeGenerator(); + var qrCodeData = qrGenerator.CreateQrCode(challengeUrl, QRCodeGenerator.ECCLevel.L); + var qrCode = new AsciiQRCode(qrCodeData); + var qrCodeAsAsciiArt = qrCode.GetGraphic(1, drawQuietZones: false); + + Console.WriteLine("Use the Steam Mobile App to sign in with this QR code:"); + Console.WriteLine(qrCodeAsAsciiArt); + } } } From 8d6c09e779d26bcbf5a218d977368b8073f43c8b Mon Sep 17 00:00:00 2001 From: Yaakov Date: Fri, 24 Mar 2023 15:00:36 +1100 Subject: [PATCH 3/5] dispose of disposables --- DepotDownloader/Steam3Session.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index e30ff64e..db42df8d 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -747,9 +747,9 @@ namespace DepotDownloader private static void DisplayQrCode(string challengeUrl) { // Encode the link as a QR code - var qrGenerator = new QRCodeGenerator(); + using var qrGenerator = new QRCodeGenerator(); var qrCodeData = qrGenerator.CreateQrCode(challengeUrl, QRCodeGenerator.ECCLevel.L); - var qrCode = new AsciiQRCode(qrCodeData); + using var qrCode = new AsciiQRCode(qrCodeData); var qrCodeAsAsciiArt = qrCode.GetGraphic(1, drawQuietZones: false); Console.WriteLine("Use the Steam Mobile App to sign in with this QR code:"); From c36ddcc065034ed52e308b3ae54373b928d1a120 Mon Sep 17 00:00:00 2001 From: Yaakov Date: Fri, 24 Mar 2023 15:57:46 +1100 Subject: [PATCH 4/5] handle reconnects more gracefully --- DepotDownloader/Steam3Session.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index db42df8d..976bd833 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -482,6 +482,12 @@ namespace DepotDownloader Console.WriteLine(" Done!"); bConnecting = false; bConnected = true; + + // Update our tracking so that we don't time out, even if we need to reconnect multiple times, + // e.g. if the authentication phase takes a while and therefore multiple connections. + connectTime = DateTime.Now; + connectionBackoff = 0; + if (!authenticatedUser) { Console.Write("Logging anonymously into Steam3..."); @@ -515,10 +521,15 @@ namespace DepotDownloader AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; AccountSettingsStore.Save(); } + catch (TaskCanceledException) + { + return; + } catch (Exception ex) { Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); Abort(false); + return; } } else if (ContentDownloader.Config.UseQrCode) @@ -554,10 +565,15 @@ namespace DepotDownloader AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; AccountSettingsStore.Save(); } + catch (TaskCanceledException) + { + return; + } catch (Exception ex) { Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); Abort(false); + return; } } @@ -569,6 +585,8 @@ namespace DepotDownloader { bDidDisconnect = true; + DebugLog.WriteLine(nameof(Steam3Session), $"Disconnected: bIsConnectionRecovery = {bIsConnectionRecovery}, UserInitiated = {disconnected.UserInitiated}, bExpectingDisconnectRemote = {bExpectingDisconnectRemote}"); + // When recovering the connection, we want to reconnect even if the remote disconnects us if (!bIsConnectionRecovery && (disconnected.UserInitiated || bExpectingDisconnectRemote)) { From d73462e077f6e7ba1251734577a3cb11d6581a0b Mon Sep 17 00:00:00 2001 From: Yaakov Date: Fri, 24 Mar 2023 16:12:14 +1100 Subject: [PATCH 5/5] improve pre-login auth handling (I think?) --- DepotDownloader/Steam3Session.cs | 108 ++++++++++++++++++------------- 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 976bd833..bc1aa0d7 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -59,6 +59,7 @@ namespace DepotDownloader int connectionBackoff; int seq; // more hack fixes DateTime connectTime; + AuthSession authSession; // input readonly SteamUser.LogOnDetails logonDetails; @@ -426,6 +427,7 @@ namespace DepotDownloader bConnected = false; bConnecting = true; connectionBackoff = 0; + authSession = null; ResetConnectionFlags(); @@ -500,63 +502,75 @@ namespace DepotDownloader Console.WriteLine("Logging '{0}' into Steam3...", logonDetails.Username); } - if (logonDetails.Username != null && logonDetails.Password != null && logonDetails.AccessToken is null) + if (authSession is null) { - try + if (logonDetails.Username != null && logonDetails.Password != null && logonDetails.AccessToken is null) { - var session = await steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new SteamKit2.Authentication.AuthSessionDetails + try { - Username = logonDetails.Username, - Password = logonDetails.Password, - IsPersistentSession = ContentDownloader.Config.RememberPassword, - Authenticator = new UserConsoleAuthenticator(), - }); - - var result = await session.PollingWaitForResultAsync(); - - // Assume that we get back the same username, no need to reset it. - logonDetails.Password = null; - logonDetails.AccessToken = result.RefreshToken; - - AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; - AccountSettingsStore.Save(); - } - catch (TaskCanceledException) - { - return; + authSession = await steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new SteamKit2.Authentication.AuthSessionDetails + { + Username = logonDetails.Username, + Password = logonDetails.Password, + IsPersistentSession = ContentDownloader.Config.RememberPassword, + Authenticator = new UserConsoleAuthenticator(), + }); + } + catch (TaskCanceledException) + { + return; + } + catch (Exception ex) + { + Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); + Abort(false); + return; + } } - catch (Exception ex) + else if (logonDetails.AccessToken is null && ContentDownloader.Config.UseQrCode) { - Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); - Abort(false); - return; - } - } - else if (ContentDownloader.Config.UseQrCode) - { - Console.WriteLine("Logging in with QR code..."); + Console.WriteLine("Logging in with QR code..."); - try - { - var session = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails + try { - IsPersistentSession = ContentDownloader.Config.RememberPassword, - Authenticator = new UserConsoleAuthenticator(), - }); + var session = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails + { + IsPersistentSession = ContentDownloader.Config.RememberPassword, + Authenticator = new UserConsoleAuthenticator(), + }); - // Steam will periodically refresh the challenge url, so we need a new QR code. - session.ChallengeURLChanged = () => - { - Console.WriteLine(); - Console.WriteLine("The QR code has changed:"); + authSession = session; - DisplayQrCode(session.ChallengeURL); - }; + // Steam will periodically refresh the challenge url, so we need a new QR code. + session.ChallengeURLChanged = () => + { + Console.WriteLine(); + Console.WriteLine("The QR code has changed:"); - // Draw initial QR code immediately - DisplayQrCode(session.ChallengeURL); + DisplayQrCode(session.ChallengeURL); + }; - var result = await session.PollingWaitForResultAsync(); + // Draw initial QR code immediately + DisplayQrCode(session.ChallengeURL); + } + catch (TaskCanceledException) + { + return; + } + catch (Exception ex) + { + Console.Error.WriteLine("Failed to authenticate with Steam: " + ex.Message); + Abort(false); + return; + } + } + } + + if (authSession != null) + { + try + { + var result = await authSession.PollingWaitForResultAsync(); logonDetails.Username = result.AccountName; logonDetails.Password = null; @@ -575,6 +589,8 @@ namespace DepotDownloader Abort(false); return; } + + authSession = null; } steamUser.LogOn(logonDetails);