static string GetAppOrDepotName(Steam3Session steam3, uint depotId, uint appId)
        {
            if (depotId == INVALID_DEPOT_ID)
            {
                KeyValue info = GetSteam3AppSection(steam3, appId, EAppInfoSection.Common);

                if (info == null)
                {
                    return(String.Empty);
                }

                return(info["name"].AsString());
            }
            else
            {
                KeyValue depots = GetSteam3AppSection(steam3, appId, EAppInfoSection.Depots);

                if (depots == null)
                {
                    return(String.Empty);
                }

                KeyValue depotChild = depots[depotId.ToString()];

                if (depotChild == null)
                {
                    return(String.Empty);
                }

                return(depotChild["name"].AsString());
            }
        }
        static uint GetSteam3AppBuildNumber(Steam3Session steam3, uint appId, string branch)
        {
            if (appId == INVALID_APP_ID)
            {
                return(0);
            }


            KeyValue depots   = ContentDownloader.GetSteam3AppSection(steam3, appId, EAppInfoSection.Depots);
            KeyValue branches = depots["branches"];
            KeyValue node     = branches[branch];

            if (node == KeyValue.Invalid)
            {
                return(0);
            }

            KeyValue buildid = node["buildid"];

            if (buildid == KeyValue.Invalid)
            {
                return(0);
            }

            return(uint.Parse(buildid.Value));
        }
        public static bool InitializeSteam3(string username = null, string password = null)
        {
            string loginKey = null;

            if (username != null && Config.RememberPassword)
            {
                _ = AccountSettingsStore.Instance.LoginKeys.TryGetValue(username, out loginKey);
            }

            Steam3 = new Steam3Session(
                new SteamUser.LogOnDetails()
            {
                Username = username,
                Password = loginKey == null ? password : null,
                ShouldRememberPassword = Config.RememberPassword,
                LoginKey = loginKey,
                LoginID  = Config.LoginID ?? 0x534B32,    // "SK2"
            }
                );

            Steam3Credentials = Steam3.WaitForCredentials();

            if (!Steam3Credentials.IsValid)
            {
                Console.WriteLine("Unable to get Steam3 credentials.");
                return(false);
            }

            cdnPool = new CDNClientPool(Steam3);
            return(true);
        }
        public static async Task DownloadApp(Steam3Session steam3, string installPath, uint appId, bool manifestOnly = false, Action downloadCompleteAction = null, params string[] fileList)
        {
            //Config.CellID = 0;
            Config.UsingFileList = fileList != null && fileList.Length > 0;
            if (Config.UsingFileList)
            {
                Config.FilesToDownload = new List <string>(fileList);
            }

            Config.InstallDirectory     = installPath;
            Config.DownloadManifestOnly = manifestOnly;
            Config.MaxDownloads         = 4;
            Config.MaxServers           = 20;
            string branch = DEFAULT_BRANCH;

            string os = "windows";

            cdnPool = new CDNClientPool(steam3);
            try
            {
                await DownloadAppAsync(steam3, appId, INVALID_DEPOT_ID, INVALID_MANIFEST_ID, branch, os, false, downloadCompleteAction);
            }
            catch (Exception e) { DebugLog.WriteLine("ErrorContentDownloader", e.ToString()); }
            Shutdown();
        }
Beispiel #5
0
        public static bool InitializeSteam3(string username, string password)
        {
            string loginKey = null;

            if (username != null && Config.RememberPassword)
            {
                _ = ConfigStore.TheConfig.LoginKeys.TryGetValue(username, out loginKey);
            }

            steam3 = new Steam3Session(
                new SteamUser.LogOnDetails()
            {
                Username = username,
                Password = loginKey == null ? password : null,
                ShouldRememberPassword = Config.RememberPassword,
                LoginKey = loginKey,
            }
                );

            steam3Credentials = steam3.WaitForCredentials();

            if (!steam3Credentials.IsValid)
            {
                Console.WriteLine("Unable to get steam3 credentials.");
                return(false);
            }

            cdnPool = new CDNClientPool(steam3);
            return(true);
        }
Beispiel #6
0
        public CDNClientPool(Steam3Session steamSession)
        {
            this.steamSession = steamSession;

            activeClientPool         = new ConcurrentBag <CDNClient>();
            activeClientAuthed       = new ConcurrentDictionary <CDNClient, Tuple <uint, CDNClient.Server> >();
            availableServerEndpoints = new BlockingCollection <CDNClient.Server>();

            populatePoolEvent = new AutoResetEvent(true);

            monitorTask = Task.Factory.StartNew(ConnectionPoolMonitorAsync).Unwrap();
        }
