예제 #1
0
        public void RequestDepotKey(uint depotId, uint appid = 0)
        {
            if (DepotKeys.ContainsKey(depotId) || bAborted)
            {
                return;
            }
            bool completed = false;

            Action <SteamApps.DepotKeyCallback> cbMethod = (depotKey) =>
            {
                completed = true;
                Console.WriteLine("Got depot key for {0} result: {1}", depotKey.DepotID, depotKey.Result);


                if (depotKey.Result == EResult.Timeout)
                {
                    completed = true;
                    return;
                }
                else if (depotKey.Result != EResult.OK)
                {
                    Abort();
                    return;
                }

                Program.sw.WriteLine($"{depotKey.DepotID};{string.Concat(depotKey.DepotKey.Select(b => b.ToString("X2")).ToArray())}");
                DepotKeys[depotKey.DepotID] = depotKey.DepotKey;
            };

            WaitUntilCallback(() =>
            {
                callbacks.Subscribe(steamApps.GetDepotDecryptionKey(depotId, appid), cbMethod);
            }, () => { return(completed); });
        }
예제 #2
0
        public void RequestDepotKey(uint depotId, uint appid = 0)
        {
            if (DepotKeys.ContainsKey(depotId) || bAborted)
            {
                return;
            }

            bool completed = false;

            Action <SteamApps.DepotKeyCallback> cbMethod = (depotKey) =>
            {
                completed = true;
                Log.Info("Got depot key for {0} result: {1}", depotKey.DepotID, depotKey.Result);

                if (depotKey.Result != EResult.OK)
                {
                    Abort();
                    return;
                }

                DepotKeys[depotKey.DepotID] = depotKey.DepotKey;
            };

            WaitUntilCallback(() =>
            {
                callbacks.Subscribe(steamApps.GetDepotDecryptionKey(depotId, appid), cbMethod);
            }, () => { return(completed); });
        }
예제 #3
0
        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);
        }
예제 #4
0
        public Task <bool> RequestDepotKey(uint depotId, uint appid = 0)
        {
            var tsc = new TaskCompletionSource <bool>();

            if (DepotKeys.ContainsKey(depotId) || bAborted)
            {
                tsc.SetResult(true);
                return(tsc.Task);
            }
            else
            {
                IDisposable subscription = null;
                Action <SteamApps.DepotKeyCallback> cbMethod = (depotKey) =>
                {
                    subscription.Dispose();
                    DebugLog.WriteLine("Steam3Session", "Got depot key for " + depotKey.DepotID + " result: " + depotKey.Result);

                    if (depotKey.Result != EResult.OK)
                    {
                        Abort();
                        return;
                    }

                    DepotKeys[depotKey.DepotID] = depotKey.DepotKey;
                    tsc.SetResult(true);
                };

                subscription = callbacks.Subscribe(steamApps.GetDepotDecryptionKey(depotId, appid), cbMethod);
                return(tsc.Task);
            }
        }
예제 #5
0
        public async Task <byte[]> RequestDepotKey(uint appId, uint depotId)
        {
            if (!DepotKeys.ContainsKey(depotId))
            {
                DepotKeys[depotId] = (await Apps.GetDepotDecryptionKey(depotId, appId)).DepotKey;
            }

            return(DepotKeys[depotId]);
        }
