public async Task <CdnClient> GetClientAsync(AppId appId, DepotId depotId, CancellationToken cancellationToken = default)
        {
            await _getClientSemaphore.WaitAsync(cancellationToken);

            if (_cdnClientWrappersAvailable.Count == 0)
            {
                await FillServerPoolAsync();
            }

            await _poolFilledEvent.WaitAsync(cancellationToken);

            CdnClient recommendedClient = null;

            lock (this)
            {
                recommendedClient = _cdnClientWrappersAvailable
                                    .OrderByDescending(x => x.ServerWrapper.Score)
                                    .ThenBy(x => x.ServerWrapper.Server.WeightedLoad)
                                    .ThenBy(x => x.ServerWrapper.Server.Load)
                                    .Take(10)
                                    .OrderBy(x => _random.Next())
                                    .First();

                _cdnClientWrappersAvailable.Remove(recommendedClient);
            }

            if (recommendedClient.RequiresAuthentication(appId, depotId))
            {
                await AuthenticateClientInfoAsync(recommendedClient, appId, depotId);
            }

            _getClientSemaphore.Release();

            return(recommendedClient);
        }
Example #2
0
        public static Tuple <HttpStatusCode, Depot> GetRecordedEsm()
        {
            var request = new RestRequest(_getRecordedEsm, Method.GET);

            request.AddUrlSegment("id", DepotId.ToString());
            return(GetResponse <Depot>(request));
        }
 public CdnClientAuthToken(string authToken, DateTime expires, AppId appId, DepotId depotId)
 {
     Token   = authToken;
     Expires = expires;
     AppId   = appId;
     DepotId = depotId;
 }
        public async Task <byte[]> GetDepotKeyAsync(DepotId depotId, AppId appId)
        {
            if (_depotKeys.ContainsKey(depotId))
            {
                return(_depotKeys[depotId]);
            }

            var result = await _steamApps.GetDepotDecryptionKey(depotId, appId);

            if (result.Result != EResult.OK)
            {
                if (result.Result == EResult.AccessDenied)
                {
                    throw new SteamDepotAccessDeniedException(depotId);
                }

                throw new SteamDepotKeyNotRetrievableException(depotId, result.Result);
            }

            while (!_depotKeys.TryAdd(depotId, result.DepotKey))
            {
            }

            return(result.DepotKey);
        }
 public DepotEncryptedManifest(AppId appId, DepotId depotId, string branchName, string encryptedManifestId, EncryptionVersion version)
 {
     BranchName          = branchName;
     EncryptedManifestId = encryptedManifestId;
     Version             = version;
     AppId   = appId;
     DepotId = depotId;
 }
 public Manifest(List <ManifestFile> files, DepotId depotId, ManifestId manifestId, DateTime creationTime, ulong totalUncompressedSize, ulong totalCompressedSize)
 {
     Files                 = files;
     DepotId               = depotId;
     ManifestId            = manifestId;
     CreationTime          = creationTime;
     TotalUncompressedSize = totalUncompressedSize;
     TotalCompressedSize   = totalCompressedSize;
 }
        public MultipleFilesHandler(SteamContentClient steamContentClient, Manifest manifest, AppId appId, DepotId depotId, ManifestId manifestId)
        {
            _steamContentClient = steamContentClient;

            Manifest   = manifest;
            AppId      = appId;
            DepotId    = depotId;
            ManifestId = manifestId;
        }
            public bool RequiresAuthentication(AppId appId, DepotId depotId)
            {
                var authToken = GetAuthTokenOrDefault(appId, depotId);

                if (authToken == null)
                {
                    return(true);
                }

                return(authToken.Expires - DateTime.UtcNow < TimeSpan.FromMinutes(5));
            }
        private async Task <string> GetCdnAuthenticationTokenAsync(AppId appId, DepotId depotId, string host, string cdnKey)
        {
            if (_steamContentClient.CdnAuthenticationTokens.TryGetValue(cdnKey, out var response))
            {
                return(response.Token);
            }

            var authResponse = await _steamContentClient.SteamApps.GetCDNAuthToken(appId, depotId, host);

            _steamContentClient.CdnAuthenticationTokens.AddOrUpdate(cdnKey, authResponse, (key, existingValue) => authResponse);

            return(authResponse.Token);
        }
        public async Task <string> AuthenticateWithServerAsync(DepotId depotId, CDNClient.Server server)
        {
            string host = server.Host;

            if (host.EndsWith(".steampipe.steamcontent.com"))
            {
                host = "steampipe.steamcontent.com";
            }
            else if (host.EndsWith(".steamcontent.com"))
            {
                host = "steamcontent.com";
            }

            string cdnKey = $"{depotId.Id:D}:{host}";

            return(await GetCdnAuthenticationTokenAsync(_appId, depotId, host, cdnKey));
        }
