diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs
index caa50eba..c7dd46cf 100644
--- a/DepotDownloader/ContentDownloader.cs
+++ b/DepotDownloader/ContentDownloader.cs
@@ -231,59 +231,62 @@ namespace DepotDownloader
}
var manifests = depotChild["manifests"];
- var manifests_encrypted = depotChild["encryptedmanifests"];
- if (manifests.Children.Count == 0 && manifests_encrypted.Children.Count == 0)
+ if (manifests.Children.Count == 0)
return INVALID_MANIFEST_ID;
var node = manifests[branch]["gid"];
- if (node == KeyValue.Invalid && !string.Equals(branch, DEFAULT_BRANCH, StringComparison.OrdinalIgnoreCase))
- {
- var node_encrypted = manifests_encrypted[branch];
- if (node_encrypted != KeyValue.Invalid)
- {
- var password = Config.BetaPassword;
- while (string.IsNullOrEmpty(password))
- {
- Console.Write("Please enter the password for branch {0}: ", branch);
- Config.BetaPassword = password = Console.ReadLine();
- }
+ // Non passworded branch, found the manifest
+ if (node.Value != null)
+ return ulong.Parse(node.Value);
- var encrypted_gid = node_encrypted["gid"];
+ // If we requested public branch and it had no manifest, nothing to do
+ if (string.Equals(branch, DEFAULT_BRANCH, StringComparison.OrdinalIgnoreCase))
+ return INVALID_MANIFEST_ID;
- if (encrypted_gid != KeyValue.Invalid)
- {
- // Submit the password to Steam now to get encryption keys
- await steam3.CheckAppBetaPassword(appId, Config.BetaPassword);
+ // Either the branch just doesn't exist, or it has a password
+ var password = Config.BetaPassword;
- if (!steam3.AppBetaPasswords.TryGetValue(branch, out var appBetaPassword))
- {
- Console.WriteLine("Password was invalid for branch {0}", branch);
- return INVALID_MANIFEST_ID;
- }
+ if (string.IsNullOrEmpty(password))
+ {
+ Console.WriteLine($"Branch {branch} was not found, either it does not exist or it has a password.");
+ }
- var input = Util.DecodeHexString(encrypted_gid.Value);
- byte[] manifest_bytes;
- try
- {
- manifest_bytes = Util.SymmetricDecryptECB(input, appBetaPassword);
- }
- catch (Exception e)
- {
- Console.WriteLine("Failed to decrypt branch {0}: {1}", branch, e.Message);
- return INVALID_MANIFEST_ID;
- }
+ while (string.IsNullOrEmpty(password))
+ {
+ Console.Write($"Please enter the password for branch {branch}: ");
+ Config.BetaPassword = password = Console.ReadLine();
+ }
- return BitConverter.ToUInt64(manifest_bytes, 0);
- }
+ if (!steam3.AppBetaPasswords.ContainsKey(branch))
+ {
+ // Submit the password to Steam now to get encryption keys
+ await steam3.CheckAppBetaPassword(appId, Config.BetaPassword);
- Console.WriteLine("Unhandled depot encryption for depotId {0}", depotId);
+ if (!steam3.AppBetaPasswords.TryGetValue(branch, out var appBetaPassword))
+ {
+ Console.WriteLine($"Error: Password was invalid for branch {branch} (or the branch does not exist)");
return INVALID_MANIFEST_ID;
}
+ }
+
+ // Got the password, request private depot section
+ // TODO: We're probably repeating this request for every depot?
+ var privateDepotSection = await steam3.GetPrivateBetaDepotSection(appId, branch);
+ // Now repeat the same code to get the manifest gid from depot section
+ depotChild = privateDepotSection[depotId.ToString()];
+
+ if (depotChild == KeyValue.Invalid)
return INVALID_MANIFEST_ID;
- }
+
+ manifests = depotChild["manifests"];
+
+ if (manifests.Children.Count == 0)
+ return INVALID_MANIFEST_ID;
+
+ node = manifests[branch]["gid"];
if (node.Value == null)
return INVALID_MANIFEST_ID;
diff --git a/DepotDownloader/DepotDownloader.csproj b/DepotDownloader/DepotDownloader.csproj
index 1dfcf0ff..976d7740 100644
--- a/DepotDownloader/DepotDownloader.csproj
+++ b/DepotDownloader/DepotDownloader.csproj
@@ -4,7 +4,7 @@
net9.0
true
LatestMajor
- 3.0.0
+ 3.2.0
Steam Downloading Utility
SteamRE Team
Copyright © SteamRE Team 2025
@@ -25,8 +25,8 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+
diff --git a/DepotDownloader/Program.cs b/DepotDownloader/Program.cs
index 475c20ba..ae9be3bf 100644
--- a/DepotDownloader/Program.cs
+++ b/DepotDownloader/Program.cs
@@ -249,6 +249,12 @@ namespace DepotDownloader
var branch = GetParameter(args, "-branch") ?? GetParameter(args, "-beta") ?? ContentDownloader.DEFAULT_BRANCH;
ContentDownloader.Config.BetaPassword = GetParameter(args, "-branchpassword") ?? GetParameter(args, "-betapassword");
+ if (!string.IsNullOrEmpty(ContentDownloader.Config.BetaPassword) && string.IsNullOrEmpty(branch))
+ {
+ Console.WriteLine("Error: Cannot specify -branchpassword when -branch is not specified.");
+ return 1;
+ }
+
ContentDownloader.Config.DownloadAllPlatforms = HasParameter(args, "-all-platforms");
var os = GetParameter(args, "-os");
diff --git a/DepotDownloader/Steam3Session.cs b/DepotDownloader/Steam3Session.cs
index 9ebfe536..0155b6a8 100644
--- a/DepotDownloader/Steam3Session.cs
+++ b/DepotDownloader/Steam3Session.cs
@@ -310,6 +310,22 @@ namespace DepotDownloader
}
}
+ public async Task GetPrivateBetaDepotSection(uint appid, string branch)
+ {
+ if (!AppBetaPasswords.TryGetValue(branch, out var branchPassword)) // Should be filled by CheckAppBetaPassword
+ {
+ return new KeyValue();
+ }
+
+ AppTokens.TryGetValue(appid, out var accessToken); // Should be filled by RequestAppInfo
+
+ var privateBeta = await steamApps.PICSGetPrivateBeta(appid, accessToken, branch, branchPassword);
+
+ Console.WriteLine($"Retrieved private beta depot section for {appid} with result: {privateBeta.Result}");
+
+ return privateBeta.DepotSection;
+ }
+
public async Task GetPublishedFileDetails(uint appId, PublishedFileID pubFile)
{
var pubFileRequest = new CPublishedFile_GetDetails_Request { appid = appId };