예제 #6
0
        private async Task <byte[]> GetDepotDecryptionKey(SteamApps instance, uint depotID, uint appID)
        {
            using (var db = Database.Get())
            {
                var currentDecryptionKey = await db.ExecuteScalarAsync <string>("SELECT `Key` FROM `DepotsKeys` WHERE `DepotID` = @DepotID", new { depotID });

                if (currentDecryptionKey != null)
                {
                    return(Utils.StringToByteArray(currentDecryptionKey));
                }
            }

            var task = instance.GetDepotDecryptionKey(depotID, appID);

            task.Timeout = TimeSpan.FromMinutes(15);

            SteamApps.DepotKeyCallback callback;

            try
            {
                callback = await task;
            }
            catch (TaskCanceledException)
            {
                Log.WriteError("Depot Processor", "Decryption key timed out for {0}", depotID);

                return(null);
            }

            if (callback.Result != EResult.OK)
            {
                if (callback.Result != EResult.AccessDenied)
                {
                    Log.WriteError("Depot Processor", "No access to depot {0} ({1})", depotID, callback.Result);
                }

                return(null);
            }

            Log.WriteDebug("Depot Downloader", "Got a new depot key for depot {0}", depotID);

            using (var db = Database.Get())
            {
                await db.ExecuteAsync("INSERT INTO `DepotsKeys` (`DepotID`, `Key`) VALUES (@DepotID, @Key) ON DUPLICATE KEY UPDATE `Key` = VALUES(`Key`)", new { depotID, Key = Utils.ByteArrayToString(callback.DepotKey) });
            }

            return(callback.DepotKey);
        }
예제 #7
0
        public Task <byte[]> RequestDepotKey(uint depotId, uint appId, bool allowCached = true)
        {
            if (allowCached && cachedDepotKeys.TryGetValue(depotId, out var runningTask))
            {
                return(runningTask);
            }

            return(cachedDepotKeys[depotId] = Task.Run <byte[]>(async() =>
            {
                var depotDecryptionKey = await steamApps.GetDepotDecryptionKey(depotId, appId);

                if (depotDecryptionKey.Result != EResult.OK)
                {
                    throw new Exception($"GetDepotDecryptionKey result = {depotDecryptionKey.Result}");
                }

                return depotDecryptionKey.DepotKey;
            }));
        }
        private static async Task GetDepotDecryptionKey(SteamApps instance, ManifestJob depot, uint appID)
        {
            if (!LicenseList.OwnedApps.ContainsKey(depot.DepotID))
            {
                return;
            }

            var task = instance.GetDepotDecryptionKey(depot.DepotID, appID);

            task.Timeout = TimeSpan.FromMinutes(15);

            SteamApps.DepotKeyCallback callback;

            try
            {
                callback = await task;
            }
            catch (TaskCanceledException)
            {
                Log.WriteWarn(nameof(DepotProcessor), $"Decryption key timed out for {depot.DepotID}");

                return;
            }

            if (callback.Result != EResult.OK)
            {
                if (callback.Result != EResult.AccessDenied)
                {
                    Log.WriteWarn(nameof(DepotProcessor), $"No access to depot {depot.DepotID} ({callback.Result})");
                }

                return;
            }

            Log.WriteDebug(nameof(DepotProcessor), $"Got a new depot key for depot {depot.DepotID}");

            await using (var db = await Database.GetConnectionAsync())
            {
                await db.ExecuteAsync("INSERT INTO `DepotsKeys` (`DepotID`, `Key`) VALUES (@DepotID, @Key) ON DUPLICATE KEY UPDATE `Key` = VALUES(`Key`)", new { depot.DepotID, Key = Utils.ByteArrayToString(callback.DepotKey) });
            }

            depot.DepotKey = callback.DepotKey;
        }