Beispiel #7
0
        public CDNClientPool(Steam3Session steamSession)
        {
            this.steamSession = steamSession;
            CDNClient         = new CDNClient(steamSession.steamClient);

            activeConnectionPool     = new ConcurrentBag <CDNClient.Server>();
            availableServerEndpoints = new BlockingCollection <CDNClient.Server>();

            populatePoolEvent = new AutoResetEvent(true);
            shutdownToken     = new CancellationTokenSource();

            monitorTask = Task.Factory.StartNew(ConnectionPoolMonitorAsync).Unwrap();
        }
        public static async Task DownloadPubfileAsync(Steam3Session steam3, ulong publishedFileId, Action downloadCompleteAction = null)
        {
            var details = await steam3.GetPubfileDetails(publishedFileId);

            if (details.hcontent_file > 0)
            {
                await DownloadAppAsync(steam3, details.consumer_appid, details.consumer_appid, details.hcontent_file, DEFAULT_BRANCH, null, true, downloadCompleteAction);
            }
            else
            {
                DebugLog.WriteLine("ContentDownloader", "Unable to locate manifest ID for published file " + publishedFileId);
            }
        }
        public CDNClientPool(Steam3Session steamSession)
        {
            this.steamSession = steamSession;

            activeClientPool         = new ConcurrentBag <CDNClient>();
            activeClientAuthed       = new ConcurrentDictionary <CDNClient, Tuple <uint, CDNClient.Server> >();
            availableServerEndpoints = new BlockingCollection <CDNClient.Server>();

            populatePoolEvent = new AutoResetEvent(true);

            monitorThread              = new Thread(ConnectionPoolMonitor);
            monitorThread.Name         = "CDNClient Pool Monitor";
            monitorThread.IsBackground = true;
            monitorThread.Start();
        }
Beispiel #10
0
        public static void InitializeSteam3(string username, string password)
        {
            steam3 = new Steam3Session(
                new SteamUser.LogOnDetails()
            {
                Username = username,
                Password = password,
            }
                );

            steam3Credentials = steam3.WaitForCredentials();

            if (!steam3Credentials.IsValid)
            {
                Console.WriteLine("Unable to get steam3 credentials.");
                return;
            }
        }
        internal static KeyValue GetSteam3AppSection(Steam3Session steam3, uint appId, EAppInfoSection section)
        {
            if (steam3 == null || steam3.AppInfo == null)
            {
                return(null);
            }

            SteamApps.PICSProductInfoCallback.PICSProductInfo app;
            if (!steam3.AppInfo.TryGetValue(appId, out app) || app == null)
            {
                return(null);
            }

            KeyValue appinfo = app.KeyValues;
            string   section_key;

            switch (section)
            {
            case EAppInfoSection.Common:
                section_key = "common";
                break;

            case EAppInfoSection.Extended:
                section_key = "extended";
                break;

            case EAppInfoSection.Config:
                section_key = "config";
                break;

            case EAppInfoSection.Depots:
                section_key = "depots";
                break;

            default:
                throw new NotImplementedException();
            }

            KeyValue section_kv = appinfo.Children.Where(c => c.Name == section_key).FirstOrDefault();

            return(section_kv);
        }
        static async Task <bool> AccountHasAccess(Steam3Session steam3, uint depotId)
        {
            if (steam3 == null || steam3.steamUser.SteamID == null || (steam3.Licenses == null && steam3.steamUser.SteamID.AccountType != EAccountType.AnonUser))
            {
                return(false);
            }

            IEnumerable <uint> licenseQuery;

            if (steam3.steamUser.SteamID.AccountType == EAccountType.AnonUser)
            {
                licenseQuery = new List <uint>()
                {
                    17906
                };
            }
            else
            {
                licenseQuery = steam3.Licenses.Select(x => x.PackageID);
            }

            await steam3.RequestPackageInfo(licenseQuery);

            foreach (var license in licenseQuery)
            {
                SteamApps.PICSProductInfoCallback.PICSProductInfo package;
                if (steam3.PackageInfo.TryGetValue(license, out package) && package != null)
                {
                    if (package.KeyValues["appids"].Children.Any(child => child.AsUnsignedInteger() == depotId))
                    {
                        return(true);
                    }

                    if (package.KeyValues["depotids"].Children.Any(child => child.AsUnsignedInteger() == depotId))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public static bool InitializeSteam3(string username, string password)
        {
            steam3 = new Steam3Session(
                new SteamUser.LogOnDetails()
                {
                    Username = username,
                    Password = password,
                }
            );

            steam3Credentials = steam3.WaitForCredentials();

            if (!steam3Credentials.IsValid)
            {
                Console.WriteLine("Unable to get steam3 credentials.");
                return false;
            }

            cdnPool = new CDNClientPool(steam3);
            return true;
        }
        static async Task <ulong> GetSteam3DepotManifest(Steam3Session steam3, uint depotId, uint appId, string branch)
        {
            KeyValue depots     = GetSteam3AppSection(steam3, 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 = depotChild["depotfromapp"].AsUnsignedInteger();
                if (otherAppId == appId)
                {
                    // This shouldn't ever happen, but ya never know with Valve. Don't infinite loop.
                    DebugLog.WriteLine("ContentDownloader", "App " + appId + ", Depot " + depotId + " has depotfromapp of " + otherAppId + "!");
                    return(INVALID_MANIFEST_ID);
                    //return INVALID_MANIFEST_ID;
                }

                await steam3.RequestAppInfo(otherAppId);

                return(await GetSteam3DepotManifest(steam3, 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)
                    {
                        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)
                        {
                            DebugLog.WriteLine("ContentDownloader", "Password was invalid for branch " + 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
                        await steam3.CheckAppBetaPassword(appId, Config.BetaPassword);

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

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

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

                return(INVALID_MANIFEST_ID);
            }

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

            return(ulong.Parse(node.Value));
        }
        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");
            }
        }
        public static void InitializeSteam3(string username, string password)
        {
            steam3 = new Steam3Session(
                new SteamUser.LogOnDetails()
                {
                    Username = username,
                    Password = password,

                    RequestSteam2Ticket = true,
                }
            );

            steam3Credentials = steam3.WaitForCredentials();

            if (!steam3Credentials.IsValid)
            {
                Console.WriteLine("Unable to get steam3 credentials.");
                return;
            }
        }
        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);
        }