When downloading using -ugc we need to check UGCDetails first for a file URL (like -pubfile). Resolves #59

pull/151/head
Ryan Kistner 5 years ago
parent 8fcfd837b0
commit a58059eb80

@ -387,34 +387,7 @@ namespace DepotDownloader
if ( !string.IsNullOrEmpty( details?.file_url ) )
{
string installDir;
if ( !CreateDirectories( details.consumer_appid, (uint)details.revision_change_number, out installDir ) )
{
Console.WriteLine( "Error: Unable to create install directories!" );
return;
}
var stagingDir = Path.Combine( installDir, STAGING_DIR );
var fileStagingPath = Path.Combine( stagingDir, details.filename );
var fileFinalPath = Path.Combine( installDir, details.filename );
Directory.CreateDirectory( Path.GetDirectoryName( fileFinalPath ) );
Directory.CreateDirectory( Path.GetDirectoryName( fileStagingPath ) );
using ( var file = File.OpenWrite( fileStagingPath ) )
using ( var client = new HttpClient() )
{
Console.WriteLine( "Downloading {0}", details.filename );
var responseStream = await client.GetStreamAsync( details.file_url );
await responseStream.CopyToAsync( file );
}
if ( File.Exists( fileFinalPath ) )
{
File.Delete( fileFinalPath );
}
File.Move( fileStagingPath, fileFinalPath );
await DownloadWebFile( appId, details.filename, details.file_url );
}
else if ( details?.hcontent_file > 0 )
{
@ -426,6 +399,52 @@ namespace DepotDownloader
}
}
public static async Task DownloadUGCAsync( uint appId, ulong ugcId )
{
var details = steam3.GetUGCDetails( ugcId );
if ( !string.IsNullOrEmpty( details?.URL ) )
{
await DownloadWebFile( appId, details.FileName, details.URL );
}
else
{
await DownloadAppAsync( appId, new List<Tuple<uint, ulong>>() { Tuple.Create( appId, ugcId ) }, DEFAULT_BRANCH, null, null, null, false, true );
}
}
private static async Task DownloadWebFile( uint appId, string fileName, string url )
{
string installDir;
if ( !CreateDirectories( appId, 0, out installDir ) )
{
Console.WriteLine( "Error: Unable to create install directories!" );
return;
}
var stagingDir = Path.Combine( installDir, STAGING_DIR );
var fileStagingPath = Path.Combine( stagingDir, fileName );
var fileFinalPath = Path.Combine( installDir, fileName );
Directory.CreateDirectory( Path.GetDirectoryName( fileFinalPath ) );
Directory.CreateDirectory( Path.GetDirectoryName( fileStagingPath ) );
using ( var file = File.OpenWrite( fileStagingPath ) )
using ( var client = new HttpClient() )
{
Console.WriteLine( "Downloading {0}", fileName );
var responseStream = await client.GetStreamAsync( url );
await responseStream.CopyToAsync( file );
}
if ( File.Exists( fileFinalPath ) )
{
File.Delete( fileFinalPath );
}
File.Move( fileStagingPath, fileFinalPath );
}
public static async Task DownloadAppAsync( uint appId, List<Tuple<uint, ulong>> depotManifestIds, string branch, string os, string arch, string language, bool lv, bool isUgc )
{
cdnPool = new CDNClientPool(steam3, appId);

@ -124,6 +124,7 @@ namespace DepotDownloader
}
ulong pubFile = GetParameter<ulong>( args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID );
ulong ugcId = GetParameter<ulong>( args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID );
if ( pubFile != ContentDownloader.INVALID_MANIFEST_ID )
{
#region Pubfile Downloading
@ -159,6 +160,41 @@ namespace DepotDownloader
#endregion
}
else if ( ugcId != ContentDownloader.INVALID_MANIFEST_ID )
{
#region UGC Downloading
if ( InitializeSteam( username, password ) )
{
try
{
await ContentDownloader.DownloadUGCAsync( appId, ugcId ).ConfigureAwait( false );
}
catch ( Exception ex ) when (
ex is ContentDownloaderException
|| ex is OperationCanceledException )
{
Console.WriteLine( ex.Message );
return 1;
}
catch ( Exception e )
{
Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message );
throw;
}
finally
{
ContentDownloader.ShutdownSteam3();
}
}
else
{
Console.WriteLine( "Error: InitializeSteam failed" );
return 1;
}
#endregion
}
else
{
#region App downloading
@ -188,34 +224,24 @@ namespace DepotDownloader
bool lv = HasParameter( args, "-lowviolence" );
List<uint> depotIdList;
List<Tuple<uint, ulong>> depotManifestIds = new List<Tuple<uint, ulong>>();
bool isUGC = false;
ulong manifestId = GetParameter<ulong>( args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID );
List<uint> depotIdList = GetParameterList<uint>( args, "-depot" );
ulong manifestId = GetParameter<ulong>( args, "-manifest", ContentDownloader.INVALID_MANIFEST_ID );
if ( manifestId != ContentDownloader.INVALID_MANIFEST_ID )
{
depotManifestIds.Add( Tuple.Create( appId, manifestId ) );
isUGC = true;
if ( depotIdList.Count != 1 )
{
Console.WriteLine( "Error: -manifest requires one -depot to be specified" );
return 1;
}
depotManifestIds.Add( Tuple.Create( depotIdList[0], manifestId ) );
}
else
{
depotIdList = GetParameterList<uint>( args, "-depot" );
manifestId = GetParameter<ulong>( args, "-manifest", ContentDownloader.INVALID_MANIFEST_ID );
if ( manifestId != ContentDownloader.INVALID_MANIFEST_ID )
{
if ( depotIdList.Count != 1 )
{
Console.WriteLine( "Error: -manifest requires one -depot to be specified" );
return 1;
}
depotManifestIds.Add( Tuple.Create( depotIdList[0], manifestId ) );
}
else
{
depotManifestIds.AddRange( depotIdList.Select( depotId => Tuple.Create( depotId, ContentDownloader.INVALID_MANIFEST_ID ) ) );
}
depotManifestIds.AddRange( depotIdList.Select( depotId => Tuple.Create( depotId, ContentDownloader.INVALID_MANIFEST_ID ) ) );
}
if ( InitializeSteam( username, password ) )
@ -359,7 +385,6 @@ namespace DepotDownloader
Console.WriteLine( "\t-app <#>\t\t\t\t- the AppID 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-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." );
@ -369,6 +394,7 @@ namespace DepotDownloader
Console.WriteLine( "\t-language <lang>\t\t\t\t- the language for which to download the game (default: english)" );
Console.WriteLine( "\t-lowviolence\t\t\t\t- download low violence depots when -app is used." );
Console.WriteLine();
Console.WriteLine( "\t-ugc <#>\t\t\t\t- the UGC ID to download." );
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.");

@ -43,6 +43,7 @@ namespace DepotDownloader
public SteamClient steamClient;
public SteamUser steamUser;
SteamApps steamApps;
SteamCloud steamCloud;
SteamUnifiedMessages.UnifiedService<IPublishedFile> steamPublishedFile;
CallbackManager callbacks;
@ -94,6 +95,7 @@ namespace DepotDownloader
this.steamUser = this.steamClient.GetHandler<SteamUser>();
this.steamApps = this.steamClient.GetHandler<SteamApps>();
this.steamCloud = this.steamClient.GetHandler<SteamCloud>();
var steamUnifiedMessages = this.steamClient.GetHandler<SteamUnifiedMessages>();
this.steamPublishedFile = steamUnifiedMessages.CreateService<IPublishedFile>();
@ -473,6 +475,37 @@ namespace DepotDownloader
return details;
}
public SteamCloud.UGCDetailsCallback GetUGCDetails(UGCHandle ugcHandle)
{
bool completed = false;
SteamCloud.UGCDetailsCallback details = null;
Action<SteamCloud.UGCDetailsCallback> cbMethod = callback =>
{
completed = true;
if (callback.Result == EResult.OK)
{
details = callback;
}
else if (callback.Result == EResult.FileNotFound)
{
details = null;
}
else
{
throw new Exception($"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC details for {ugcHandle}.");
}
};
WaitUntilCallback(() =>
{
callbacks.Subscribe(steamCloud.RequestUGCDetails(ugcHandle), cbMethod);
}, () => { return completed; });
return details;
}
void Connect()
{
bAborted = false;

Loading…
Cancel
Save