예제 #9
0
        private async void OnLoggedOn(SteamUser.LoggedOnCallback callback)
        {
            if (callback.Result != EResult.OK)
            {
                if (callback.Result == EResult.AccountLogonDenied)
                {
                    // if we recieve AccountLogonDenied or one of it's flavors (AccountLogonDeniedNoMailSent, etc)
                    // then the account we're logging into is SteamGuard protected
                    // see sample 5 for how SteamGuard can be handled

                    _logger.LogWarning("Unable to logon to Steam: This account is SteamGuard protected.");
                    return;
                }

                _logger.LogError("Unable to logon to Steam: {0} / {1}", callback.Result, callback.ExtendedResult);

                return;
            }

            // in this sample, we'll simply do a few async requests to acquire information about appid 440 (Team Fortress 2)

            // first, we'll request a depot decryption key for TF2's client/server shared depot (441)
            var depotJob = steamApps.GetDepotDecryptionKey(depotid: 441, appid: 440);

            // at this point, this request is now in-flight to the steam server, so we'll use te async/await pattern to wait for a response
            // the await pattern allows this code to resume once the Steam servers have replied to the request.
            // if Steam does not reply to the request in a timely fashion (controlled by the `Timeout` field on the AsyncJob object), the underlying
            // task for this job will be cancelled, and TaskCanceledException will be thrown.
            // additionally, if Steam encounters a remote failure and is unable to process your request, the job will be faulted and an AsyncJobFailedException
            // will be thrown.
            SteamApps.DepotKeyCallback depotKey = await depotJob;

            if (depotKey.Result == EResult.OK)
            {
                _logger.LogDebug($"Got our depot key: {BitConverter.ToString(depotKey.DepotKey)}");
            }
            else
            {
                _logger.LogDebug("Unable to request depot key!");
            }

            // now request some product info for TF2
            var productJob = steamApps.PICSGetProductInfo(440, package: null);

            // note that with some requests, Steam can return multiple results, so these jobs don't return the callback object directly, but rather
            // a result set that could contain multiple callback objects if Steam gives us multiple results
            AsyncJobMultiple <SteamApps.PICSProductInfoCallback> .ResultSet resultSet = await productJob;

            if (resultSet.Complete)
            {
                // the request fully completed, we can handle the data
                SteamApps.PICSProductInfoCallback productInfo = resultSet.Results.First();

                // ... do something with our product info
            }
            else if (resultSet.Failed)
            {
                // the request partially completed, and then Steam encountered a remote failure. for async jobs with only a single result (such as
                // GetDepotDecryptionKey), this would normally throw an AsyncJobFailedException. but since Steam had given us a partial set of callbacks
                // we get to decide what to do with the data

                // keep in mind that if Steam immediately fails to provide any data, or times out while waiting for the first result, an
                // AsyncJobFailedException or TaskCanceledException will be thrown

                // the result set might not have our data, so we need to test to see if we have results for our request
                SteamApps.PICSProductInfoCallback productInfo = resultSet.Results.FirstOrDefault(prodCallback => prodCallback.Apps.ContainsKey(440));

                if (productInfo != null)
                {
                    // we were lucky and Steam gave us the info we requested before failing
                }
                else
                {
                    // bad luck
                }
            }
            else
            {
                // the request partially completed, but then we timed out. essentially the same as the previous case, but Steam didn't explicitly fail.

                // we still need to check our result set to see if we have our data
                SteamApps.PICSProductInfoCallback productInfo = resultSet.Results.FirstOrDefault(prodCallback => prodCallback.Apps.ContainsKey(440));

                if (productInfo != null)
                {
                    // we were lucky and Steam gave us the info we requested before timing out
                }
                else
                {
                    // bad luck
                }
            }

            // lastly, if you're unable to use the async/await pattern (older VS/compiler, etc) you can still directly access the TPL Task associated
            // with the async job by calling `ToTask()`
            var depotTask = steamApps.GetDepotDecryptionKey(depotid: 441, appid: 440).ToTask();

            // set up a continuation for when this task completes
            var ignored = depotTask.ContinueWith(task =>
            {
                depotKey = task.Result;

                // do something with the depot key

                // we're finished with this sample, drop out of the callback loop
            }, TaskContinuationOptions.OnlyOnRanToCompletion);
        }
예제 #10
0
        public void RequestDepotKey(uint depotId, uint appid = 0)
        {
            if (DepotKeys.ContainsKey(depotId) || bAborted)
            {
                return;
            }

            Action <SteamApps.DepotKeyCallback, JobID> cbMethod = (depotKey, jobId) =>
            {
                Console.WriteLine("Got depot key for {0} result: {1}", depotKey.DepotID, depotKey.Result);

                if (depotKey.Result != EResult.OK)
                {
                    Abort();
                    return;
                }

                DepotKeys[depotKey.DepotID] = depotKey.DepotKey;
            };

            using (var depotKeyCallback = new JobCallback <SteamApps.DepotKeyCallback>(cbMethod, callbacks, steamApps.GetDepotDecryptionKey(depotId, appid)))
            {
                do
                {
                    WaitForCallbacks();
                }while (!depotKeyCallback.Completed && !bAborted);
            }
        }