Compare commits

..

No commits in common. 'master' and 'DepotDownloader_3.1.0' have entirely different histories.

@ -25,10 +25,10 @@ jobs:
env: env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Setup .NET Core - name: Setup .NET Core
uses: actions/setup-dotnet@v5 uses: actions/setup-dotnet@v4
- name: Build - name: Build
run: dotnet publish DepotDownloader/DepotDownloader.csproj -c ${{ matrix.configuration }} -o artifacts /p:ContinuousIntegrationBuild=true run: dotnet publish DepotDownloader/DepotDownloader.csproj -c ${{ matrix.configuration }} -o artifacts /p:ContinuousIntegrationBuild=true

@ -17,10 +17,10 @@ jobs:
env: env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
- name: Setup .NET Core - name: Setup .NET Core
uses: actions/setup-dotnet@v5 uses: actions/setup-dotnet@v4
- name: Configure NuGet - name: Configure NuGet
run: | run: |

@ -14,11 +14,7 @@ jobs:
run: | run: |
$wingetPackage = "SteamRE.DepotDownloader" $wingetPackage = "SteamRE.DepotDownloader"
$headers = @{ $github = Invoke-RestMethod -uri "https://api.github.com/repos/SteamRE/DepotDownloader/releases"
Authorization = "Bearer ${{ secrets.GITHUB_TOKEN }}"
}
$github = Invoke-RestMethod -uri "https://api.github.com/repos/SteamRE/DepotDownloader/releases" -Headers $headers
$targetRelease = $github | Where-Object -Property name -match '^DepotDownloader' | Select -First 1 $targetRelease = $github | Where-Object -Property name -match '^DepotDownloader' | Select -First 1
$assets = $targetRelease | Select -ExpandProperty assets -First 1 $assets = $targetRelease | Select -ExpandProperty assets -First 1

5
.gitignore vendored

@ -60,7 +60,7 @@ _ReSharper*
*.ncrunch* *.ncrunch*
.*crunch*.local.xml .*crunch*.local.xml
# Installshield output folder # Installshield output folder
[Ee]xpress [Ee]xpress
# DocProject is a documentation generator add-in # DocProject is a documentation generator add-in
@ -117,5 +117,4 @@ protobuf/
cryptopp/ cryptopp/
# misc # misc
Thumbs.db Thumbs.db
launchSettings.json

@ -1,76 +0,0 @@
// This file is subject to the terms and conditions defined
// in file 'LICENSE', which is part of this source code package.
using System;
using System.Threading.Tasks;
using SteamKit2.Authentication;
namespace DepotDownloader
{
// This is practically copied from https://github.com/SteamRE/SteamKit/blob/master/SteamKit2/SteamKit2/Steam/Authentication/UserConsoleAuthenticator.cs
internal class ConsoleAuthenticator : IAuthenticator
{
/// <inheritdoc />
public Task<string> GetDeviceCodeAsync(bool previousCodeWasIncorrect)
{
if (previousCodeWasIncorrect)
{
Console.Error.WriteLine("The previous 2-factor auth code you have provided is incorrect.");
}
string code;
do
{
Console.Error.Write("STEAM GUARD! Please enter your 2-factor auth code from your authenticator app: ");
code = Console.ReadLine()?.Trim();
if (code == null)
{
break;
}
}
while (string.IsNullOrEmpty(code));
return Task.FromResult(code!);
}
/// <inheritdoc />
public Task<string> GetEmailCodeAsync(string email, bool previousCodeWasIncorrect)
{
if (previousCodeWasIncorrect)
{
Console.Error.WriteLine("The previous 2-factor auth code you have provided is incorrect.");
}
string code;
do
{
Console.Error.Write($"STEAM GUARD! Please enter the auth code sent to the email at {email}: ");
code = Console.ReadLine()?.Trim();
if (code == null)
{
break;
}
}
while (string.IsNullOrEmpty(code));
return Task.FromResult(code!);
}
/// <inheritdoc />
public Task<bool> AcceptDeviceConfirmationAsync()
{
if (ContentDownloader.Config.SkipAppConfirmation)
{
return Task.FromResult(false);
}
Console.Error.WriteLine("STEAM GUARD! Use the Steam Mobile App to confirm your sign in...");
return Task.FromResult(true);
}
}
}

