Esempio n. 1
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

            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;
        }
Esempio n. 2
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();
        }
Esempio n. 5
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

            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);
        }