static async Task<int> MainAsync( string[] args ) { if ( args.Length == 0 ) { PrintUsage(); return 1; } DebugLog.Enabled = false; AccountSettingsStore.LoadFromFile( "account.config" ); #region Common Options if ( HasParameter( args, "-debug" ) ) { DebugLog.Enabled = true; DebugLog.AddListener( ( category, message ) => { Console.WriteLine( "[{0}] {1}", category, message ); }); } try { string regex = GetParameter<string>( args, "-blacklist-cdn", "$^" ); CDNClientPool.blacklistCDN = new Regex(regex, RegexOptions.Compiled | RegexOptions.IgnoreCase); } catch { Console.WriteLine( "Error: Invalid regex supplied for -blacklist-cdn" ); return 1; } string username = GetParameter<string>( args, "-username" ) ?? GetParameter<string>( args, "-user" ); string password = GetParameter<string>( args, "-password" ) ?? GetParameter<string>( args, "-pass" ); ContentDownloader.Config.RememberPassword = HasParameter( args, "-remember-password" ); ContentDownloader.Config.DownloadManifestOnly = HasParameter( args, "-manifest-only" ); int cellId = GetParameter<int>( args, "-cellid", -1 ); if ( cellId == -1 ) { cellId = 0; } ContentDownloader.Config.CellID = cellId; string fileList = GetParameter<string>( args, "-filelist" ); string[] files = null; if ( fileList != null ) { try { string fileListData = File.ReadAllText(fileList); files = fileListData.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries ); ContentDownloader.Config.UsingFileList = true; ContentDownloader.Config.FilesToDownload = new List<string>(); ContentDownloader.Config.FilesToDownloadRegex = new List<Regex>(); var isWindows = RuntimeInformation.IsOSPlatform( OSPlatform.Windows ); foreach ( var fileEntry in files ) { try { string fileEntryProcessed; if ( isWindows ) { // On Windows, ensure that forward slashes can match either forward or backslashes in depot paths fileEntryProcessed = fileEntry.Replace( "/", "[\\\\|/]" ); } else { // On other systems, treat / normally fileEntryProcessed = fileEntry; } Regex rgx = new Regex( fileEntryProcessed, RegexOptions.Compiled | RegexOptions.IgnoreCase ); ContentDownloader.Config.FilesToDownloadRegex.Add( rgx ); } catch { // For anything that can't be processed as a Regex, allow both forward and backward slashes to match // on Windows if( isWindows ) { ContentDownloader.Config.FilesToDownload.Add( fileEntry.Replace( "/", "\\" ) ); } ContentDownloader.Config.FilesToDownload.Add( fileEntry ); continue; } } Console.WriteLine( "Using filelist: '{0}'.", fileList ); } catch (Exception ex) { Console.WriteLine( "Warning: Unable to load filelist: {0}", ex.ToString() ); } } ContentDownloader.Config.InstallDirectory = GetParameter<string>( args, "-dir" ); ContentDownloader.Config.VerifyAll = HasParameter( args, "-verify-all" ) || HasParameter( args, "-verify_all" ) || HasParameter( args, "-validate" ); ContentDownloader.Config.MaxServers = GetParameter<int>( args, "-max-servers", 20 ); ContentDownloader.Config.MaxDownloads = GetParameter<int>( args, "-max-downloads", 4 ); ContentDownloader.Config.MaxServers = Math.Max( ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads ); ContentDownloader.Config.LoginID = HasParameter( args, "-loginid" ) ? (uint?)GetParameter<uint>( args, "-loginid" ) : null; #endregion uint appId = GetParameter<uint>( args, "-app", ContentDownloader.INVALID_APP_ID ); if ( appId == ContentDownloader.INVALID_APP_ID ) { Console.WriteLine( "Error: -app not specified!" ); return 1; } ulong pubFile = GetParameter<ulong>( args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID ); if ( pubFile != ContentDownloader.INVALID_MANIFEST_ID ) { #region Pubfile Downloading if ( InitializeSteam( username, password ) ) { try { await ContentDownloader.DownloadPubfileAsync( appId, pubFile ).ConfigureAwait( false ); } catch ( Exception ex ) when ( ex is ContentDownloaderException || ex is OperationCanceledException ) { Console.WriteLine( ex.Message ); return 1; } catch ( Exception e ) { Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message ); throw; } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine( "Error: InitializeSteam failed" ); return 1; } #endregion } else { #region App downloading string branch = GetParameter<string>( args, "-branch" ) ?? GetParameter<string>( args, "-beta" ) ?? ContentDownloader.DEFAULT_BRANCH; ContentDownloader.Config.BetaPassword = GetParameter<string>( args, "-betapassword" ); ContentDownloader.Config.DownloadAllPlatforms = HasParameter( args, "-all-platforms" ); string os = GetParameter<string>( args, "-os", null ); if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) ) { Console.WriteLine("Error: Cannot specify -os when -all-platforms is specified."); return 1; } string arch = GetParameter<string>( args, "-osarch", null ); ContentDownloader.Config.DownloadAllLanguages = HasParameter( args, "-all-languages" ); string language = GetParameter<string>( args, "-language", null ); if ( ContentDownloader.Config.DownloadAllLanguages && !String.IsNullOrEmpty( language ) ) { Console.WriteLine( "Error: Cannot specify -language when -all-languages is specified." ); return 1; } bool lv = HasParameter( args, "-lowviolence" ); uint depotId; bool isUGC = false; ulong manifestId = GetParameter<ulong>( args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID ); if ( manifestId != ContentDownloader.INVALID_MANIFEST_ID ) { depotId = appId; isUGC = true; } else { depotId = GetParameter<uint>( args, "-depot", ContentDownloader.INVALID_DEPOT_ID ); manifestId = GetParameter<ulong>( args, "-manifest", ContentDownloader.INVALID_MANIFEST_ID ); if ( depotId == ContentDownloader.INVALID_DEPOT_ID && manifestId != ContentDownloader.INVALID_MANIFEST_ID ) { Console.WriteLine( "Error: -manifest requires -depot to be specified" ); return 1; } } if ( InitializeSteam( username, password ) ) { try { await ContentDownloader.DownloadAppAsync( appId, depotId, manifestId, branch, os, arch, language, lv, isUGC ).ConfigureAwait( false ); } catch ( Exception ex ) when ( ex is ContentDownloaderException || ex is OperationCanceledException ) { Console.WriteLine( ex.Message ); return 1; } catch ( Exception e ) { Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message ); throw; } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine( "Error: InitializeSteam failed" ); return 1; } #endregion } return 0; }
static async Task <int> MainAsync(string[] args) { if (args.Length == 0) { PrintUsage(); return(1); } DebugLog.Enabled = false; AccountSettingsStore.LoadFromFile("account.config"); #region Common Options string username = GetParameter <string>(args, "-username") ?? GetParameter <string>(args, "-user"); string password = GetParameter <string>(args, "-password") ?? GetParameter <string>(args, "-pass"); ContentDownloader.Config.RememberPassword = HasParameter(args, "-remember-password"); ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); int cellId = GetParameter <int>(args, "-cellid", -1); if (cellId == -1) { cellId = 0; } ContentDownloader.Config.CellID = cellId; string fileList = GetParameter <string>(args, "-filelist"); string[] files = null; if (fileList != null) { try { string fileListData = File.ReadAllText(fileList); files = fileListData.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); ContentDownloader.Config.UsingFileList = true; ContentDownloader.Config.FilesToDownload = new List <string>(); ContentDownloader.Config.FilesToDownloadRegex = new List <Regex>(); foreach (var fileEntry in files) { try { Regex rgx = new Regex(fileEntry, RegexOptions.Compiled | RegexOptions.IgnoreCase); ContentDownloader.Config.FilesToDownloadRegex.Add(rgx); } catch { ContentDownloader.Config.FilesToDownload.Add(fileEntry); continue; } } Console.WriteLine("Using filelist: '{0}'.", fileList); } catch (Exception ex) { Console.WriteLine("Warning: Unable to load filelist: {0}", ex.ToString()); } } ContentDownloader.Config.InstallDirectory = GetParameter <string>(args, "-dir"); ContentDownloader.Config.VerifyAll = HasParameter(args, "-verify-all") || HasParameter(args, "-verify_all") || HasParameter(args, "-validate"); ContentDownloader.Config.MaxServers = GetParameter <int>(args, "-max-servers", 20); ContentDownloader.Config.MaxDownloads = GetParameter <int>(args, "-max-downloads", 4); ContentDownloader.Config.MaxServers = Math.Max(ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads); #endregion ulong pubFile = GetParameter <ulong>(args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID); if (pubFile != ContentDownloader.INVALID_MANIFEST_ID) { #region Pubfile Downloading if (InitializeSteam(username, password)) { try { await ContentDownloader.DownloadPubfileAsync(pubFile).ConfigureAwait(false); } catch (Exception ex) when( ex is ContentDownloaderException || ex is OperationCanceledException) { Console.WriteLine(ex.Message); return(1); } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine("Error: InitializeSteam failed"); return(1); } #endregion } else { #region App downloading string branch = GetParameter <string>(args, "-branch") ?? GetParameter <string>(args, "-beta") ?? ContentDownloader.DEFAULT_BRANCH; ContentDownloader.Config.BetaPassword = GetParameter <string>(args, "-betapassword"); ContentDownloader.Config.DownloadAllPlatforms = HasParameter(args, "-all-platforms"); string os = GetParameter <string>(args, "-os", null); if (ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty(os)) { Console.WriteLine("Error: Cannot specify -os when -all-platforms is specified."); return(1); } uint appId = GetParameter <uint>(args, "-app", ContentDownloader.INVALID_APP_ID); if (appId == ContentDownloader.INVALID_APP_ID) { Console.WriteLine("Error: -app not specified!"); return(1); } uint depotId; bool isUGC = false; ulong manifestId = GetParameter <ulong>(args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID); if (manifestId != ContentDownloader.INVALID_MANIFEST_ID) { depotId = appId; isUGC = true; } else { depotId = GetParameter <uint>(args, "-depot", ContentDownloader.INVALID_DEPOT_ID); manifestId = GetParameter <ulong>(args, "-manifest", ContentDownloader.INVALID_MANIFEST_ID); if (depotId == ContentDownloader.INVALID_DEPOT_ID && manifestId != ContentDownloader.INVALID_MANIFEST_ID) { Console.WriteLine("Error: -manifest requires -depot to be specified"); return(1); } } if (InitializeSteam(username, password)) { try { await ContentDownloader.DownloadAppAsync(appId, depotId, manifestId, branch, os, isUGC).ConfigureAwait(false); } catch (Exception ex) when( ex is ContentDownloaderException || ex is OperationCanceledException) { Console.WriteLine(ex.Message); return(1); } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine("Error: InitializeSteam failed"); return(1); } #endregion } return(0); }
private void LogOnCallback(SteamUser.LoggedOnCallback loggedOn) { bool isSteamGuard = loggedOn.Result == EResult.AccountLogonDenied; bool is2FA = loggedOn.Result == EResult.AccountLoginDeniedNeedTwoFactor; bool isLoginKey = ContentDownloader.Config.RememberPassword && logonDetails.LoginKey != null && loggedOn.Result == EResult.InvalidPassword; if (isSteamGuard || is2FA || isLoginKey) { bExpectingDisconnectRemote = true; Abort(false); if (!isLoginKey) { Console.WriteLine("This account is protected by Steam Guard."); } if (is2FA) { Console.Write("Please enter your 2 factor auth code from your authenticator app: "); logonDetails.TwoFactorCode = Console.ReadLine(); } else if (isLoginKey) { AccountSettingsStore.Instance.LoginKeys.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.WriteLine("Login key was expired. Please enter your password: "******"Please enter the authentication code sent to your email address: "); logonDetails.AuthCode = Console.ReadLine(); } Console.Write("Retrying Steam3 connection..."); Connect(); return; } else if (loggedOn.Result == EResult.ServiceUnavailable) { Console.WriteLine("Unable to login to Steam3: {0}", loggedOn.Result); Abort(false); return; } else if (loggedOn.Result != EResult.OK) { Console.WriteLine("Unable to login to Steam3: {0}", loggedOn.Result); Abort(); return; } Console.WriteLine(" Done!"); this.seq++; credentials.LoggedOn = true; if (ContentDownloader.Config.CellID == 0) { Console.WriteLine("Using Steam3 suggested CellID: " + loggedOn.CellID); ContentDownloader.Config.CellID = ( int )loggedOn.CellID; } }
public Steam3Session(SteamUser.LogOnDetails details) { this.logonDetails = details; this.authenticatedUser = details.Username != null; this.credentials = new Credentials(); this.bConnected = false; this.bConnecting = false; this.bAborted = false; this.bExpectingDisconnectRemote = false; this.bDidDisconnect = false; this.bDidReceiveLoginKey = false; this.seq = 0; this.AppTickets = new Dictionary <uint, byte[]>(); this.AppTokens = new Dictionary <uint, ulong>(); this.PackageTokens = new Dictionary <uint, ulong>(); this.DepotKeys = new Dictionary <uint, byte[]>(); this.CDNAuthTokens = new ConcurrentDictionary <string, TaskCompletionSource <SteamApps.CDNAuthTokenCallback> >(); this.AppInfo = new Dictionary <uint, SteamApps.PICSProductInfoCallback.PICSProductInfo>(); this.PackageInfo = new Dictionary <uint, SteamApps.PICSProductInfoCallback.PICSProductInfo>(); this.AppBetaPasswords = new Dictionary <string, byte[]>(); this.steamClient = new SteamClient(); this.steamUser = this.steamClient.GetHandler <SteamUser>(); this.steamApps = this.steamClient.GetHandler <SteamApps>(); var steamUnifiedMessages = this.steamClient.GetHandler <SteamUnifiedMessages>(); this.steamPublishedFile = steamUnifiedMessages.CreateService <IPublishedFile>(); this.callbacks = new CallbackManager(this.steamClient); this.callbacks.Subscribe <SteamClient.ConnectedCallback>(ConnectedCallback); this.callbacks.Subscribe <SteamClient.DisconnectedCallback>(DisconnectedCallback); this.callbacks.Subscribe <SteamUser.LoggedOnCallback>(LogOnCallback); this.callbacks.Subscribe <SteamUser.SessionTokenCallback>(SessionTokenCallback); this.callbacks.Subscribe <SteamApps.LicenseListCallback>(LicenseListCallback); this.callbacks.Subscribe <SteamUser.UpdateMachineAuthCallback>(UpdateMachineAuthCallback); this.callbacks.Subscribe <SteamUser.LoginKeyCallback>(LoginKeyCallback); Console.Write("Connecting to Steam3..."); if (authenticatedUser) { FileInfo fi = new FileInfo(String.Format("{0}.sentryFile", logonDetails.Username)); if (AccountSettingsStore.Instance.SentryData != null && AccountSettingsStore.Instance.SentryData.ContainsKey(logonDetails.Username)) { logonDetails.SentryFileHash = Util.SHAHash(AccountSettingsStore.Instance.SentryData[logonDetails.Username]); } else if (fi.Exists && fi.Length > 0) { var sentryData = File.ReadAllBytes(fi.FullName); logonDetails.SentryFileHash = Util.SHAHash(sentryData); AccountSettingsStore.Instance.SentryData[logonDetails.Username] = sentryData; AccountSettingsStore.Save(); } } Connect(); }
static async Task <int> MainAsync(string[] args) { if (args.Length == 0) { PrintUsage(); return(1); } DebugLog.Enabled = false; AccountSettingsStore.LoadFromFile("account.config"); #region Common Options if (HasParameter(args, "-debug")) { DebugLog.Enabled = true; DebugLog.AddListener((category, message) => { Console.WriteLine("[{0}] {1}", category, message); }); } string username = GetParameter <string>(args, "-username") ?? GetParameter <string>(args, "-user"); string password = GetParameter <string>(args, "-password") ?? GetParameter <string>(args, "-pass"); ContentDownloader.Config.RememberPassword = HasParameter(args, "-remember-password"); ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); int cellId = GetParameter <int>(args, "-cellid", -1); if (cellId == -1) { cellId = 0; } ContentDownloader.Config.CellID = cellId; string fileList = GetParameter <string>(args, "-filelist"); if (fileList != null) { try { string fileListData = await File.ReadAllTextAsync(fileList); var files = fileListData.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); ContentDownloader.Config.UsingFileList = true; ContentDownloader.Config.FilesToDownload = new HashSet <string>(StringComparer.OrdinalIgnoreCase); ContentDownloader.Config.FilesToDownloadRegex = new List <Regex>(); foreach (var fileEntry in files) { if (fileEntry.StartsWith("regex:")) { Regex rgx = new Regex(fileEntry.Substring(6), RegexOptions.Compiled | RegexOptions.IgnoreCase); ContentDownloader.Config.FilesToDownloadRegex.Add(rgx); } else { ContentDownloader.Config.FilesToDownload.Add(fileEntry.Replace('\\', '/')); } } Console.WriteLine("Using filelist: '{0}'.", fileList); } catch (Exception ex) { Console.WriteLine("Warning: Unable to load filelist: {0}", ex.ToString()); } } ContentDownloader.Config.InstallDirectory = GetParameter <string>(args, "-dir"); ContentDownloader.Config.VerifyAll = HasParameter(args, "-verify-all") || HasParameter(args, "-verify_all") || HasParameter(args, "-validate"); ContentDownloader.Config.MaxServers = GetParameter <int>(args, "-max-servers", 20); ContentDownloader.Config.MaxDownloads = GetParameter <int>(args, "-max-downloads", 8); ContentDownloader.Config.MaxServers = Math.Max(ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads); ContentDownloader.Config.LoginID = HasParameter(args, "-loginid") ? (uint?)GetParameter <uint>(args, "-loginid") : null; #endregion uint appId = GetParameter <uint>(args, "-app", ContentDownloader.INVALID_APP_ID); if (appId == ContentDownloader.INVALID_APP_ID) { Console.WriteLine("Error: -app not specified!"); return(1); } ulong pubFile = GetParameter <ulong>(args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID); ulong ugcId = GetParameter <ulong>(args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID); if (pubFile != ContentDownloader.INVALID_MANIFEST_ID) { #region Pubfile Downloading if (InitializeSteam(username, password, null)) { try { await ContentDownloader.DownloadPubfileAsync(appId, pubFile).ConfigureAwait(false); } catch (Exception ex) when( ex is ContentDownloaderException || ex is OperationCanceledException) { Console.WriteLine(ex.Message); return(1); } catch (Exception e) { Console.WriteLine("Download failed to due to an unhandled exception: {0}", e.Message); throw; } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine("Error: InitializeSteam failed"); return(1); } #endregion } else if (ugcId != ContentDownloader.INVALID_MANIFEST_ID) { #region UGC Downloading if (InitializeSteam(username, password, null)) { try { await ContentDownloader.DownloadUGCAsync(appId, ugcId).ConfigureAwait(false); } catch (Exception ex) when( ex is ContentDownloaderException || ex is OperationCanceledException) { Console.WriteLine(ex.Message); return(1); } catch (Exception e) { Console.WriteLine("Download failed to due to an unhandled exception: {0}", e.Message); throw; } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine("Error: InitializeSteam failed"); return(1); } #endregion } else { #region App downloading string branch = GetParameter <string>(args, "-branch") ?? GetParameter <string>(args, "-beta") ?? ContentDownloader.DEFAULT_BRANCH; ContentDownloader.Config.BetaPassword = GetParameter <string>(args, "-betapassword"); ContentDownloader.Config.DownloadAllPlatforms = HasParameter(args, "-all-platforms"); string os = GetParameter <string>(args, "-os", null); if (ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty(os)) { Console.WriteLine("Error: Cannot specify -os when -all-platforms is specified."); return(1); } string arch = GetParameter <string>(args, "-osarch", null); ContentDownloader.Config.DownloadAllLanguages = HasParameter(args, "-all-languages"); string language = GetParameter <string>(args, "-language", null); if (ContentDownloader.Config.DownloadAllLanguages && !String.IsNullOrEmpty(language)) { Console.WriteLine("Error: Cannot specify -language when -all-languages is specified."); return(1); } bool lv = HasParameter(args, "-lowviolence"); List <(uint, ulong)> depotManifestIds = new List <(uint, ulong)>(); List <(uint, byte[])> depotDepotkeys = new List <(uint, byte[])>(); bool isUGC = false; List <uint> depotIdList = GetParameterList <uint>(args, "-depot"); List <string> depotKeyList = GetParameterList <string>(args, "-depotkey"); List <ulong> manifestIdList = GetParameterList <ulong>(args, "-manifest"); if (manifestIdList.Count > 0) { if (depotIdList.Count != manifestIdList.Count) { Console.WriteLine("Error: -manifest requires one id for every -depot specified"); return(1); } var zippedDepotManifest = depotIdList.Zip(manifestIdList, (depotId, manifestId) => (depotId, manifestId)); depotManifestIds.AddRange(zippedDepotManifest); } else { depotManifestIds.AddRange(depotIdList.Select(depotId => (depotId, ContentDownloader.INVALID_MANIFEST_ID))); } if (depotKeyList.Count > 0) { if (depotIdList.Count != depotKeyList.Count) { Console.WriteLine("Error: -depotkey requires one key for every -depot specified"); return(1); } var zippedDepotKeys = depotIdList.Zip(depotKeyList, (depotId, depotkey) => (depotId, Util.DecodeHexString(depotkey))); depotDepotkeys.AddRange(zippedDepotKeys); } if (InitializeSteam(username, password, depotDepotkeys)) { try { await ContentDownloader.DownloadAppAsync(appId, depotManifestIds, branch, os, arch, language, lv, isUGC).ConfigureAwait(false); } catch (Exception ex) when( ex is ContentDownloaderException || ex is OperationCanceledException) { Console.WriteLine(ex.Message); return(1); } catch (Exception e) { Console.WriteLine("Download failed to due to an unhandled exception: {0}", e.Message); throw; } finally { ContentDownloader.ShutdownSteam3(); } } else { Console.WriteLine("Error: InitializeSteam failed"); return(1); } #endregion } return(0); }