|
|
|
@ -8,6 +8,7 @@ using System.Text;
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading;
|
|
|
|
using SteamKit2;
|
|
|
|
using SteamKit2;
|
|
|
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DepotDownloader
|
|
|
|
namespace DepotDownloader
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -435,10 +436,10 @@ namespace DepotDownloader
|
|
|
|
public ProtoManifest.ChunkData NewChunk { get; private set; }
|
|
|
|
public ProtoManifest.ChunkData NewChunk { get; private set; }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static List<CDNClient> CollectCDNClientsForDepot(DepotDownloadInfo depot)
|
|
|
|
private static ConcurrentQueue<CDNClient> CollectCDNClientsForDepot(DepotDownloadInfo depot)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
var cdnClients = new List<CDNClient>();
|
|
|
|
var cdnClients = new ConcurrentQueue<CDNClient>();
|
|
|
|
CDNClient initialClient = new CDNClient(steam3.steamClient, depot.id, steam3.AppTickets[depot.id], depot.depotKey);
|
|
|
|
CDNClient initialClient = new CDNClient(steam3.steamClient, steam3.AppTickets[depot.id]);
|
|
|
|
var cdnServers = initialClient.FetchServerList(cellId: (uint)Config.CellID);
|
|
|
|
var cdnServers = initialClient.FetchServerList(cellId: (uint)Config.CellID);
|
|
|
|
|
|
|
|
|
|
|
|
// Grab up to the first eight server in the allegedly best-to-worst order from Steam
|
|
|
|
// Grab up to the first eight server in the allegedly best-to-worst order from Steam
|
|
|
|
@ -454,19 +455,27 @@ namespace DepotDownloader
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
c = new CDNClient( steam3.steamClient, depot.id, steam3.AppTickets[depot.id], depot.depotKey );
|
|
|
|
c = new CDNClient( steam3.steamClient, steam3.AppTickets[depot.id] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
c.Connect( s );
|
|
|
|
c.Connect( s );
|
|
|
|
cdnClients.Add( c );
|
|
|
|
|
|
|
|
|
|
|
|
string cdnAuthToken = null;
|
|
|
|
|
|
|
|
if ( s.Type == "CDN" )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
steam3.RequestCDNAuthToken(depot.id, s.Host);
|
|
|
|
|
|
|
|
cdnAuthToken = steam3.CDNAuthTokens[Tuple.Create(depot.id, s.Host)].Token;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c.AuthenticateDepot( depot.id, depot.depotKey, cdnAuthToken );
|
|
|
|
|
|
|
|
cdnClients.Enqueue( c );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Console.WriteLine( "\nFailed to connect to content server {0}. Remaining content servers for depot: {1}.", s, Config.MaxServers - tries - 1 );
|
|
|
|
Console.WriteLine( "\nFailed to connect to content server {0}. Remaining content servers for depot: {1}.", s, Config.MaxServers - tries - 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tries++;
|
|
|
|
tries++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@ -491,7 +500,8 @@ namespace DepotDownloader
|
|
|
|
Console.WriteLine("Downloading depot {0} - {1}", depot.id, depot.contentName);
|
|
|
|
Console.WriteLine("Downloading depot {0} - {1}", depot.id, depot.contentName);
|
|
|
|
Console.Write("Finding content servers...");
|
|
|
|
Console.Write("Finding content servers...");
|
|
|
|
|
|
|
|
|
|
|
|
List<CDNClient> cdnClients = null;
|
|
|
|
var cdnClientsLock = new Object();
|
|
|
|
|
|
|
|
ConcurrentQueue<CDNClient> cdnClients = null;
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine(" Done!");
|
|
|
|
Console.WriteLine(" Done!");
|
|
|
|
|
|
|
|
|
|
|
|
@ -542,7 +552,7 @@ namespace DepotDownloader
|
|
|
|
{
|
|
|
|
{
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
depotManifest = c.DownloadManifest(depot.manifestId);
|
|
|
|
depotManifest = c.DownloadManifest(depot.id, depot.manifestId);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (WebException) { }
|
|
|
|
catch (WebException) { }
|
|
|
|
@ -713,12 +723,16 @@ namespace DepotDownloader
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int cdnClientIndex = 0;
|
|
|
|
|
|
|
|
if (neededChunks.Count > 0 && cdnClients == null)
|
|
|
|
if (neededChunks.Count > 0 && cdnClients == null)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// If we didn't need to connect to get manifests, connect now.
|
|
|
|
// If we didn't need to connect to get manifests, connect now.
|
|
|
|
cdnClients = CollectCDNClientsForDepot(depot);
|
|
|
|
lock (cdnClientsLock)
|
|
|
|
cdnClientIndex = rand.Next(0, cdnClients.Count);
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cdnClients == null)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
cdnClients = CollectCDNClientsForDepot(depot);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var chunk in neededChunks)
|
|
|
|
foreach (var chunk in neededChunks)
|
|
|
|
@ -726,8 +740,9 @@ namespace DepotDownloader
|
|
|
|
string chunkID = Util.EncodeHexString(chunk.ChunkID);
|
|
|
|
string chunkID = Util.EncodeHexString(chunk.ChunkID);
|
|
|
|
|
|
|
|
|
|
|
|
CDNClient.DepotChunk chunkData = null;
|
|
|
|
CDNClient.DepotChunk chunkData = null;
|
|
|
|
int idx = cdnClientIndex;
|
|
|
|
CDNClient client = null;
|
|
|
|
while (true)
|
|
|
|
|
|
|
|
|
|
|
|
while (cdnClients.TryDequeue(out client))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DepotManifest.ChunkData data = new DepotManifest.ChunkData();
|
|
|
|
DepotManifest.ChunkData data = new DepotManifest.ChunkData();
|
|
|
|
data.ChunkID = chunk.ChunkID;
|
|
|
|
data.ChunkID = chunk.ChunkID;
|
|
|
|
@ -738,16 +753,13 @@ namespace DepotDownloader
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
chunkData = cdnClients[idx].DownloadDepotChunk(data);
|
|
|
|
chunkData = client.DownloadDepotChunk(depot.id, data);
|
|
|
|
|
|
|
|
cdnClients.Enqueue(client);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (++idx >= cdnClients.Count)
|
|
|
|
Console.WriteLine("Encountered error downloading chunk {0}", chunkID);
|
|
|
|
idx = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (idx == cdnClientIndex)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|