Esempio n. 1
0
        static ulong GetSteam3DepotManifest(uint depotId, uint appId, string branch)
        {
            if (Config.ManifestId != INVALID_MANIFEST_ID)
            {
                return(Config.ManifestId);
            }

            KeyValue depots     = GetSteam3AppSection(appId, EAppInfoSection.Depots);
            KeyValue depotChild = depots[depotId.ToString()];

            if (depotChild == KeyValue.Invalid)
            {
                return(INVALID_MANIFEST_ID);
            }

            // Shared depots can either provide manifests, or leave you relying on their parent app.
            // It seems that with the latter, "sharedinstall" will exist (and equals 2 in the one existance I know of).
            // Rather than relay on the unknown sharedinstall key, just look for manifests. Test cases: 111710, 346680.
            if (depotChild["manifests"] == KeyValue.Invalid && depotChild["depotfromapp"] != KeyValue.Invalid)
            {
                uint otherAppId = ( uint )depotChild["depotfromapp"].AsInteger();
                if (otherAppId == appId)
                {
                    // This shouldn't ever happen, but ya never know with Valve. Don't infinite loop.
                    Console.WriteLine("App {0}, Depot {1} has depotfromapp of {2}!",
                                      appId, depotId, otherAppId);
                    return(INVALID_MANIFEST_ID);
                }

                steam3.RequestAppInfo(otherAppId);

                return(GetSteam3DepotManifest(depotId, otherAppId, branch));
            }

            var manifests           = depotChild["manifests"];
            var manifests_encrypted = depotChild["encryptedmanifests"];

            if (manifests.Children.Count == 0 && manifests_encrypted.Children.Count == 0)
            {
                return(INVALID_MANIFEST_ID);
            }

            var node = manifests[branch];

            if (branch != "Public" && node == KeyValue.Invalid)
            {
                var node_encrypted = manifests_encrypted[branch];
                if (node_encrypted != KeyValue.Invalid)
                {
                    string password = Config.BetaPassword;
                    if (password == null)
                    {
                        Console.Write("Please enter the password for branch {0}: ", branch);
                        Config.BetaPassword = password = Console.ReadLine();
                    }

                    var encrypted_v1 = node_encrypted["encrypted_gid"];
                    var encrypted_v2 = node_encrypted["encrypted_gid_2"];

                    if (encrypted_v1 != KeyValue.Invalid)
                    {
                        byte[] input          = Util.DecodeHexString(encrypted_v1.Value);
                        byte[] manifest_bytes = CryptoHelper.VerifyAndDecryptPassword(input, password);

                        if (manifest_bytes == null)
                        {
                            Console.WriteLine("Password was invalid for branch {0}", branch);
                            return(INVALID_MANIFEST_ID);
                        }

                        return(BitConverter.ToUInt64(manifest_bytes, 0));
                    }
                    else if (encrypted_v2 != KeyValue.Invalid)
                    {
                        // Submit the password to Steam now to get encryption keys
                        steam3.CheckAppBetaPassword(appId, Config.BetaPassword);

                        if (!steam3.AppBetaPasswords.ContainsKey(branch))
                        {
                            Console.WriteLine("Password was invalid for branch {0}", branch);
                            return(INVALID_MANIFEST_ID);
                        }

                        byte[] input = Util.DecodeHexString(encrypted_v2.Value);
                        byte[] manifest_bytes;
                        try
                        {
                            manifest_bytes = CryptoHelper.SymmetricDecryptECB(input, steam3.AppBetaPasswords[branch]);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("Failed to decrypt branch {0}: {1}", branch, e.Message);
                            return(INVALID_MANIFEST_ID);
                        }

                        return(BitConverter.ToUInt64(manifest_bytes, 0));
                    }
                    else
                    {
                        Console.WriteLine("Unhandled depot encryption for depotId {0}", depotId);
                        return(INVALID_MANIFEST_ID);
                    }
                }

                return(INVALID_MANIFEST_ID);
            }

            if (node.Value == null)
            {
                return(INVALID_MANIFEST_ID);
            }

            return(UInt64.Parse(node.Value));
        }