Add -pubfile support, dynamically getting appId + ugcId.

pull/45/head
Nicholas Hastings 7 years ago
parent 18a57dd1dd
commit f957ef5da9

@ -16,6 +16,7 @@ namespace DepotDownloader
public const uint INVALID_APP_ID = uint.MaxValue; public const uint INVALID_APP_ID = uint.MaxValue;
public const uint INVALID_DEPOT_ID = uint.MaxValue; public const uint INVALID_DEPOT_ID = uint.MaxValue;
public const ulong INVALID_MANIFEST_ID = ulong.MaxValue; public const ulong INVALID_MANIFEST_ID = ulong.MaxValue;
public const string DEFAULT_BRANCH = "Public";
public static DownloadConfig Config = new DownloadConfig(); public static DownloadConfig Config = new DownloadConfig();
@ -373,6 +374,12 @@ namespace DepotDownloader
steam3.Disconnect(); 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 ) public static async Task DownloadAppAsync( uint appId, uint depotId, ulong manifestId, string branch, string os, bool isUgc )
{ {
if ( steam3 != null ) if ( steam3 != null )
@ -392,12 +399,9 @@ namespace DepotDownloader
} }
} }
Console.WriteLine( "Using app branch: '{0}'.", branch );
var depotIDs = new List<uint>(); var depotIDs = new List<uint>();
KeyValue depots = GetSteam3AppSection( appId, EAppInfoSection.Depots ); KeyValue depots = GetSteam3AppSection( appId, EAppInfoSection.Depots );
if ( isUgc ) if ( isUgc )
{ {
var workshopDepot = depots["workshopdepot"].AsUnsignedInteger(); var workshopDepot = depots["workshopdepot"].AsUnsignedInteger();
@ -408,6 +412,8 @@ namespace DepotDownloader
} }
else else
{ {
Console.WriteLine( "Using app branch: '{0}'.", branch );
if ( depots != null ) if ( depots != null )
{ {
foreach ( var depotSection in depots.Children ) foreach ( var depotSection in depots.Children )

@ -25,34 +25,13 @@ namespace DepotDownloader
ConfigStore.LoadFromFile( Path.Combine( Directory.GetCurrentDirectory(), "DepotDownloader.config" ) ); ConfigStore.LoadFromFile( Path.Combine( Directory.GetCurrentDirectory(), "DepotDownloader.config" ) );
uint appId = GetParameter<uint>( args, "-app", ContentDownloader.INVALID_APP_ID ); #region Common Options
if (appId == ContentDownloader.INVALID_APP_ID)
{
Console.WriteLine("Error: -app not specified!");
return;
}
uint depotId; string username = GetParameter<string>( args, "-username" ) ?? GetParameter<string>( args, "-user" );
bool isUGC = false; string password = GetParameter<string>( args, "-password" ) ?? GetParameter<string>( args, "-pass" );
ContentDownloader.Config.RememberPassword = HasParameter( args, "-remember-password" );
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;
}
}
ContentDownloader.Config.DownloadManifestOnly = HasParameter(args, "-manifest-only"); ContentDownloader.Config.DownloadManifestOnly = HasParameter( args, "-manifest-only" );
int cellId = GetParameter<int>( args, "-cellid", -1 ); int cellId = GetParameter<int>( args, "-cellid", -1 );
if ( cellId == -1 ) if ( cellId == -1 )
@ -61,7 +40,6 @@ namespace DepotDownloader
} }
ContentDownloader.Config.CellID = cellId; ContentDownloader.Config.CellID = cellId;
ContentDownloader.Config.BetaPassword = GetParameter<string>( args, "-betapassword" );
string fileList = GetParameter<string>( args, "-filelist" ); string fileList = GetParameter<string>( args, "-filelist" );
string[] files = null; string[] files = null;
@ -70,7 +48,7 @@ namespace DepotDownloader
{ {
try try
{ {
string fileListData = File.ReadAllText( fileList ); string fileListData = File.ReadAllText(fileList);
files = fileListData.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries ); files = fileListData.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries );
ContentDownloader.Config.UsingFileList = true; ContentDownloader.Config.UsingFileList = true;
@ -93,36 +71,94 @@ namespace DepotDownloader
Console.WriteLine( "Using filelist: '{0}'.", fileList ); Console.WriteLine( "Using filelist: '{0}'.", fileList );
} }
catch ( Exception ex ) catch (Exception ex)
{ {
Console.WriteLine( "Warning: Unable to load filelist: {0}", ex.ToString() ); Console.WriteLine( "Warning: Unable to load filelist: {0}", ex.ToString() );
} }
} }
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.InstallDirectory = GetParameter<string>( args, "-dir" ); ContentDownloader.Config.InstallDirectory = GetParameter<string>( 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.VerifyAll = HasParameter( args, "-verify-all" ) || HasParameter( args, "-verify_all" ) || HasParameter( args, "-validate" );
ContentDownloader.Config.MaxServers = GetParameter<int>( args, "-max-servers", 20 ); ContentDownloader.Config.MaxServers = GetParameter<int>( args, "-max-servers", 20 );
ContentDownloader.Config.MaxDownloads = GetParameter<int>( args, "-max-downloads", 4 ); ContentDownloader.Config.MaxDownloads = GetParameter<int>( args, "-max-downloads", 4 );
string branch = GetParameter<string>( args, "-branch" ) ?? GetParameter<string>( args, "-beta" ) ?? "Public"; ContentDownloader.Config.MaxServers = Math.Max( ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads );
string os = GetParameter<string>( args, "-os", null );
if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) ) #endregion
ulong pubFile = GetParameter<ulong>( args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID );
if ( pubFile != ContentDownloader.INVALID_MANIFEST_ID )
{ {
Console.WriteLine( "Error: Cannot specify -os when -all-platforms is specified." ); #region Pubfile Downloading
return;
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<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;
}
uint appId = GetParameter<uint>( 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<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;
}
}
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 ) ) ) if ( username != null && password == null && ( !ContentDownloader.Config.RememberPassword || !ConfigStore.TheConfig.LoginKeys.ContainsKey( username ) ) )
{ {
do do
{ {
Console.Write("Enter account password for \"{0}\": ", username); Console.Write( "Enter account password for \"{0}\": ", username );
password = Util.ReadPassword(); password = Util.ReadPassword();
Console.WriteLine(); Console.WriteLine();
} while ( String.Empty == password ); } 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 // capture the supplied password in case we need to re-use it after checking the login key
ContentDownloader.Config.SuppliedPassword = password; ContentDownloader.Config.SuppliedPassword = password;
if ( ContentDownloader.InitializeSteam3( username, password ) ) return ContentDownloader.InitializeSteam3( username, password );
{
await ContentDownloader.DownloadAppAsync( appId, depotId, manifestId, branch, os, isUGC ).ConfigureAwait( false );
ContentDownloader.ShutdownSteam3();
}
} }
static int IndexOfParam( string[] args, string param ) static int IndexOfParam( string[] args, string param )
@ -177,28 +209,30 @@ namespace DepotDownloader
static void PrintUsage() static void PrintUsage()
{ {
Console.WriteLine(); Console.WriteLine();
Console.WriteLine( "Usage: depotdownloader -app <id> [-depot <id> [-manifest <id>] | -ugc <id>]" ); Console.WriteLine( "Usage - downloading one or all depots for an app:" );
Console.WriteLine( "\tdepotdownloader -app <id> [-depot <id> [-manifest <id>] | [-ugc <id>]]" );
Console.WriteLine( "\t\t[-username <username> [-password <password>]] [other options]" ); Console.WriteLine( "\t\t[-username <username> [-password <password>]] [other options]" );
Console.WriteLine(); Console.WriteLine();
Console.WriteLine( "Usage - downloading a Workshop item published via SteamUGC" );
Console.WriteLine( "\tdepotdownloader -pubfile <id> [-username <username> [-password <password>]]" );
Console.WriteLine();
Console.WriteLine( "Parameters:" ); Console.WriteLine( "Parameters:" );
Console.WriteLine( "\t-app <#>\t\t\t\t- the AppID to download." ); 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-depot <#>\t\t\t\t- the DepotID to download." );
Console.WriteLine( "\t-manifest <id>\t\t\t- manifest id of content to download (requires -depot, default: current for branch)." ); Console.WriteLine( "\t-manifest <id>\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-ugc <#>\t\t\t\t- the UGC ID to download." );
Console.WriteLine( "\t-beta <branchname>\t\t\t- download from specified branch if available (default: Public)." );
Console.WriteLine( "\t-betapassword <pass>\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 <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();
Console.WriteLine( "\t-username <user>\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 <user>\t\t- the username of the account to login to for restricted content.");
Console.WriteLine( "\t-password <pass>\t\t- the password of the account to login to for restricted content." ); Console.WriteLine( "\t-password <pass>\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( "\t-remember-password\t\t- if set, remember the password for subsequent logins of this user." );
Console.WriteLine(); Console.WriteLine();
Console.WriteLine( "\t-beta <branchname>\t\t\t- download from specified branch if available (default: Public)." );
Console.WriteLine( "\t-betapassword <pass>\t\t- branch password if applicable." );
Console.WriteLine();
Console.WriteLine( "\t-dir <installdir>\t\t- the directory in which to place downloaded files." ); Console.WriteLine( "\t-dir <installdir>\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 <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 <file.txt>\t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." ); Console.WriteLine( "\t-filelist <file.txt>\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( "\t-validate\t\t\t\t- Include checksum verification of files already downloaded" );
Console.WriteLine(); Console.WriteLine();

@ -1,4 +1,5 @@
using SteamKit2; using SteamKit2;
using SteamKit2.Unified.Internal;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -40,6 +41,7 @@ namespace DepotDownloader
public SteamClient steamClient; public SteamClient steamClient;
public SteamUser steamUser; public SteamUser steamUser;
SteamApps steamApps; SteamApps steamApps;
SteamUnifiedMessages.UnifiedService<IPublishedFile> steamPublishedFile;
CallbackManager callbacks; CallbackManager callbacks;
@ -85,6 +87,8 @@ namespace DepotDownloader
this.steamUser = this.steamClient.GetHandler<SteamUser>(); this.steamUser = this.steamClient.GetHandler<SteamUser>();
this.steamApps = this.steamClient.GetHandler<SteamApps>(); 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 = new CallbackManager( this.steamClient );
@ -202,6 +206,36 @@ namespace DepotDownloader
}, () => { return completed; } ); }, () => { return completed; } );
} }
public PublishedFileDetails GetPubfileDetails( PublishedFileID pubFile )
{
var pubFileRequest = new CPublishedFile_GetDetails_Request();
pubFileRequest.publishedfileids.Add( pubFile );
bool completed = false;
PublishedFileDetails details = null;
Action<SteamUnifiedMessages.ServiceMethodResponse> cbMethod = callback =>
{
completed = true;
if ( callback.Result == EResult.OK )
{
var response = callback.GetDeserializedResponse<CPublishedFile_GetDetails_Response>();
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<uint> packageIds ) public void RequestPackageInfo( IEnumerable<uint> packageIds )
{ {
List<uint> packages = packageIds.ToList(); List<uint> packages = packageIds.ToList();

Loading…
Cancel
Save