Esempio n. 1
0
        static bool AppIsSteam3(int appId)
        {
            if (steam3 == null || steam3.AppInfoOverridesCDR == null)
            {
                return(false);
            }

            steam3.RequestAppInfo((uint)appId);

            bool app_override;

            if (!steam3.AppInfoOverridesCDR.TryGetValue((uint)appId, out app_override))
            {
                return(false);
            }

            return(app_override);
        }
Esempio n. 2
0
        static bool AppIsSteam3(int appId)
        {
            if (steam3 == null || steam3.AppInfoOverridesCDR == null)
            {
                return(false);
            }

            steam3.RequestAppInfo((uint)appId);

            bool app_override;

            if (!steam3.AppInfoOverridesCDR.TryGetValue((uint)appId, out app_override))
            {
                return(false);
            }

            KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots);

            foreach (KeyValue depotChild in depots.Children)
            {
                if (depotChild == null)
                {
                    return(false);
                }

                int id;
                if (!int.TryParse(depotChild.Name, out id))
                {
                    continue;
                }

                var nodes           = depotChild["manifests"].Children;
                var nodes_encrypted = depotChild["encryptedmanifests"].Children;

                if (nodes.Count == 0 && nodes_encrypted.Count == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 3
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));
        }
        static async Task <DepotDownloadInfo> GetDepotInfo(Steam3Session steam3, uint depotId, uint appId, ulong manifestId, string branch)
        {
            if (steam3 != null && appId != INVALID_APP_ID)
            {
                await steam3.RequestAppInfo(appId);
            }

            string contentName = GetAppOrDepotName(steam3, depotId, appId);

            bool hasAccess = await AccountHasAccess(steam3, depotId);

            if (!hasAccess)
            {
                DebugLog.WriteLine("ContentDownloader", "Depot " + depotId + " (" + contentName + ") is not available from this account.");

                return(null);
            }

            // Skip requesting an app ticket
            steam3.AppTickets[depotId] = null;

            if (manifestId == INVALID_MANIFEST_ID)
            {
                manifestId = await GetSteam3DepotManifest(steam3, depotId, appId, branch);

                if (manifestId == INVALID_MANIFEST_ID && branch != "public")
                {
                    DebugLog.WriteLine("ContentDownloader", "Warning: Depot " + depotId + " does not have branch named \"" + branch + "\". Trying public branch.");
                    branch     = "public";
                    manifestId = await GetSteam3DepotManifest(steam3, depotId, appId, branch);
                }

                if (manifestId == INVALID_MANIFEST_ID)
                {
                    DebugLog.WriteLine("ContentDownloader", "Depot " + depotId + " (" + contentName + ") missing public subsection or manifest section.");
                    return(null);
                }
            }

            uint uVersion = GetSteam3AppBuildNumber(steam3, appId, branch);

            string installDir;

            if (!CreateDirectories(depotId, uVersion, out installDir))
            {
                DebugLog.WriteLine("ContentDownloader", "Error: Unable to create install directories!");
                return(null);
            }

            await steam3.RequestDepotKey(depotId, appId);

            if (!steam3.DepotKeys.ContainsKey(depotId))
            {
                DebugLog.WriteLine("ContentDownloader", "No valid depot key for " + depotId + ", unable to download.");
                return(null);
            }

            byte[] depotKey = steam3.DepotKeys[depotId];

            var info = new DepotDownloadInfo(depotId, manifestId, installDir, contentName);

            info.depotKey = depotKey;
            return(info);
        }
        public static async Task DownloadAppAsync(Steam3Session steam3, uint appId, uint depotId, ulong manifestId, string branch, string os, bool isUgc, Action downloadCompleteAction = null)
        {
            if (steam3 != null)
            {
                await steam3.RequestAppInfo(appId);
            }

            bool hasAccess = await AccountHasAccess(steam3, appId);

            if (!hasAccess)
            {
                bool freeAppLicense = await steam3.RequestFreeAppLicense(appId);

                if (freeAppLicense)
                {
                    DebugLog.WriteLine("ContentDownloader", "Obtained FreeOnDemand license for app " + appId);
                }
                else
                {
                    string contentName = GetAppOrDepotName(steam3, INVALID_DEPOT_ID, appId);
                    DebugLog.WriteLine("ContentDownloader", "App " + appId + " (" + contentName + ") is not available from this account.");
                    return;
                }
            }

            var      depotIDs = new List <uint>();
            KeyValue depots   = GetSteam3AppSection(steam3, appId, EAppInfoSection.Depots);

            if (isUgc)
            {
                var workshopDepot = depots["workshopdepot"].AsUnsignedInteger();
                if (workshopDepot != 0)
                {
                    depotId = workshopDepot;
                }

                depotIDs.Add(depotId);
            }
            else
            {
                DebugLog.WriteLine("ContentDownloader", "Using app branch: '" + branch + "'.");

                if (depots != null)
                {
                    foreach (var depotSection in depots.Children)
                    {
                        uint id = INVALID_DEPOT_ID;
                        if (depotSection.Children.Count == 0)
                        {
                            continue;
                        }

                        if (!uint.TryParse(depotSection.Name, out id))
                        {
                            continue;
                        }

                        if (depotId != INVALID_DEPOT_ID && id != depotId)
                        {
                            continue;
                        }

                        if (depotId == INVALID_DEPOT_ID && !Config.DownloadAllPlatforms)
                        {
                            var depotConfig = depotSection["config"];
                            if (depotConfig != KeyValue.Invalid && depotConfig["oslist"] != KeyValue.Invalid && !string.IsNullOrWhiteSpace(depotConfig["oslist"].Value))
                            {
                                var oslist = depotConfig["oslist"].Value.Split(',');
                                if (Array.IndexOf(oslist, os ?? Util.GetSteamOS()) == -1)
                                {
                                    continue;
                                }
                            }
                        }

                        depotIDs.Add(id);
                    }
                }
                if (depotIDs == null || (depotIDs.Count == 0 && depotId == INVALID_DEPOT_ID))
                {
                    DebugLog.WriteLine("ContentDownloader", "Couldn't find any depots to download for app " + appId);
                    return;
                }
                else if (depotIDs.Count == 0)
                {
                    DebugLog.WriteLine("ContentDownloader", "Depot " + depotId + " not listed for app " + appId);
                    return;
                }
            }

            var infos = new List <DepotDownloadInfo>();

            foreach (var depot in depotIDs)
            {
                var info = await GetDepotInfo(steam3, depot, appId, manifestId, branch);

                if (info != null)
                {
                    infos.Add(info);
                }
            }

            try
            {
                IsDownloading = true;
                await DownloadSteam3Async(appId, infos, downloadCompleteAction);
            }
            catch (OperationCanceledException)
            {
                DebugLog.WriteLine("ContentDownloader", "App " + appId + " was not completely downloaded.");
            }
            finally
            {
                DebugLog.WriteLine("ContentDownloader", "Download completed");
            }
        }
