From a0aeb80d0690cc54b0cc2291f9b49911f8854a6d Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Mon, 4 Jul 2011 16:26:45 -0500 Subject: [PATCH 1/4] Check if the user has access to a depot before attempting to download it. --- .../DepotDownloader/CDRManager.cs | 27 +++++++++++++++++++ .../DepotDownloader/ContentDownloader.cs | 25 +++++++++++++++++ .../DepotDownloader/Steam3Session.cs | 24 ++++++++++++++++- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/Projects/DepotDownloader/DepotDownloader/CDRManager.cs b/Projects/DepotDownloader/DepotDownloader/CDRManager.cs index 9a9e1163..75170b89 100644 --- a/Projects/DepotDownloader/DepotDownloader/CDRManager.cs +++ b/Projects/DepotDownloader/DepotDownloader/CDRManager.cs @@ -12,6 +12,9 @@ namespace DepotDownloader { [BlobField( FieldKey = CDRFields.eFieldApplicationsRecord, Depth = 1, Complex = true )] public List Apps { get; set; } + + [BlobField( FieldKey = CDRFields.eFieldSubscriptionsRecord, Depth = 1, Complex = true )] + public List Subs { get; set; } } class App @@ -35,6 +38,15 @@ namespace DepotDownloader public Dictionary UserDefined { get; private set; } } + class Sub + { + [BlobField( FieldKey = CDRSubRecordFields.eFieldSubId, Depth = 1 )] + public int SubID { get; set; } + + [BlobField( FieldKey = CDRSubRecordFields.eFieldAppIdsRecord, Depth = 1 )] + public List AppIDs { get; private set; } + } + class AppVersion { [BlobField( FieldKey = CDRAppVersionFields.eFieldVersionId )] @@ -121,6 +133,11 @@ namespace DepotDownloader return cdrObj.Apps.Find( ( app ) => app.AppID == appID ); } + static Sub GetSubBlob( int subID ) + { + return cdrObj.Subs.Find( ( sub ) => sub.SubID == subID ); + } + public static string GetDepotName( int depotId ) { // Match hardcoded names from hldsupdatetool for certain HL1 depots @@ -352,6 +369,16 @@ namespace DepotDownloader Console.WriteLine( "\t\"{0}\"", game ); } + public static bool SubHasDepot( int subId, int depotId ) + { + Sub sub = GetSubBlob( subId ); + + if ( sub == null ) + return false; + + return sub.AppIDs.Contains( depotId ); + } + static byte[] GetCdr() { try diff --git a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs index ffb408e8..0ffeec26 100644 --- a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs +++ b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs @@ -108,6 +108,20 @@ namespace DepotDownloader return false; } + static bool AccountHasAccess( int depotId ) + { + if ( steam3 == null || steam3.Licenses == null ) + return CDRManager.SubHasDepot( 0, depotId ); + + foreach ( var license in steam3.Licenses ) + { + if ( CDRManager.SubHasDepot( ( int )license.PackageID, depotId ) ) + return true; + } + + return false; + } + public static void Download( int depotId, int depotVersion, int cellId, string username, string password, bool onlyManifest, bool gameServer, bool exclude, string installDir, string[] fileList ) { if ( !CreateDirectories( depotId, depotVersion, ref installDir ) ) @@ -135,6 +149,17 @@ namespace DepotDownloader credentials = GetCredentials( ( uint )depotId, username, password ); } + if ( !AccountHasAccess( depotId ) ) + { + string contentName = CDRManager.GetDepotName( depotId ); + Console.WriteLine( "Depot {0} ({1}) is not available from this account.", depotId, contentName ); + + if ( steam3 != null ) + steam3.Disconnect(); + + return; + } + string manifestFile = Path.Combine( installDir, "manifest.bin" ); string txtManifest = Path.Combine( installDir, "manifest.txt" ); diff --git a/Projects/DepotDownloader/DepotDownloader/Steam3Session.cs b/Projects/DepotDownloader/DepotDownloader/Steam3Session.cs index c3dd5a96..c94ca21c 100644 --- a/Projects/DepotDownloader/DepotDownloader/Steam3Session.cs +++ b/Projects/DepotDownloader/DepotDownloader/Steam3Session.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using SteamKit2; using System.Threading; +using System.Collections.ObjectModel; namespace DepotDownloader { @@ -18,6 +19,12 @@ namespace DepotDownloader public byte[] AppTicket { get; set; } } + public ReadOnlyCollection Licenses + { + get; + private set; + } + SteamClient steamClient; SteamUser steamUser; @@ -90,7 +97,7 @@ namespace DepotDownloader if ( diff > STEAM3_TIMEOUT && !bConnected ) break; - if ( credentials.HasSessionToken && credentials.AppTicket != null ) + if ( credentials.HasSessionToken && credentials.AppTicket != null && Licenses != null ) break; if ( callback == null ) @@ -162,6 +169,21 @@ namespace DepotDownloader credentials.SessionToken = msg.SessionToken; credentials.HasSessionToken = true; } + + if ( callback.IsType() ) + { + var msg = callback as SteamApps.LicenseListCallback; + + if ( msg.Result != EResult.OK ) + { + Console.WriteLine( "Unable to get license list: {0} ", msg.Result ); + steamUser.LogOff(); + break; + } + + Console.WriteLine( "Got {0} licenses for account!", msg.LicenseList.Count ); + Licenses = msg.LicenseList; + } } credentialHandle.Set(); From 5275fde9c3a9a694f596bb244cdce478228c0907 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Mon, 4 Jul 2011 16:30:12 -0500 Subject: [PATCH 2/4] If the content server client fails to open a storage session, keep retrying. This behavior matches hldsupdatetool. --- .../DepotDownloader/ContentDownloader.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs index 0ffeec26..421a257a 100644 --- a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs +++ b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs @@ -14,6 +14,7 @@ namespace DepotDownloader static class ContentDownloader { const string DEFAULT_DIR = "depots"; + const int STORAGE_RETRY_COUNT = 500; static Steam3Session steam3; @@ -165,22 +166,28 @@ namespace DepotDownloader ContentServerClient csClient = new ContentServerClient(); - csClient.Connect( contentServer ); - - ContentServerClient.StorageSession session = null; - try - { - session = csClient.OpenStorage( ( uint )depotId, ( uint )depotVersion, ( uint )cellId, credentials ); - } - catch ( Steam2Exception ex ) - { - Console.WriteLine( "Unable to open storage: " + ex.Message ); + int retryCount = 0; - if ( steam3 != null ) - steam3.Disconnect(); + while ( session == null ) + { + try + { + csClient.Connect( contentServer ); + session = csClient.OpenStorage( ( uint )depotId, ( uint )depotVersion, ( uint )cellId, credentials ); + } + catch ( Steam2Exception ex ) + { + csClient.Disconnect(); + retryCount++; - return; + if (retryCount > STORAGE_RETRY_COUNT) + { + if (steam3 != null) + steam3.Disconnect(); + return; + } + } } using ( session ) From 61b8b6c97557711199b9bc21f9be3cfaaf339b73 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Thu, 7 Jul 2011 22:27:56 -0500 Subject: [PATCH 3/4] Fixed compiler warning by adding back forgotten error message for opening a storage session. --- .../DepotDownloader/DepotDownloader/ContentDownloader.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs index 421a257a..0bcacd8f 100644 --- a/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs +++ b/Projects/DepotDownloader/DepotDownloader/ContentDownloader.cs @@ -14,7 +14,7 @@ namespace DepotDownloader static class ContentDownloader { const string DEFAULT_DIR = "depots"; - const int STORAGE_RETRY_COUNT = 500; + const int MAX_STORAGE_RETRIES = 500; static Steam3Session steam3; @@ -181,8 +181,10 @@ namespace DepotDownloader csClient.Disconnect(); retryCount++; - if (retryCount > STORAGE_RETRY_COUNT) + if ( retryCount > MAX_STORAGE_RETRIES ) { + Console.WriteLine( "Unable to open storage: " + ex.Message ); + if (steam3 != null) steam3.Disconnect(); return; From 20cc0a5998746b264c16efa7e86318940dd1a465 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Thu, 7 Jul 2011 22:27:57 -0500 Subject: [PATCH 4/4] Added -beta parameter to download beta versions of depots if available. --- Projects/DepotDownloader/DepotDownloader/CDRManager.cs | 8 +++++++- Projects/DepotDownloader/DepotDownloader/Program.cs | 8 +++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Projects/DepotDownloader/DepotDownloader/CDRManager.cs b/Projects/DepotDownloader/DepotDownloader/CDRManager.cs index 75170b89..32e34d1d 100644 --- a/Projects/DepotDownloader/DepotDownloader/CDRManager.cs +++ b/Projects/DepotDownloader/DepotDownloader/CDRManager.cs @@ -36,6 +36,9 @@ namespace DepotDownloader [BlobField( FieldKey = CDRAppRecordFields.eFieldUserDefinedRecord, Depth = 1 )] public Dictionary UserDefined { get; private set; } + + [BlobField( FieldKey = CDRAppRecordFields.eFieldBetaVersionId, Depth = 1 )] + public int BetaVersion { get; set; } } class Sub @@ -158,7 +161,7 @@ namespace DepotDownloader return app.Name; } - public static int GetLatestDepotVersion( int depotId ) + public static int GetLatestDepotVersion( int depotId, bool beta ) { App app = GetAppBlob( depotId ); @@ -167,6 +170,9 @@ namespace DepotDownloader return -1; } + if ( beta && app.BetaVersion > app.CurrentVersion ) + return app.BetaVersion; + return app.CurrentVersion; } diff --git a/Projects/DepotDownloader/DepotDownloader/Program.cs b/Projects/DepotDownloader/DepotDownloader/Program.cs index 6d7fe48d..a74b4fd0 100644 --- a/Projects/DepotDownloader/DepotDownloader/Program.cs +++ b/Projects/DepotDownloader/DepotDownloader/Program.cs @@ -59,10 +59,11 @@ namespace DepotDownloader } int depotVersion = GetIntParameter( args, "-version" ); + bool bBeta = HasParameter( args, "-beta" ); if ( !bGameserver && !bApp && depotVersion == -1 ) { - int latestVer = CDRManager.GetLatestDepotVersion( depotId ); + int latestVer = CDRManager.GetLatestDepotVersion( depotId, bBeta ); if ( latestVer == -1 ) { @@ -134,7 +135,7 @@ namespace DepotDownloader foreach ( int currentDepotId in depotIDs ) { - depotVersion = CDRManager.GetLatestDepotVersion( currentDepotId ); + depotVersion = CDRManager.GetLatestDepotVersion( currentDepotId, bBeta ); if ( depotVersion == -1 ) { Console.WriteLine( "Error: Unable to find DepotID {0} in the CDR!", currentDepotId ); @@ -208,7 +209,8 @@ namespace DepotDownloader Console.WriteLine( "\t-dir installdir\t\t\t- the directory in which to place downloaded files." ); Console.WriteLine( "\t-filelist filename.txt\t\t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); Console.WriteLine( "\t-no-exclude\t\t\t- don't exclude any files when downloading depots with the -game parameter." ); - Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -game or -app is used.\n" ); + Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -game or -app is used." ); + Console.WriteLine( "\t-beta\t\t\t\t- download beta version of depots if available." ); } } }