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