@ -231,55 +231,59 @@ namespace DepotDownloader
} }
var manifests = depotChild["manifests"]; var manifests = depotChild["manifests"];
var manifests_encrypted = depotChild["encryptedmanifests"];
if (manifests.Children.Count == 0) if (manifests.Children.Count == 0 && manifests_encrypted.Children.Count == 0)
return INVALID_MANIFEST_ID; return INVALID_MANIFEST_ID;
var node = manifests[branch]["gid"]; var node = manifests[branch]["gid"];
// Non passworded branch, found the manifest if (node == KeyValue.Invalid && !string.Equals(branch, DEFAULT_BRANCH, StringComparison.OrdinalIgnoreCase))
if (node.Value != null)
return ulong.Parse(node.Value);
// 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;
// Either the branch just doesn't exist, or it has a password
if (string.IsNullOrEmpty(Config.BetaPassword))
{ {
Console.WriteLine($"Branch {branch} for depot {depotId} was not found, either it does not exist or it has a password."); var node_encrypted = manifests_encrypted[branch];
return INVALID_MANIFEST_ID; 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();
}
if (!steam3.AppBetaPasswords.ContainsKey(branch)) var encrypted_gid = node_encrypted["gid"];
{
// Submit the password to Steam now to get encryption keys
await steam3.CheckAppBetaPassword(appId, Config.BetaPassword);
if (!steam3.AppBetaPasswords.ContainsKey(branch)) if (encrypted_gid != KeyValue.Invalid)
{ {
Console.WriteLine($"Error: Password was invalid for branch {branch} (or the branch does not exist)"); // Submit the password to Steam now to get encryption keys
return INVALID_MANIFEST_ID; await steam3.CheckAppBetaPassword(appId, Config.BetaPassword);
}
}
// Got the password, request private depot section if (!steam3.AppBetaPasswords.TryGetValue(branch, out var appBetaPassword))
// TODO: We're probably repeating this request for every depot? {
var privateDepotSection = await steam3.GetPrivateBetaDepotSection(appId, branch); Console.WriteLine("Password was invalid for branch {0}", branch);
return INVALID_MANIFEST_ID;
}
// Now repeat the same code to get the manifest gid from depot section var input = Util.DecodeHexString(encrypted_gid.Value);
depotChild = privateDepotSection[depotId.ToString()]; 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;
}
if (depotChild == KeyValue.Invalid) return BitConverter.ToUInt64(manifest_bytes, 0);
return INVALID_MANIFEST_ID; }
manifests = depotChild["manifests"]; Console.WriteLine("Unhandled depot encryption for depotId {0}", depotId);
return INVALID_MANIFEST_ID;
}
if (manifests.Children.Count == 0)
return INVALID_MANIFEST_ID; return INVALID_MANIFEST_ID;
}
node = manifests[branch]["gid"];
if (node.Value == null) if (node.Value == null)
return INVALID_MANIFEST_ID; return INVALID_MANIFEST_ID;
@ -425,7 +429,7 @@ namespace DepotDownloader
if (!await AccountHasAccess(appId, appId)) if (!await AccountHasAccess(appId, appId))
{ {
if (steam3.steamUser.SteamID.AccountType != EAccountType.AnonUser && await steam3.RequestFreeAppLicense(appId)) if (await steam3.RequestFreeAppLicense(appId))
{ {
Console.WriteLine("Obtained FreeOnDemand license for app {0}", appId); Console.WriteLine("Obtained FreeOnDemand license for app {0}", appId);
@ -542,8 +546,6 @@ namespace DepotDownloader
} }
} }
Console.WriteLine();
try try
{ {
await DownloadSteam3Async(infos).ConfigureAwait(false); await DownloadSteam3Async(infos).ConfigureAwait(false);

@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<RollForward>LatestMajor</RollForward> <RollForward>LatestMajor</RollForward>
<Version>3.4.0</Version> <Version>3.0.0</Version>
<Description>Steam Downloading Utility</Description> <Description>Steam Downloading Utility</Description>
<Authors>SteamRE Team</Authors> <Authors>SteamRE Team</Authors>
<Copyright>Copyright © SteamRE Team 2025</Copyright> <Copyright>Copyright © SteamRE Team 2025</Copyright>
@ -25,8 +25,8 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="protobuf-net" Version="3.2.52" /> <PackageReference Include="protobuf-net" Version="3.2.46" />
<PackageReference Include="QRCoder" Version="1.6.0" /> <PackageReference Include="QRCoder" Version="1.6.0" />
<PackageReference Include="SteamKit2" Version="3.3.0" /> <PackageReference Include="SteamKit2" Version="3.0.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

@ -31,6 +31,5 @@ namespace DepotDownloader
public uint? LoginID { get; set; } public uint? LoginID { get; set; }
public bool UseQrCode { get; set; } public bool UseQrCode { get; set; }
public bool SkipAppConfirmation { get; set; }
} }
} }

