From 72f633eadef37c54890868d45e1779c7955bd0d1 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 23 Mar 2019 12:02:05 -0400 Subject: [PATCH 1/5] Add new -ugc option, removing -force-depot. (#41) Also improve and clean up command line usage output, as well as add automatic lookup of correct workshop depot id for UGC, instead of requiring it on command line (usually assuming app id). --- DepotDownloader/ContentDownloader.cs | 40 ++++++++------- DepotDownloader/DownloadConfig.cs | 2 - DepotDownloader/Program.cs | 73 +++++++++++++++++----------- 3 files changed, 67 insertions(+), 48 deletions(-) diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index b2c99abe..c2d171c2 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -197,9 +197,6 @@ namespace DepotDownloader static ulong GetSteam3DepotManifest( uint depotId, uint appId, string branch ) { - if ( Config.ManifestId != INVALID_MANIFEST_ID ) - return Config.ManifestId; - KeyValue depots = GetSteam3AppSection( appId, EAppInfoSection.Depots ); KeyValue depotChild = depots[ depotId.ToString() ]; @@ -376,7 +373,7 @@ namespace DepotDownloader steam3.Disconnect(); } - public static async Task DownloadAppAsync( uint appId, uint depotId, string branch, string os = null, bool forceDepot = false ) + public static async Task DownloadAppAsync( uint appId, uint depotId, ulong manifestId, string branch, string os, bool isUgc ) { if ( steam3 != null ) steam3.RequestAppInfo( appId ); @@ -401,8 +398,12 @@ namespace DepotDownloader KeyValue depots = GetSteam3AppSection( appId, EAppInfoSection.Depots ); - if ( forceDepot ) + if ( isUgc ) { + var workshopDepot = depots["workshopdepot"].AsUnsignedInteger(); + if (workshopDepot != 0) + depotId = workshopDepot; + depotIDs.Add( depotId ); } else @@ -456,7 +457,7 @@ namespace DepotDownloader foreach ( var depot in depotIDs ) { - var info = GetDepotInfo( depot, appId, branch ); + var info = GetDepotInfo( depot, appId, manifestId, branch ); if ( info != null ) { infos.Add( info ); @@ -473,7 +474,7 @@ namespace DepotDownloader } } - static DepotDownloadInfo GetDepotInfo( uint depotId, uint appId, string branch ) + static DepotDownloadInfo GetDepotInfo( uint depotId, uint appId, ulong manifestId, string branch ) { if ( steam3 != null && appId != INVALID_APP_ID ) steam3.RequestAppInfo( ( uint )appId ); @@ -490,18 +491,21 @@ namespace DepotDownloader // Skip requesting an app ticket steam3.AppTickets[ depotId ] = null; - ulong manifestID = GetSteam3DepotManifest( depotId, appId, branch ); - if ( manifestID == INVALID_MANIFEST_ID && branch != "public" ) + if (manifestId == INVALID_MANIFEST_ID) { - Console.WriteLine( "Warning: Depot {0} does not have branch named \"{1}\". Trying public branch.", depotId, branch ); - branch = "public"; - manifestID = GetSteam3DepotManifest( depotId, appId, branch ); - } + manifestId = GetSteam3DepotManifest(depotId, appId, branch); + if (manifestId == INVALID_MANIFEST_ID && branch != "public") + { + Console.WriteLine("Warning: Depot {0} does not have branch named \"{1}\". Trying public branch.", depotId, branch); + branch = "public"; + manifestId = GetSteam3DepotManifest(depotId, appId, branch); + } - if ( manifestID == INVALID_MANIFEST_ID ) - { - Console.WriteLine( "Depot {0} ({1}) missing public subsection or manifest section.", depotId, contentName ); - return null; + if (manifestId == INVALID_MANIFEST_ID) + { + Console.WriteLine("Depot {0} ({1}) missing public subsection or manifest section.", depotId, contentName); + return null; + } } uint uVersion = GetSteam3AppBuildNumber( appId, branch ); @@ -522,7 +526,7 @@ namespace DepotDownloader byte[] depotKey = steam3.DepotKeys[ depotId ]; - var info = new DepotDownloadInfo( depotId, manifestID, installDir, contentName ); + var info = new DepotDownloadInfo( depotId, manifestId, installDir, contentName ); info.depotKey = depotKey; return info; } diff --git a/DepotDownloader/DownloadConfig.cs b/DepotDownloader/DownloadConfig.cs index bd2480b7..fc695aa8 100644 --- a/DepotDownloader/DownloadConfig.cs +++ b/DepotDownloader/DownloadConfig.cs @@ -18,8 +18,6 @@ namespace DepotDownloader public string BetaPassword { get; set; } - public ulong ManifestId { get; set; } - public bool VerifyAll { get; set; } public int MaxServers { get; set; } diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs index 62df230e..1c9e3f52 100644 --- a/DepotDownloader/Program.cs +++ b/DepotDownloader/Program.cs @@ -25,24 +25,34 @@ namespace DepotDownloader ConfigStore.LoadFromFile( Path.Combine( Directory.GetCurrentDirectory(), "DepotDownloader.config" ) ); - bool bDumpManifest = HasParameter( args, "-manifest-only" ); uint appId = GetParameter( args, "-app", ContentDownloader.INVALID_APP_ID ); - uint depotId = GetParameter( args, "-depot", ContentDownloader.INVALID_DEPOT_ID ); - ContentDownloader.Config.ManifestId = GetParameter( args, "-manifest", ContentDownloader.INVALID_MANIFEST_ID ); - - if ( appId == ContentDownloader.INVALID_APP_ID ) + if (appId == ContentDownloader.INVALID_APP_ID) { - Console.WriteLine( "Error: -app not specified!" ); + Console.WriteLine("Error: -app not specified!"); return; } - if ( depotId == ContentDownloader.INVALID_DEPOT_ID && ContentDownloader.Config.ManifestId != ContentDownloader.INVALID_MANIFEST_ID ) + uint depotId; + bool isUGC = false; + + ulong manifestId = GetParameter(args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID); + if (manifestId != ContentDownloader.INVALID_MANIFEST_ID) { - Console.WriteLine( "Error: -manifest requires -depot to be specified" ); - return; + depotId = appId; + isUGC = true; + } + else + { + depotId = GetParameter(args, "-depot", ContentDownloader.INVALID_DEPOT_ID); + manifestId = GetParameter(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; + } } - ContentDownloader.Config.DownloadManifestOnly = bDumpManifest; + ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); int cellId = GetParameter( args, "-cellid", -1 ); if ( cellId == -1 ) @@ -98,7 +108,6 @@ namespace DepotDownloader ContentDownloader.Config.MaxServers = GetParameter( args, "-max-servers", 20 ); ContentDownloader.Config.MaxDownloads = GetParameter( args, "-max-downloads", 4 ); string branch = GetParameter( args, "-branch" ) ?? GetParameter( args, "-beta" ) ?? "Public"; - bool forceDepot = HasParameter( args, "-force-depot" ); string os = GetParameter( args, "-os", null ); if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) ) @@ -128,7 +137,7 @@ namespace DepotDownloader if ( ContentDownloader.InitializeSteam3( username, password ) ) { - await ContentDownloader.DownloadAppAsync( appId, depotId, branch, os, forceDepot ).ConfigureAwait( false ); + await ContentDownloader.DownloadAppAsync( appId, depotId, manifestId, branch, os, isUGC ).ConfigureAwait( false ); ContentDownloader.ShutdownSteam3(); } } @@ -167,28 +176,36 @@ namespace DepotDownloader static void PrintUsage() { - Console.WriteLine( "\nUsage: depotdownloader [optional parameters]\n" ); - + Console.WriteLine(); + Console.WriteLine( "Usage: depotdownloader -app [-depot [-manifest ] | -ugc ]" ); + Console.WriteLine( "\t\t[-username [-password ]] [other options]" ); + Console.WriteLine(); Console.WriteLine( "Parameters:" ); Console.WriteLine( "\t-app <#>\t\t\t\t- the AppID to download." ); Console.WriteLine(); - Console.WriteLine( "Optional Parameters:" ); - Console.WriteLine( "\t-depot <#>\t\t\t- the DepotID to download." ); - Console.WriteLine( "\t-cellid <#>\t\t\t- the overridden CellID of the content server to download from." ); - Console.WriteLine( "\t-username \t\t\t- the username of the account to login to for restricted content." ); - Console.WriteLine( "\t-password \t\t\t- the password of the account to login to for restricted content." ); - Console.WriteLine( "\t-remember-password\t\t\t- if set, remember the password for subsequent logins of this user." ); - Console.WriteLine( "\t-dir \t\t\t- the directory in which to place downloaded files." ); - Console.WriteLine( "\t-os \t\t\t- the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)" ); - Console.WriteLine( "\t-filelist \t\t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); + Console.WriteLine( "\t-depot <#>\t\t\t\t- the DepotID to download." ); + Console.WriteLine( "\t-manifest \t\t\t- manifest id of content to download (requires -depot, default: current for branch)." ); + Console.WriteLine(); + Console.WriteLine( "\t-ugc <#>\t\t\t\t- the UGC ID to download." ); + Console.WriteLine(); + Console.WriteLine( "\t-username \t\t- the username of the account to login to for restricted content. "); + Console.WriteLine( "\t-password \t\t- the password of the account to login to for restricted content." ); + Console.WriteLine( "\t-remember-password\t\t- if set, remember the password for subsequent logins of this user." ); + Console.WriteLine(); + Console.WriteLine( "\t-beta \t\t\t- download from specified branch if available (default: Public)." ); + Console.WriteLine( "\t-betapassword \t\t- branch password if applicable." ); + Console.WriteLine(); + Console.WriteLine( "\t-dir \t\t- the directory in which to place downloaded files." ); Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -app is used." ); + Console.WriteLine( "\t-os \t\t\t\t- the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)" ); + Console.WriteLine( "\t-filelist \t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); + Console.WriteLine( "\t-validate\t\t\t\t- Include checksum verification of files already downloaded" ); + Console.WriteLine(); Console.WriteLine( "\t-manifest-only\t\t\t- downloads a human readable manifest for any depots that would be downloaded." ); - Console.WriteLine( "\t-beta \t\t\t\t- download from specified branch if available (default: Public)." ); - Console.WriteLine( "\t-betapassword \t\t\t- branch password if applicable." ); - Console.WriteLine( "\t-manifest \t\t\t- manifest id of content to download (requires -depot, default: current for branch)." ); - Console.WriteLine( "\t-max-servers <#>\t\t\t- maximum number of content servers to use. (default: 8)." ); - Console.WriteLine( "\t-max-downloads <#>\t\t\t- maximum number of chunks to download concurrently. (default: 4)." ); + Console.WriteLine( "\t-cellid <#>\t\t\t\t- the overridden CellID of the content server to download from." ); + Console.WriteLine( "\t-max-servers <#>\t\t- maximum number of content servers to use. (default: 8)." ); + Console.WriteLine( "\t-max-downloads <#>\t\t- maximum number of chunks to download concurrently. (default: 4)." ); } } } From a2ffdd30f501fa6e8a1e53e4ea244a5417aa313f Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 23 Mar 2019 12:02:21 -0400 Subject: [PATCH 2/5] Misc cleanup to avoid unnecessary conversions. --- DepotDownloader/ContentDownloader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index c2d171c2..f8aaca7b 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -125,10 +125,10 @@ namespace DepotDownloader SteamApps.PICSProductInfoCallback.PICSProductInfo package; if ( steam3.PackageInfo.TryGetValue( license, out package ) && package != null ) { - if ( package.KeyValues[ "appids" ].Children.Any( child => child.AsInteger() == depotId ) ) + if ( package.KeyValues[ "appids" ].Children.Any( child => child.AsUnsignedInteger() == depotId ) ) return true; - if ( package.KeyValues[ "depotids" ].Children.Any( child => child.AsInteger() == depotId ) ) + if ( package.KeyValues[ "depotids" ].Children.Any( child => child.AsUnsignedInteger() == depotId ) ) return true; } } @@ -208,7 +208,7 @@ namespace DepotDownloader // Rather than relay on the unknown sharedinstall key, just look for manifests. Test cases: 111710, 346680. if ( depotChild[ "manifests" ] == KeyValue.Invalid && depotChild[ "depotfromapp" ] != KeyValue.Invalid ) { - uint otherAppId = ( uint )depotChild[ "depotfromapp" ].AsInteger(); + uint otherAppId = depotChild["depotfromapp"].AsUnsignedInteger(); if ( otherAppId == appId ) { // This shouldn't ever happen, but ya never know with Valve. Don't infinite loop. From 18a57dd1dd6b108d4f73668b598470725869fb0e Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 23 Mar 2019 12:08:41 -0400 Subject: [PATCH 3/5] Update SK from 2.0.0 to 2.1.0 BECAUSE WE CAN. --- DepotDownloader/DepotDownloader.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DepotDownloader/DepotDownloader.csproj b/DepotDownloader/DepotDownloader.csproj index bc9b809f..f8bf887d 100644 --- a/DepotDownloader/DepotDownloader.csproj +++ b/DepotDownloader/DepotDownloader.csproj @@ -6,6 +6,6 @@ - + \ No newline at end of file From f957ef5da9fed84269b3016bfb9a946e45e9879e Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 23 Mar 2019 17:17:10 -0400 Subject: [PATCH 4/5] Add -pubfile support, dynamically getting appId + ugcId. --- DepotDownloader/ContentDownloader.cs | 14 ++- DepotDownloader/Program.cs | 144 +++++++++++++++++---------- DepotDownloader/Steam3Session.cs | 34 +++++++ 3 files changed, 133 insertions(+), 59 deletions(-) diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index f8aaca7b..15381b9b 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -16,6 +16,7 @@ namespace DepotDownloader public const uint INVALID_APP_ID = uint.MaxValue; public const uint INVALID_DEPOT_ID = uint.MaxValue; public const ulong INVALID_MANIFEST_ID = ulong.MaxValue; + public const string DEFAULT_BRANCH = "Public"; public static DownloadConfig Config = new DownloadConfig(); @@ -373,6 +374,12 @@ namespace DepotDownloader steam3.Disconnect(); } + public static async Task DownloadPubfileAsync( ulong publishedFileId ) + { + var details = steam3.GetPubfileDetails(publishedFileId); + await DownloadAppAsync( details.consumer_appid, details.consumer_appid, details.hcontent_file, DEFAULT_BRANCH, null, true ); + } + public static async Task DownloadAppAsync( uint appId, uint depotId, ulong manifestId, string branch, string os, bool isUgc ) { if ( steam3 != null ) @@ -392,12 +399,9 @@ namespace DepotDownloader } } - Console.WriteLine( "Using app branch: '{0}'.", branch ); - var depotIDs = new List(); KeyValue depots = GetSteam3AppSection( appId, EAppInfoSection.Depots ); - if ( isUgc ) { var workshopDepot = depots["workshopdepot"].AsUnsignedInteger(); @@ -408,6 +412,8 @@ namespace DepotDownloader } else { + Console.WriteLine( "Using app branch: '{0}'.", branch ); + if ( depots != null ) { foreach ( var depotSection in depots.Children ) @@ -918,7 +924,7 @@ namespace DepotDownloader ConfigStore.TheConfig.LastManifests[ depot.id ] = depot.manifestId; ConfigStore.Save(); - Console.WriteLine( "Depot {0} - Downloaded {1} bytes ({2} bytes uncompressed)", depot.id, DepotBytesCompressed, DepotBytesUncompressed ); + Console.WriteLine( "Depot {0} - Downloaded {1} bytes ({2} bytes uncompressed)", depot.id, DepotBytesCompressed, DepotBytesUncompressed ); } Console.WriteLine( "Total downloaded: {0} bytes ({1} bytes uncompressed) from {2} depots", TotalBytesCompressed, TotalBytesUncompressed, depots.Count ); diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs index 1c9e3f52..71496a3d 100644 --- a/DepotDownloader/Program.cs +++ b/DepotDownloader/Program.cs @@ -25,34 +25,13 @@ namespace DepotDownloader ConfigStore.LoadFromFile( Path.Combine( Directory.GetCurrentDirectory(), "DepotDownloader.config" ) ); - uint appId = GetParameter( args, "-app", ContentDownloader.INVALID_APP_ID ); - if (appId == ContentDownloader.INVALID_APP_ID) - { - Console.WriteLine("Error: -app not specified!"); - return; - } + #region Common Options - uint depotId; - bool isUGC = false; - - ulong manifestId = GetParameter(args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID); - if (manifestId != ContentDownloader.INVALID_MANIFEST_ID) - { - depotId = appId; - isUGC = true; - } - else - { - depotId = GetParameter(args, "-depot", ContentDownloader.INVALID_DEPOT_ID); - manifestId = GetParameter(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; - } - } + string username = GetParameter( args, "-username" ) ?? GetParameter( args, "-user" ); + string password = GetParameter( args, "-password" ) ?? GetParameter( args, "-pass" ); + ContentDownloader.Config.RememberPassword = HasParameter( args, "-remember-password" ); - ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); + ContentDownloader.Config.DownloadManifestOnly = HasParameter( args, "-manifest-only" ); int cellId = GetParameter( args, "-cellid", -1 ); if ( cellId == -1 ) @@ -61,7 +40,6 @@ namespace DepotDownloader } ContentDownloader.Config.CellID = cellId; - ContentDownloader.Config.BetaPassword = GetParameter( args, "-betapassword" ); string fileList = GetParameter( args, "-filelist" ); string[] files = null; @@ -70,7 +48,7 @@ namespace DepotDownloader { try { - string fileListData = File.ReadAllText( fileList ); + string fileListData = File.ReadAllText(fileList); files = fileListData.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries ); ContentDownloader.Config.UsingFileList = true; @@ -93,36 +71,94 @@ namespace DepotDownloader Console.WriteLine( "Using filelist: '{0}'.", fileList ); } - catch ( Exception ex ) + catch (Exception ex) { Console.WriteLine( "Warning: Unable to load filelist: {0}", ex.ToString() ); } } - string username = GetParameter( args, "-username" ) ?? GetParameter( args, "-user" ); - string password = GetParameter( args, "-password" ) ?? GetParameter( args, "-pass" ); - ContentDownloader.Config.RememberPassword = HasParameter( args, "-remember-password" ); ContentDownloader.Config.InstallDirectory = GetParameter( args, "-dir" ); - ContentDownloader.Config.DownloadAllPlatforms = HasParameter( args, "-all-platforms" ); + ContentDownloader.Config.VerifyAll = HasParameter( args, "-verify-all" ) || HasParameter( args, "-verify_all" ) || HasParameter( args, "-validate" ); ContentDownloader.Config.MaxServers = GetParameter( args, "-max-servers", 20 ); ContentDownloader.Config.MaxDownloads = GetParameter( args, "-max-downloads", 4 ); - string branch = GetParameter( args, "-branch" ) ?? GetParameter( args, "-beta" ) ?? "Public"; - string os = GetParameter( args, "-os", null ); + ContentDownloader.Config.MaxServers = Math.Max( ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads ); - if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) ) + #endregion + + ulong pubFile = GetParameter( args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID ); + if ( pubFile != ContentDownloader.INVALID_MANIFEST_ID ) { - Console.WriteLine( "Error: Cannot specify -os when -all-platforms is specified." ); - return; + #region Pubfile Downloading + + if ( InitializeSteam( username, password ) ) + { + await ContentDownloader.DownloadPubfileAsync( pubFile ).ConfigureAwait( false ); + ContentDownloader.ShutdownSteam3(); + } + + #endregion } + else + { + #region App downloading - ContentDownloader.Config.MaxServers = Math.Max( ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads ); + string branch = GetParameter( args, "-branch" ) ?? GetParameter( args, "-beta" ) ?? ContentDownloader.DEFAULT_BRANCH; + ContentDownloader.Config.BetaPassword = GetParameter( args, "-betapassword" ); + + ContentDownloader.Config.DownloadAllPlatforms = HasParameter( args, "-all-platforms" ); + string os = GetParameter( args, "-os", null ); + + if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) ) + { + Console.WriteLine("Error: Cannot specify -os when -all-platforms is specified."); + return; + } + uint appId = GetParameter( args, "-app", ContentDownloader.INVALID_APP_ID ); + if ( appId == ContentDownloader.INVALID_APP_ID ) + { + Console.WriteLine( "Error: -app not specified!" ); + return; + } + + uint depotId; + bool isUGC = false; + + ulong manifestId = GetParameter( args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID ); + if ( manifestId != ContentDownloader.INVALID_MANIFEST_ID ) + { + depotId = appId; + isUGC = true; + } + else + { + depotId = GetParameter( args, "-depot", ContentDownloader.INVALID_DEPOT_ID ); + manifestId = GetParameter( 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; + } + } + + if ( InitializeSteam( username, password ) ) + { + await ContentDownloader.DownloadAppAsync( appId, depotId, manifestId, branch, os, isUGC ).ConfigureAwait( false ); + ContentDownloader.ShutdownSteam3(); + } + + #endregion + } + } + + static bool InitializeSteam( string username, string password ) + { if ( username != null && password == null && ( !ContentDownloader.Config.RememberPassword || !ConfigStore.TheConfig.LoginKeys.ContainsKey( username ) ) ) { do { - Console.Write("Enter account password for \"{0}\": ", username); + Console.Write( "Enter account password for \"{0}\": ", username ); password = Util.ReadPassword(); Console.WriteLine(); } while ( String.Empty == password ); @@ -135,11 +171,7 @@ namespace DepotDownloader // capture the supplied password in case we need to re-use it after checking the login key ContentDownloader.Config.SuppliedPassword = password; - if ( ContentDownloader.InitializeSteam3( username, password ) ) - { - await ContentDownloader.DownloadAppAsync( appId, depotId, manifestId, branch, os, isUGC ).ConfigureAwait( false ); - ContentDownloader.ShutdownSteam3(); - } + return ContentDownloader.InitializeSteam3( username, password ); } static int IndexOfParam( string[] args, string param ) @@ -177,28 +209,30 @@ namespace DepotDownloader static void PrintUsage() { Console.WriteLine(); - Console.WriteLine( "Usage: depotdownloader -app [-depot [-manifest ] | -ugc ]" ); + Console.WriteLine( "Usage - downloading one or all depots for an app:" ); + Console.WriteLine( "\tdepotdownloader -app [-depot [-manifest ] | [-ugc ]]" ); Console.WriteLine( "\t\t[-username [-password ]] [other options]" ); Console.WriteLine(); + Console.WriteLine( "Usage - downloading a Workshop item published via SteamUGC" ); + Console.WriteLine( "\tdepotdownloader -pubfile [-username [-password ]]" ); + Console.WriteLine(); Console.WriteLine( "Parameters:" ); Console.WriteLine( "\t-app <#>\t\t\t\t- the AppID to download." ); - Console.WriteLine(); - Console.WriteLine( "Optional Parameters:" ); Console.WriteLine( "\t-depot <#>\t\t\t\t- the DepotID to download." ); Console.WriteLine( "\t-manifest \t\t\t- manifest id of content to download (requires -depot, default: current for branch)." ); - Console.WriteLine(); Console.WriteLine( "\t-ugc <#>\t\t\t\t- the UGC ID to download." ); + Console.WriteLine( "\t-beta \t\t\t- download from specified branch if available (default: Public)." ); + Console.WriteLine( "\t-betapassword \t\t- branch password if applicable." ); + Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -app is used." ); + Console.WriteLine( "\t-os \t\t\t\t- the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)" ); Console.WriteLine(); - Console.WriteLine( "\t-username \t\t- the username of the account to login to for restricted content. "); + Console.WriteLine( "\t-pubfile <#>\t\t\t- the PublishedFileId to download. (Will automatically resolve to UGC id)" ); + Console.WriteLine(); + Console.WriteLine( "\t-username \t\t- the username of the account to login to for restricted content."); Console.WriteLine( "\t-password \t\t- the password of the account to login to for restricted content." ); Console.WriteLine( "\t-remember-password\t\t- if set, remember the password for subsequent logins of this user." ); Console.WriteLine(); - Console.WriteLine( "\t-beta \t\t\t- download from specified branch if available (default: Public)." ); - Console.WriteLine( "\t-betapassword \t\t- branch password if applicable." ); - Console.WriteLine(); Console.WriteLine( "\t-dir \t\t- the directory in which to place downloaded files." ); - Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -app is used." ); - Console.WriteLine( "\t-os \t\t\t\t- the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)" ); Console.WriteLine( "\t-filelist \t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); Console.WriteLine( "\t-validate\t\t\t\t- Include checksum verification of files already downloaded" ); Console.WriteLine(); diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 9c1cca11..9bb17abd 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -1,4 +1,5 @@ using SteamKit2; +using SteamKit2.Unified.Internal; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -40,6 +41,7 @@ namespace DepotDownloader public SteamClient steamClient; public SteamUser steamUser; SteamApps steamApps; + SteamUnifiedMessages.UnifiedService steamPublishedFile; CallbackManager callbacks; @@ -85,6 +87,8 @@ namespace DepotDownloader this.steamUser = this.steamClient.GetHandler(); this.steamApps = this.steamClient.GetHandler(); + var steamUnifiedMessages = this.steamClient.GetHandler(); + this.steamPublishedFile = steamUnifiedMessages.CreateService(); this.callbacks = new CallbackManager( this.steamClient ); @@ -202,6 +206,36 @@ namespace DepotDownloader }, () => { return completed; } ); } + public PublishedFileDetails GetPubfileDetails( PublishedFileID pubFile ) + { + var pubFileRequest = new CPublishedFile_GetDetails_Request(); + pubFileRequest.publishedfileids.Add( pubFile ); + + bool completed = false; + PublishedFileDetails details = null; + + Action cbMethod = callback => + { + completed = true; + if ( callback.Result == EResult.OK ) + { + var response = callback.GetDeserializedResponse(); + details = response.publishedfiledetails[0]; + } + else + { + throw new Exception($"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC id for pubfile {pubFile}."); + } + }; + + WaitUntilCallback(() => + { + callbacks.Subscribe( steamPublishedFile.SendMessage( api => api.GetDetails( pubFileRequest ) ), cbMethod ); + }, () => { return completed; }); + + return details; + } + public void RequestPackageInfo( IEnumerable packageIds ) { List packages = packageIds.ToList(); From 3ad0966070c3be88d3d22800524dda3984bb778a Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sun, 24 Mar 2019 08:55:50 -0400 Subject: [PATCH 5/5] Move GetPubfileDetails to saner spot in file. --- DepotDownloader/Steam3Session.cs | 60 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs index 9bb17abd..8c38ab78 100644 --- a/DepotDownloader/Steam3Session.cs +++ b/DepotDownloader/Steam3Session.cs @@ -206,36 +206,6 @@ namespace DepotDownloader }, () => { return completed; } ); } - public PublishedFileDetails GetPubfileDetails( PublishedFileID pubFile ) - { - var pubFileRequest = new CPublishedFile_GetDetails_Request(); - pubFileRequest.publishedfileids.Add( pubFile ); - - bool completed = false; - PublishedFileDetails details = null; - - Action cbMethod = callback => - { - completed = true; - if ( callback.Result == EResult.OK ) - { - var response = callback.GetDeserializedResponse(); - details = response.publishedfiledetails[0]; - } - else - { - throw new Exception($"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC id for pubfile {pubFile}."); - } - }; - - WaitUntilCallback(() => - { - callbacks.Subscribe( steamPublishedFile.SendMessage( api => api.GetDetails( pubFileRequest ) ), cbMethod ); - }, () => { return completed; }); - - return details; - } - public void RequestPackageInfo( IEnumerable packageIds ) { List packages = packageIds.ToList(); @@ -408,6 +378,36 @@ namespace DepotDownloader }, () => { return completed; } ); } + public PublishedFileDetails GetPubfileDetails( PublishedFileID pubFile ) + { + var pubFileRequest = new CPublishedFile_GetDetails_Request(); + pubFileRequest.publishedfileids.Add( pubFile ); + + bool completed = false; + PublishedFileDetails details = null; + + Action cbMethod = callback => + { + completed = true; + if ( callback.Result == EResult.OK ) + { + var response = callback.GetDeserializedResponse(); + details = response.publishedfiledetails[0]; + } + else + { + throw new Exception( $"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC id for pubfile {pubFile}."); + } + }; + + WaitUntilCallback(() => + { + callbacks.Subscribe( steamPublishedFile.SendMessage( api => api.GetDetails( pubFileRequest ) ), cbMethod ); + }, () => { return completed; }); + + return details; + } + void Connect() { bAborted = false;