Example #11
0
        public async Task <Manifest> GetManifestAsync(AppId appId, DepotId depotId, ManifestId manifestId, CancellationToken cancellationToken = default)
        {
            await SteamClient.AwaitReadyAsync(cancellationToken);

            Exception lastEx = null;

            for (int i = 0; i < 30; i++)
            {
                SteamCdnClient steamCdnClient;

                try
                {
                    steamCdnClient = await SteamCdnServerPool.GetClientAsync();

                    //await cdnClientWrapper.CdnClient.AuthenticateDepotAsync(depotId);

                    var manifest = await steamCdnClient.DownloadManifestAsync(appId, depotId, manifestId);

                    if (manifest.FilenamesEncrypted)
                    {
                        var depotKey = await steamCdnClient.GetDepotKeyAsync(depotId, appId);

                        manifest.DecryptFilenames(depotKey);
                    }

                    return(manifest);
                }
                catch (SteamDepotAccessDeniedException)
                {
                    throw;
                }
                catch (HttpRequestException ex)
                {
                    lastEx = ex;
                }
                catch (Exception ex)
                {
                    lastEx = ex;
                }
            }

            throw new SteamManifestDownloadException(lastEx);
        }
Example #12
0
 public Depot(
     DepotId id,
     string name,
     ulong maxSize,
     IReadOnlyList <SteamOs> operatingSystems,
     IReadOnlyList <DepotManifest> manifests,
     IReadOnlyList <DepotEncryptedManifest> encryptedManifests,
     IReadOnlyDictionary <string, string> config,
     bool isSharedInstall,
     AppId?parentAppId)
 {
     Id                 = id;
     Name               = name;
     MaxSize            = maxSize;
     OperatingSystems   = operatingSystems;
     Manifests          = manifests;
     EncryptedManifests = encryptedManifests;
     Config             = config;
     IsSharedInstall    = isSharedInstall;
     DepotOfAppId       = parentAppId;
 }
Example #13
0
        public async Task <Manifest> GetManifestAsync(AppId appId, DepotId depotId, ManifestId manifestId, CancellationToken cancellationToken = default)
        {
            await SteamClient.AwaitReadyAsync(cancellationToken);

            var pool = new SteamCdnServerPool(this, appId);

            try
            {
                var server = await pool.GetServerAsync(cancellationToken);

                var depotKey = await GetDepotKeyAsync(depotId, appId);

                var cdnKey = await pool.AuthenticateWithServerAsync(depotId, server);

                var manifest = await pool.CdnClient.DownloadManifestAsync(depotId, manifestId, server, cdnKey, depotKey, proxyServer : null);


                if (manifest.FilenamesEncrypted)
                {
                    manifest.DecryptFilenames(depotKey);
                }

                pool.ReturnServer(server, isFaulty: false);

                return(manifest);
            }
            catch (SteamDepotAccessDeniedException)
            {
                throw;
            }
            catch (HttpRequestException ex)
            {
                throw new SteamManifestDownloadException(ex);
            }
            catch (Exception ex)
            {
                throw new SteamManifestDownloadException(ex);
            }
        }
Example #14
0
 public SteamBranchNotFoundException(AppId appId, DepotId depotId, string branch) : base($"Branch {branch} could not be found for app id = {appId}, depot id = {depotId}")
 {
 }
Example #15
0
 public SteamOsNotSupportedByAppException(AppId appId, DepotId depotId, ManifestId manifestId, SteamOs targetOs, IEnumerable <string> availableOs)
     : base($"App id = {appId}, depot id = {depotId}, manifest id = {manifestId} only supports OS {string.Join(", ", availableOs)} but not {targetOs}")
 {
 }
 public SteamDepotKeyNotRetrievableException(DepotId depotId, EResult result) : base($"Cannot get decryption key for depot {depotId}: {result}")
 {
 }
Example #17
0
 public SteamDepotAccessDeniedException(DepotId depotId) : base($"Access to depot id = {depotId} denied.")
 {
 }
Example #18
0
 public SteamDepotNotFoundException(DepotId depotId) : base($"Depot {depotId} not found.")
 {
 }
 public SteamInvalidBranchPasswordException(AppId appId, DepotId depotId, string branch, string password, Exception innerException = null) : base($"Invalid password = "******"'{password}' for branch = {branch} of app id = {appId}, depot id = {depotId}{(innerException != null ? ". View the inner exception for more details." : "")}", innerException)
 {
 }
 public CdnClientAuthToken GetAuthTokenOrDefault(AppId appId, DepotId depotId)
 {
     return(AuthTokens.FirstOrDefault(x => x.AppId == appId && x.DepotId == depotId));
 }
        private async Task AuthenticateClientInfoAsync(CdnClient client, AppId appId, DepotId depotId)
        {
            if (client.ServerWrapper.Server.Type == "CDN" || client.ServerWrapper.Server.Type == "SteamCache")
            {
                var authToken = client.GetAuthTokenOrDefault(appId, depotId);

                if (authToken == null)
                {
                    var result = await _steamApps.GetCDNAuthToken(appId, depotId, client.ServerWrapper.Server.Host);

                    authToken = new CdnClientAuthToken(result.Token, result.Expiration, appId, depotId);

                    client.AuthTokens.Add(authToken);
                }

                client.InternalCdnClient.AuthenticateDepot(depotId, await GetDepotKeyAsync(depotId, appId), authToken.Token);
            }
        }