revert DepotDownloader.csproj since i don't need to update SteamKit and another change to CDNClientPool.cs

pull/477/head
minecraftitsover90@gmail.com 2 years ago
parent 16d1e048c4
commit 1e1a8d4413

@ -5,91 +5,46 @@ using System.Linq;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using SteamKit2; using SteamPrefill.Handlers;
using SteamKit2.CDN;
namespace DepotDownloader namespace LancachePrefill.Common
{ {
/// <summary> public class CDNClientPool
/// CDNClientPool provides a pool of connections to CDN endpoints, requesting CDN tokens as needed
/// </summary>
class CDNClientPool
{ {
private const int ServerEndpointMinimumSize = 8; private const int ServerEndpointMinimumSize = 8;
private readonly Steam3Session steamSession; private readonly IAnsiConsole _ansiConsole;
private readonly uint appId; private readonly string _cdnUrl;
public Client CDNClient { get; } private readonly ConcurrentStack<Server> _activeConnectionPool = new ConcurrentStack<Server>();
public Server ProxyServer { get; private set; } private readonly BlockingCollection<Server> _availableServerEndpoints = new BlockingCollection<Server>();
private readonly AutoResetEvent _populatePoolEvent = new AutoResetEvent(true);
private readonly ConcurrentStack<Server> activeConnectionPool = new ConcurrentStack<Server>(); private readonly Task _monitorTask;
private readonly BlockingCollection<Server> availableServerEndpoints = new BlockingCollection<Server>(); private readonly CancellationTokenSource _shutdownToken = new CancellationTokenSource();
private readonly AutoResetEvent populatePoolEvent = new AutoResetEvent(true);
private readonly Task monitorTask;
private readonly CancellationTokenSource shutdownToken = new CancellationTokenSource();
public CancellationTokenSource ExhaustedToken { get; set; } public CancellationTokenSource ExhaustedToken { get; set; }
public CDNClientPool(Steam3Session steamSession, uint appId) public CDNClientPool(IAnsiConsole ansiConsole, string cdnUrl)
{ {
this.steamSession = steamSession; _ansiConsole = ansiConsole;
this.appId = appId; _cdnUrl = cdnUrl;
CDNClient = new Client(steamSession.steamClient);
monitorTask = Task.Factory.StartNew(ConnectionPoolMonitorAsync, TaskCreationOptions.LongRunning); _monitorTask = Task.Factory.StartNew(ConnectionPoolMonitorAsync, TaskCreationOptions.LongRunning);
} }
public void Shutdown() public void Shutdown()
{ {
shutdownToken.Cancel(); _shutdownToken.Cancel();
monitorTask.Wait(); _monitorTask.Wait();
}
private async Task<IReadOnlyCollection<Server>> FetchBootstrapServerListAsync()
{
try
{
var cdnServers = await steamSession.steamContent.GetServersForSteamPipe().ConfigureAwait(false);
return cdnServers;
}
catch (Exception ex)
{
Console.WriteLine("Failed to retrieve content server list: {0}", ex.Message);
return null;
}
}
private async Task<IPAddress> ResolveLancacheIpAsync(string hostname)
{
try
{
var hostEntry = await Dns.GetHostEntryAsync(hostname).ConfigureAwait(false);
return hostEntry.AddressList.FirstOrDefault(ip => IsPrivateIp(ip));
}
catch (Exception ex)
{
Console.WriteLine("Failed to resolve Lancache IP: {0}", ex.Message);
return null;
}
}
private bool IsPrivateIp(IPAddress ip)
{
byte[] bytes = ip.GetAddressBytes();
return bytes[0] == 10 ||
(bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
(bytes[0] == 192 && bytes[1] == 168);
} }
private async Task ConnectionPoolMonitorAsync() private async Task ConnectionPoolMonitorAsync()
{ {
var didPopulate = false; var didPopulate = false;
while (!shutdownToken.IsCancellationRequested) while (!_shutdownToken.IsCancellationRequested)
{ {
populatePoolEvent.WaitOne(TimeSpan.FromSeconds(1)); _populatePoolEvent.WaitOne(TimeSpan.FromSeconds(1));
if (availableServerEndpoints.Count < ServerEndpointMinimumSize && steamSession.steamClient.IsConnected) if (_availableServerEndpoints.Count < ServerEndpointMinimumSize)
{ {
var servers = await FetchBootstrapServerListAsync().ConfigureAwait(false); var servers = await FetchBootstrapServerListAsync().ConfigureAwait(false);
@ -99,45 +54,29 @@ namespace DepotDownloader
return; return;
} }
ProxyServer = servers.FirstOrDefault(x => x.UseAsProxy);
foreach (var server in servers) foreach (var server in servers)
{ {
if (server.Type == "SteamCache") var resolvedIp = await ResolveLancacheIpAsync(server.Host).ConfigureAwait(false);
if (resolvedIp != null && IsPrivateIp(resolvedIp))
{ {
var lancacheIp = await ResolveLancacheIpAsync(server.Host).ConfigureAwait(false); var lancacheServer = new Server
if (lancacheIp != null && IsPrivateIp(lancacheIp))
{ {
var lancacheServer = new Server Host = resolvedIp.ToString(),
{ Type = server.Type,
Host = lancacheIp.ToString(), NumEntries = server.NumEntries,
Type = server.Type, WeightedLoad = server.WeightedLoad,
NumEntries = server.NumEntries, AllowedAppIds = server.AllowedAppIds.ToArray(),
WeightedLoad = server.WeightedLoad, Protocol = Server.ConnectionProtocol.HTTP // Downgrade to HTTP
AllowedAppIds = server.AllowedAppIds.ToArray(), };
Protocol = Server.ConnectionProtocol.HTTP // Downgrade to HTTP
}; _ansiConsole.MarkupLine($"Found Lancache Server: {_cdnUrl}. Downgrading connection to HTTP.");
_availableServerEndpoints.Add(lancacheServer);
Console.WriteLine($"Found Lancache Server: {lancacheServer.Host}. Downgrading connection to HTTP.");
availableServerEndpoints.Add(lancacheServer);
}
}
else
{
var isEligibleForApp = server.AllowedAppIds.Length == 0 || server.AllowedAppIds.Contains(appId);
if (isEligibleForApp && (server.Type == "SteamCache" || server.Type == "CDN"))
{
for (var i = 0; i < server.NumEntries; i++)
{
availableServerEndpoints.Add(server);
}
}
} }
} }
didPopulate = true; didPopulate = true;
} }
else if (availableServerEndpoints.Count == 0 && !steamSession.steamClient.IsConnected && didPopulate) else if (_availableServerEndpoints.Count == 0 && didPopulate)
{ {
ExhaustedToken?.Cancel(); ExhaustedToken?.Cancel();
return; return;
@ -145,39 +84,39 @@ namespace DepotDownloader
} }
} }
private Server BuildConnection(CancellationToken token) private async Task<IReadOnlyCollection<Server>> FetchBootstrapServerListAsync()
{ {
if (availableServerEndpoints.Count < ServerEndpointMinimumSize) // Implement logic to fetch the CDN server list
{ return null;
populatePoolEvent.Set();
}
return availableServerEndpoints.Take(token);
} }
public async Task<DepotChunk> DownloadDepotChunkAsync(uint depotId, DepotManifest.ChunkData chunkData, Server connection, byte[] depotKey) private async Task<IPAddress> ResolveLancacheIpAsync(string hostname)
{ {
try try
{ {
// Call the DownloadDepotChunkAsync method of CDNClient var hostEntry = await Dns.GetHostEntryAsync(hostname).ConfigureAwait(false);
var chunk = await CDNClient.DownloadDepotChunkAsync(depotId, chunkData, connection, depotKey); return hostEntry.AddressList.FirstOrDefault(ip => IsPrivateIp(ip));
// Return the downloaded chunk
return chunk;
} }
catch (Exception ex) catch (Exception ex)
{ {
// Handle any exceptions that occur during chunk download _ansiConsole.MarkupLine($"Failed to resolve Lancache IP: {ex.Message}");
Console.WriteLine($"Error downloading chunk: {ex.Message}");
return null; return null;
} }
} }
private bool IsPrivateIp(IPAddress ip)
{
byte[] bytes = ip.GetAddressBytes();
return bytes[0] == 10 ||
(bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31) ||
(bytes[0] == 192 && bytes[1] == 168);
}
public Server GetConnection(CancellationToken token) public Server GetConnection(CancellationToken token)
{ {
if (!activeConnectionPool.TryPop(out var connection)) if (!_activeConnectionPool.TryPop(out var connection))
{ {
connection = BuildConnection(token); connection = _availableServerEndpoints.Take(token);
} }
return connection; return connection;
@ -187,14 +126,12 @@ namespace DepotDownloader
{ {
if (server == null) return; if (server == null) return;
activeConnectionPool.Push(server); _activeConnectionPool.Push(server);
} }
public void ReturnBrokenConnection(Server server) public void ReturnBrokenConnection(Server server)
{ {
if (server == null) return; // Implement logic to handle broken connections
// Broken connections are not returned to the pool
} }
} }
} }

@ -16,11 +16,6 @@
<PackageReference Include="protobuf-net" Version="3.2.30" /> <PackageReference Include="protobuf-net" Version="3.2.30" />
<PackageReference Include="QRCoder" Version="1.4.3" /> <PackageReference Include="QRCoder" Version="1.4.3" />
<PackageReference Include="System.IO.Hashing" Version="8.0.0" /> <PackageReference Include="System.IO.Hashing" Version="8.0.0" />
</ItemGroup> <PackageReference Include="SteamKit2" Version="2.5.0" />
<ItemGroup>
<Reference Include="SteamKit2">
<HintPath>..\..\SteamKit\SteamKit2\SteamKit2\bin\Debug\net8.0\SteamKit2.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
</Project> </Project>

Loading…
Cancel
Save