Esempio n. 6
0
        public static void DownloadApp(uint appId, uint depotId, string branch)
        {
            if (steam3 != null)
            {
                steam3.RequestAppInfo(appId);
            }

            if (!AccountHasAccess(appId))
            {
                string contentName = GetAppOrDepotName(INVALID_DEPOT_ID, appId);
                Console.WriteLine("App {0} ({1}) is not available from this account.", appId, contentName);
                return;
            }

            var      depotIDs = new List <uint>();
            KeyValue depots   = GetSteam3AppSection(appId, EAppInfoSection.Depots);

            if (depots != null)
            {
                foreach (var depotSection in depots.Children)
                {
                    uint id = INVALID_DEPOT_ID;
                    if (depotSection.Children.Count == 0)
                    {
                        continue;
                    }

                    if (!uint.TryParse(depotSection.Name, out id))
                    {
                        continue;
                    }

                    if (depotId != INVALID_DEPOT_ID && id != depotId)
                    {
                        continue;
                    }

                    if (!Config.DownloadAllPlatforms)
                    {
                        var depotConfig = depotSection["config"];
                        if (depotConfig != KeyValue.Invalid && depotConfig["oslist"] != KeyValue.Invalid && !string.IsNullOrWhiteSpace(depotConfig["oslist"].Value))
                        {
                            var oslist = depotConfig["oslist"].Value.Split(',');
                            if (Array.IndexOf(oslist, Util.GetSteamOS()) == -1)
                            {
                                continue;
                            }
                        }
                    }

                    depotIDs.Add(id);
                }
            }

            if (depotIDs == null || (depotIDs.Count == 0 && depotId == INVALID_DEPOT_ID))
            {
                Console.WriteLine("Couldn't find any depots to download for app {0}", appId);
                return;
            }
            else if (depotIDs.Count == 0)
            {
                Console.Write("Depot {0} not listed for app {1}", depotId, appId);
                if (!Config.DownloadAllPlatforms)
                {
                    Console.Write(" or not available on this platform");
                }
                Console.WriteLine();
                return;
            }

            var infos = new List <DepotDownloadInfo>();

            foreach (var depot in depotIDs)
            {
                DepotDownloadInfo info = GetDepotInfo(depot, appId, branch);
                if (info != null)
                {
                    infos.Add(info);
                }
            }

            DownloadSteam3(infos);
        }
        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);
            }

            if (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);

                if (AccountHasAccess(otherAppId))
                {
                    return(GetSteam3DepotManifest(depotId, otherAppId, branch));
                }
                else
                {
                    string contentName      = GetAppOrDepotName(INVALID_DEPOT_ID, otherAppId);
                    string contentDepotName = GetAppOrDepotName(depotId, appId);
                    Console.WriteLine("Dependent app {0} ({1}) for depot {2} ({3}) is not available from this account.", otherAppId, contentName, depotId, contentDepotName);
                }
            }

            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();
                    }

                    byte[] input          = Util.DecodeHexString(node_encrypted["encrypted_gid"].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));
                }

                Console.WriteLine("Invalid branch {0} for appId {1}", branch, appId);
                return(INVALID_MANIFEST_ID);
            }

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

            return(UInt64.Parse(node.Value));
        }
        static public 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();
                    }

                    byte[] input = Util.DecodeHexString(node_encrypted["encrypted_gid"].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);
                }

                return INVALID_MANIFEST_ID;
            }

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

            return UInt64.Parse(node.Value);
        }