@ -17,8 +17,6 @@ namespace DepotDownloader
{ {
class Program class Program
{ {
private static bool[] consumedArgs;
static async Task<int> Main(string[] args) static async Task<int> Main(string[] args)
{ {
if (args.Length == 0) if (args.Length == 0)
@ -49,8 +47,6 @@ namespace DepotDownloader
return 0; return 0;
} }
consumedArgs = new bool[args.Length];
if (HasParameter(args, "-debug")) if (HasParameter(args, "-debug"))
{ {
PrintVersion(true); PrintVersion(true);
@ -68,20 +64,20 @@ namespace DepotDownloader
var password = GetParameter<string>(args, "-password") ?? GetParameter<string>(args, "-pass"); var password = GetParameter<string>(args, "-password") ?? GetParameter<string>(args, "-pass");
ContentDownloader.Config.RememberPassword = HasParameter(args, "-remember-password"); ContentDownloader.Config.RememberPassword = HasParameter(args, "-remember-password");
ContentDownloader.Config.UseQrCode = HasParameter(args, "-qr"); ContentDownloader.Config.UseQrCode = HasParameter(args, "-qr");
ContentDownloader.Config.SkipAppConfirmation = HasParameter(args, "-no-mobile");
if (username == null) if (username == null)
{ {
if (ContentDownloader.Config.RememberPassword && !ContentDownloader.Config.UseQrCode) if (ContentDownloader.Config.RememberPassword)
{ {
Console.WriteLine("Error: -remember-password can not be used without -username or -qr."); Console.WriteLine("Error: -remember-password can not be used without -username.");
return 1;
}
if (ContentDownloader.Config.UseQrCode)
{
Console.WriteLine("Error: -qr can not be used without -username.");
return 1; return 1;
} }
}
else if (ContentDownloader.Config.UseQrCode)
{
Console.WriteLine("Error: -qr can not be used with -username.");
return 1;
} }
ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only");
@ -172,8 +168,6 @@ namespace DepotDownloader
{ {
#region Pubfile Downloading #region Pubfile Downloading
PrintUnconsumedArgs(args);
if (InitializeSteam(username, password)) if (InitializeSteam(username, password))
{ {
try try
@ -209,8 +203,6 @@ namespace DepotDownloader
{ {
#region UGC Downloading #region UGC Downloading
PrintUnconsumedArgs(args);
if (InitializeSteam(username, password)) if (InitializeSteam(username, password))
{ {
try try
@ -249,12 +241,6 @@ namespace DepotDownloader
var branch = GetParameter<string>(args, "-branch") ?? GetParameter<string>(args, "-beta") ?? ContentDownloader.DEFAULT_BRANCH; var branch = GetParameter<string>(args, "-branch") ?? GetParameter<string>(args, "-beta") ?? ContentDownloader.DEFAULT_BRANCH;
ContentDownloader.Config.BetaPassword = GetParameter<string>(args, "-branchpassword") ?? GetParameter<string>(args, "-betapassword"); ContentDownloader.Config.BetaPassword = GetParameter<string>(args, "-branchpassword") ?? GetParameter<string>(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"); ContentDownloader.Config.DownloadAllPlatforms = HasParameter(args, "-all-platforms");
var os = GetParameter<string>(args, "-os"); var os = GetParameter<string>(args, "-os");
@ -307,8 +293,6 @@ namespace DepotDownloader
depotManifestIds.AddRange(depotIdList.Select(depotId => (depotId, ContentDownloader.INVALID_MANIFEST_ID))); depotManifestIds.AddRange(depotIdList.Select(depotId => (depotId, ContentDownloader.INVALID_MANIFEST_ID)));
} }
PrintUnconsumedArgs(args);
if (InitializeSteam(username, password)) if (InitializeSteam(username, password))
{ {
try try
@ -350,11 +334,6 @@ namespace DepotDownloader
{ {
if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginTokens.ContainsKey(username))) if (username != null && password == null && (!ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginTokens.ContainsKey(username)))
{ {
if (AccountSettingsStore.Instance.LoginTokens.ContainsKey(username))
{
Console.WriteLine($"Account \"{username}\" has stored credentials. Did you forget to specify -remember-password?");
}
do do
{ {
Console.Write("Enter account password for \"{0}\": ", username); Console.Write("Enter account password for \"{0}\": ", username);
@ -400,10 +379,7 @@ namespace DepotDownloader
for (var x = 0; x < args.Length; ++x) for (var x = 0; x < args.Length; ++x)
{ {
if (args[x].Equals(param, StringComparison.OrdinalIgnoreCase)) if (args[x].Equals(param, StringComparison.OrdinalIgnoreCase))
{
consumedArgs[x] = true;
return x; return x;
}
} }
return -1; return -1;
@ -426,7 +402,6 @@ namespace DepotDownloader
var converter = TypeDescriptor.GetConverter(typeof(T)); var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null) if (converter != null)
{ {
consumedArgs[index + 1] = true;
return (T)converter.ConvertFromString(strParam); return (T)converter.ConvertFromString(strParam);
} }
@ -452,7 +427,6 @@ namespace DepotDownloader
var converter = TypeDescriptor.GetConverter(typeof(T)); var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter != null) if (converter != null)
{ {
consumedArgs[index] = true;
list.Add((T)converter.ConvertFromString(strParam)); list.Add((T)converter.ConvertFromString(strParam));
} }
@ -462,26 +436,6 @@ namespace DepotDownloader
return list; return list;
} }
static void PrintUnconsumedArgs(string[] args)
{
var printError = false;
for (var index = 0; index < consumedArgs.Length; index++)
{
if (!consumedArgs[index])
{
printError = true;
Console.Error.WriteLine($"Argument #{index + 1} {args[index]} was not used.");
}
}
if (printError)
{
Console.Error.WriteLine("Make sure you specified the arguments correctly. Check --help for correct arguments.");
Console.Error.WriteLine();
}
}
static void PrintUsage() static void PrintUsage()
{ {
// Do not use tabs to align parameters here because tab size may differ // Do not use tabs to align parameters here because tab size may differ
@ -516,8 +470,6 @@ namespace DepotDownloader
Console.WriteLine(" -password <pass> - the password of the account to login to for restricted content."); Console.WriteLine(" -password <pass> - the password of the account to login to for restricted content.");
Console.WriteLine(" -remember-password - if set, remember the password for subsequent logins of this user."); Console.WriteLine(" -remember-password - if set, remember the password for subsequent logins of this user.");
Console.WriteLine(" use -username <username> -remember-password as login credentials."); Console.WriteLine(" use -username <username> -remember-password as login credentials.");
Console.WriteLine(" -qr - display a login QR code to be scanned with the Steam mobile app");
Console.WriteLine(" -no-mobile - prefer entering a 2FA code instead of prompting to accept in the Steam mobile app");
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(" -dir <installdir> - the directory in which to place downloaded files."); Console.WriteLine(" -dir <installdir> - the directory in which to place downloaded files.");
Console.WriteLine(" -filelist <file.txt> - the name of a local file that contains a list of files to download (from the manifest)."); Console.WriteLine(" -filelist <file.txt> - the name of a local file that contains a list of files to download (from the manifest).");

@ -64,7 +64,7 @@ namespace DepotDownloader
var clientConfiguration = SteamConfiguration.Create(config => var clientConfiguration = SteamConfiguration.Create(config =>
config config
.WithHttpClientFactory(static purpose => HttpClientFactory.CreateHttpClient()) .WithHttpClientFactory(HttpClientFactory.CreateHttpClient)
); );
this.steamClient = new SteamClient(clientConfiguration); this.steamClient = new SteamClient(clientConfiguration);
@ -265,11 +265,6 @@ namespace DepotDownloader
if (requestCode == 0) if (requestCode == 0)
{ {
Console.WriteLine($"No manifest request code was returned for depot {depotId} from app {appId}, manifest {manifestId}"); Console.WriteLine($"No manifest request code was returned for depot {depotId} from app {appId}, manifest {manifestId}");
if (!authenticatedUser)
{
Console.WriteLine("Suggestion: Try logging in with -username as old manifests may not be available for anonymous accounts.");
}
} }
else else
{ {
@ -315,22 +310,6 @@ namespace DepotDownloader
} }
} }
public async Task<KeyValue> 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<PublishedFileDetails> GetPublishedFileDetails(uint appId, PublishedFileID pubFile) public async Task<PublishedFileDetails> GetPublishedFileDetails(uint appId, PublishedFileID pubFile)
{ {
var pubFileRequest = new CPublishedFile_GetDetails_Request { appid = appId }; var pubFileRequest = new CPublishedFile_GetDetails_Request { appid = appId };
@ -442,14 +421,13 @@ namespace DepotDownloader
try try
{ {
_ = AccountSettingsStore.Instance.GuardData.TryGetValue(logonDetails.Username, out var guarddata); _ = AccountSettingsStore.Instance.GuardData.TryGetValue(logonDetails.Username, out var guarddata);
authSession = await steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new AuthSessionDetails authSession = await steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new SteamKit2.Authentication.AuthSessionDetails
{ {
DeviceFriendlyName = nameof(DepotDownloader),
Username = logonDetails.Username, Username = logonDetails.Username,
Password = logonDetails.Password, Password = logonDetails.Password,
IsPersistentSession = ContentDownloader.Config.RememberPassword, IsPersistentSession = ContentDownloader.Config.RememberPassword,
GuardData = guarddata, GuardData = guarddata,
Authenticator = new ConsoleAuthenticator(), Authenticator = new UserConsoleAuthenticator(),
}); });
} }
catch (TaskCanceledException) catch (TaskCanceledException)
@ -471,8 +449,8 @@ namespace DepotDownloader
{ {
var session = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails var session = await steamClient.Authentication.BeginAuthSessionViaQRAsync(new AuthSessionDetails
{ {
DeviceFriendlyName = nameof(DepotDownloader),
IsPersistentSession = ContentDownloader.Config.RememberPassword, IsPersistentSession = ContentDownloader.Config.RememberPassword,
Authenticator = new UserConsoleAuthenticator(),
}); });
authSession = session; authSession = session;
@ -515,17 +493,11 @@ namespace DepotDownloader
if (result.NewGuardData != null) if (result.NewGuardData != null)
{ {
AccountSettingsStore.Instance.GuardData[result.AccountName] = result.NewGuardData; AccountSettingsStore.Instance.GuardData[result.AccountName] = result.NewGuardData;
if (ContentDownloader.Config.UseQrCode)
{
Console.WriteLine($"Success! Next time you can login with -username {result.AccountName} -remember-password instead of -qr.");
}
} }
else else
{ {
AccountSettingsStore.Instance.GuardData.Remove(result.AccountName); AccountSettingsStore.Instance.GuardData.Remove(result.AccountName);
} }
AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken; AccountSettingsStore.Instance.LoginTokens[result.AccountName] = result.RefreshToken;
AccountSettingsStore.Save(); AccountSettingsStore.Save();
} }
@ -706,14 +678,10 @@ namespace DepotDownloader
using var qrGenerator = new QRCodeGenerator(); using var qrGenerator = new QRCodeGenerator();
var qrCodeData = qrGenerator.CreateQrCode(challengeUrl, QRCodeGenerator.ECCLevel.L); var qrCodeData = qrGenerator.CreateQrCode(challengeUrl, QRCodeGenerator.ECCLevel.L);
using var qrCode = new AsciiQRCode(qrCodeData); using var qrCode = new AsciiQRCode(qrCodeData);
var qrCodeAsAsciiArt = qrCode.GetLineByLineGraphic(1, drawQuietZones: true); var qrCodeAsAsciiArt = qrCode.GetGraphic(1, drawQuietZones: false);
Console.WriteLine("Use the Steam Mobile App to sign in with this QR code:"); Console.WriteLine("Use the Steam Mobile App to sign in with this QR code:");
Console.WriteLine(qrCodeAsAsciiArt);
foreach (var line in qrCodeAsAsciiArt)
{
Console.WriteLine(line);
}
} }
} }
} }

@ -61,52 +61,33 @@ For example: `./DepotDownloader -app 730 -ugc 770604181014286929`
## Parameters ## Parameters
#### Authentication
Parameter | Description
----------------------- | -----------
`-username <user>` | the username of the account to login to for restricted content.
`-password <pass>` | the password of the account to login to for restricted content.
`-remember-password` | if set, remember the password for subsequent logins of this user. (Use `-username <username> -remember-password` as login credentials)
`-qr` | display a login QR code to be scanned with the Steam mobile app
`-no-mobile` | prefer entering a 2FA code instead of prompting to accept in the Steam mobile app.
`-loginid <#>` | a unique 32-bit integer Steam LogonID in decimal, required if running multiple instances of DepotDownloader concurrently.
#### Downloading
Parameter | Description
------------------------ | -----------
`-app <#>` | the AppID to download.
`-depot <#>` | the DepotID to download.
`-manifest <id>` | manifest id of content to download (requires `-depot`, default: current for branch).
`-ugc <#>` | the UGC ID to download.
`-pubfile <#>` | the PublishedFileId to download. (Will automatically resolve to UGC id)
`-branch <branchname>` | download from specified branch if available (default: Public).
`-branchpassword <pass>` | branch password if applicable.
#### Download configuration
Parameter | Description Parameter | Description
----------------------- | ----------- ----------------------- | -----------
`-all-platforms` | downloads all platform-specific depots when `-app` is used. `-app <#>` | the AppID to download.
`-os <os>` | the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on) `-depot <#>` | the DepotID to download.
`-osarch <arch>` | the architecture for which to download the game (32 or 64, default: the host's architecture) `-manifest <id>` | manifest id of content to download (requires `-depot`, default: current for branch).
`-all-archs` | download all architecture-specific depots when `-app` is used. `-ugc <#>` | the UGC ID to download.
`-all-languages` | download all language-specific depots when `-app` is used. `-branch <branchname>` | download from specified branch if available (default: Public).
`-language <lang>` | the language for which to download the game (default: english) `-branchpassword <pass>` | branch password if applicable.
`-lowviolence` | download low violence depots when `-app` is used. `-all-platforms` | downloads all platform-specific depots when `-app` is used.
`-os <os>` | the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)
`-osarch <arch>` | the architecture for which to download the game (32 or 64, default: the host's architecture)
`-all-archs` | download all architecture-specific depots when `-app` is used.
`-all-languages` | download all language-specific depots when `-app` is used.
`-language <lang>` | the language for which to download the game (default: english)
`-lowviolence` | download low violence depots when `-app` is used.
`-pubfile <#>` | the PublishedFileId to download. (Will automatically resolve to UGC id)
`-username <user>` | the username of the account to login to for restricted content.
`-password <pass>` | the password of the account to login to for restricted content.
`-remember-password` | if set, remember the password for subsequent logins of this user. (Use `-username <username> -remember-password` as login credentials)
`-dir <installdir>` | the directory in which to place downloaded files. `-dir <installdir>` | the directory in which to place downloaded files.
`-filelist <file.txt>` | the name of a local file that contains a list of files to download (from the manifest). prefix file path with `regex:` if you want to match with regex. each file path should be on their own line. `-filelist <file.txt>` | the name of a local file that contains a list of files to download (from the manifest). prefix file path with `regex:` if you want to match with regex. each file path should be on their own line.
`-validate` | include checksum verification of files already downloaded. `-validate` | include checksum verification of files already downloaded.
`-manifest-only` | downloads a human readable manifest for any depots that would be downloaded. `-manifest-only` | downloads a human readable manifest for any depots that would be downloaded.
`-cellid <#>` | the overridden CellID of the content server to download from. `-cellid <#>` | the overridden CellID of the content server to download from.
`-max-downloads <#>` | maximum number of chunks to download concurrently. (default: 8). `-max-downloads <#>` | maximum number of chunks to download concurrently. (default: 8).
`-loginid <#>` | a unique 32-bit integer Steam LogonID in decimal, required if running multiple instances of DepotDownloader concurrently
`-use-lancache` | forces downloads over the local network via a Lancache instance. `-use-lancache` | forces downloads over the local network via a Lancache instance.
#### Other
Parameter | Description
----------------------- | -----------
`-debug` | enable verbose debug logging. `-debug` | enable verbose debug logging.
`-V` or `--version` | print version and runtime. `-V` or `--version` | print version and runtime.

Loading…
Cancel
Save