@ -787,9 +787,11 @@ namespace DepotDownloader
}
} ) ;
var semaphore = new SemaphoreSlim ( Config . MaxDownloads ) ;
var ioSemaphore = new SemaphoreSlim ( Config . MaxDownloads ) ;
var networkSemaphore = new SemaphoreSlim ( Config . MaxDownloads ) ;
var files = filesAfterExclusions . Where ( f = > ! f . Flags . HasFlag ( EDepotFileFlag . Directory ) ) . ToArray ( ) ;
var tasks = new Task [ files . Length ] ;
var ioT asks = new Task [ files . Length ] ;
for ( var i = 0 ; i < files . Length ; i + + )
{
var file = files [ i ] ;
@ -799,7 +801,7 @@ namespace DepotDownloader
try
{
await s emaphore. WaitAsync ( ) . ConfigureAwait ( false ) ;
await ioS emaphore. WaitAsync ( ) . ConfigureAwait ( false ) ;
cts . Token . ThrowIfCancellationRequested ( ) ;
string fileFinalPath = Path . Combine ( depot . installDir , file . FileName ) ;
@ -910,9 +912,21 @@ namespace DepotDownloader
}
}
foreach ( var chunk in neededChunks )
var fileSemaphore = new SemaphoreSlim ( 1 ) ;
var downloadTasks = new Task < DepotManifest . ChunkData > [ neededChunks . Count ] ;
for ( var x = 0 ; x < neededChunks . Count ; x + + )
{
var chunk = neededChunks [ x ] ;
var downloadTask = Task . Run ( async ( ) = >
{
cts . Token . ThrowIfCancellationRequested ( ) ;
try
{
if ( cts . IsCancellationRequested ) break ;
await networkSemaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
cts . Token . ThrowIfCancellationRequested ( ) ;
string chunkID = Util . EncodeHexString ( chunk . ChunkID ) ;
CDNClient . DepotChunk chunkData = null ;
@ -941,6 +955,7 @@ namespace DepotDownloader
chunkData = await cdnPool . CDNClient . DownloadDepotChunkAsync ( depot . id , data ,
connection . Item1 , connection . Item2 , depot . depotKey ) . ConfigureAwait ( false ) ;
cdnPool . ReturnConnection ( connection ) ;
break ;
}
catch ( SteamKitWebRequestException e )
@ -978,31 +993,55 @@ namespace DepotDownloader
// Throw the cancellation exception if requested so that this task is marked failed
cts . Token . ThrowIfCancellationRequested ( ) ;
TotalBytesCompressed + = chunk . CompressedLength ;
DepotBytesCompressed + = chunk . CompressedLength ;
TotalBytesUncompressed + = chunk . UncompressedLength ;
DepotBytesUncompressed + = chunk . UncompressedLength ;
try
{
await fileSemaphore . WaitAsync ( ) . ConfigureAwait ( false ) ;
fs . Seek ( ( long ) chunk . Offset , SeekOrigin . Begin ) ;
fs . Seek ( ( long ) chunk Data. ChunkInfo . Offset , SeekOrigin . Begin ) ;
fs . Write ( chunkData . Data , 0 , chunkData . Data . Length ) ;
size_downloaded + = chunk . UncompressedLength ;
return chunkData . ChunkInfo ;
}
finally
{
fileSemaphore . Release ( ) ;
}
}
finally
{
networkSemaphore . Release ( ) ;
}
} ) ;
downloadTasks [ x ] = downloadTask ;
}
var completedDownloads = await Task . WhenAll ( downloadTasks ) . ConfigureAwait ( false ) ;
fs . Dispose ( ) ;
foreach ( var chunkInfo in completedDownloads )
{
TotalBytesCompressed + = chunkInfo . CompressedLength ;
DepotBytesCompressed + = chunkInfo . CompressedLength ;
TotalBytesUncompressed + = chunkInfo . UncompressedLength ;
DepotBytesUncompressed + = chunkInfo . UncompressedLength ;
size_downloaded + = chunkInfo . UncompressedLength ;
}
Console . WriteLine ( "{0,6:#00.00}% {1}" , ( ( float ) size_downloaded / ( float ) complete_download_size ) * 100.0f , fileFinalPath ) ;
}
finally
{
semaphore . Release ( ) ;
ioS emaphore. Release ( ) ;
}
} ) ;
tasks [ i ] = task ;
ioT asks[ i ] = task ;
}
await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
await Task . WhenAll ( ioTasks ) . ConfigureAwait ( false ) ;
DepotConfigStore . Instance . InstalledManifestIDs [ depot . id ] = depot . manifestId ;
DepotConfigStore . Save ( ) ;