/// <summary> /// Loads the Build, CDN and Patch configs from disk /// </summary> /// <param name="directory">Directory containing the config files</param> public void OpenLocal(string directory, ManifestContainer manifestContainer) { if (manifestContainer?.VersionsFile == null || manifestContainer?.CDNsFile == null) { throw new Exception("Versions and CDNs files must be loaded first"); } if (!manifestContainer.VersionsFile.HasLocale(manifestContainer.Locale)) { throw new Exception($"Versions missing {manifestContainer.Locale} locale"); } if (manifestContainer.BuildConfigMD5.Value != null) { BuildConfig = new KeyValueConfig(manifestContainer.BuildConfigMD5.ToString(), directory, ConfigType.BuildConfig); } if (manifestContainer.CDNConfigMD5.Value != null) { CDNConfig = new KeyValueConfig(manifestContainer.CDNConfigMD5.ToString(), directory, ConfigType.CDNConfig); } // optionally load the patch config if (PatchConfigMD5.Value != null) { string path = Helpers.GetCDNPath(PatchConfigMD5.ToString(), "config", directory); if (File.Exists(path)) { PatchConfig = new KeyValueConfig(PatchConfigMD5.ToString(), directory, ConfigType.PatchConfig); } } }
/// <summary> /// Opens the CDNs, Versions from Ribbit and the config files from Blizzard's CDN /// </summary> public void OpenRemote(ManifestContainer manifestContainer) { if (manifestContainer?.VersionsFile == null || manifestContainer?.CDNsFile == null) { throw new Exception("Versions and CDNs files must be loaded first"); } if (!manifestContainer.VersionsFile.HasLocale(manifestContainer.Locale)) { throw new Exception($"Versions missing {manifestContainer.Locale} locale"); } var cdnClient = new CDNClient(manifestContainer); if (manifestContainer.BuildConfigMD5.Value != null) { string configUrl = Helpers.GetCDNUrl(manifestContainer.BuildConfigMD5.ToString(), "config"); BuildConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.BuildConfig); } if (manifestContainer.CDNConfigMD5.Value != null) { string configUrl = Helpers.GetCDNUrl(manifestContainer.CDNConfigMD5.ToString(), "config"); CDNConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.CDNConfig); } if (PatchConfigMD5.Value != null) { string configUrl = Helpers.GetCDNUrl(PatchConfigMD5.ToString(), "config"); PatchConfig = new KeyValueConfig(cdnClient.OpenStream(configUrl).Result, ConfigType.PatchConfig); } }
/// <summary> /// Download and open an remote TACT container /// <para>Note: This will download the entire CDN so will take a while</para> /// </summary> /// <param name="url"></param> /// <param name="tprDirectory"></param> /// <param name="product"></param> /// <param name="locale"></param> public void DownloadRemote(string tprDirectory, string product, Locale locale, bool systemFileOnly = false) { ManifestContainer = new Configs.ManifestContainer(product, locale); ManifestContainer.DownloadRemote(BaseDirectory); ConfigContainer = new Configs.ConfigContainer(); ConfigContainer.DownloadRemote(tprDirectory, ManifestContainer); var cdnClient = new CDNClient(ManifestContainer); var queuedDownload = new QueuedDownloader(tprDirectory, cdnClient); if (ConfigContainer.EncodingEKey.Value != null) { // Download encoding file var encodingEKey = DownloadSystemFile(ConfigContainer.EncodingEKey, cdnClient, tprDirectory); if (encodingEKey.Value != null) { EncodingFile = new Encoding.EncodingFile(tprDirectory, encodingEKey, true); } // Download PatchFile DownloadSystemFile(ConfigContainer.PatchEKey, cdnClient, tprDirectory, "patch"); // Download RootFile if (EncodingFile.TryGetCKeyEntry(ConfigContainer.RootCKey, out var ekeyEntry)) { ekeyEntry.EKeys.ForEach(x => queuedDownload.Enqueue(x.Value.ToString())); } // Download InstallFile if (EncodingFile.TryGetCKeyEntry(ConfigContainer.InstallCKey, out ekeyEntry)) { ekeyEntry.EKeys.ForEach(x => queuedDownload.Enqueue(x.Value.ToString())); } // Download DownloadFile if (EncodingFile.TryGetCKeyEntry(ConfigContainer.DownloadCKey, out ekeyEntry)) { ekeyEntry.EKeys.ForEach(x => queuedDownload.Enqueue(x.Value.ToString())); } // Download DownloadSizeFile if (EncodingFile.TryGetCKeyEntry(ConfigContainer.DownloadSizeCKey, out ekeyEntry)) { ekeyEntry.EKeys.ForEach(x => queuedDownload.Enqueue(x.Value.ToString())); } queuedDownload.Download("data"); } // Download Indices and archives if (!systemFileOnly) { IndexContainer = new Indices.IndexContainer(); IndexContainer.DownloadRemote(tprDirectory, ConfigContainer, ManifestContainer); } Open(tprDirectory); }
/// <summary> /// Saves the configs using to the Blizzard standard location /// </summary> /// <param name="directory"></param> public void Save(string directory, ManifestContainer manifestContainer = null) { // save and update patch config value if (PatchConfig != null) { PatchConfig?.Write(directory); BuildConfig?.SetValue("patch-config", PatchConfig.Checksum.ToString()); } // save the localised configs BuildConfig?.Write(directory); CDNConfig?.Write(directory); // update the hashes manifestContainer?.VersionsFile.SetValue("buildconfig", BuildConfig.Checksum.ToString()); manifestContainer?.VersionsFile.SetValue("cdnconfig", CDNConfig.Checksum.ToString()); }
/// <summary> /// Creates a new TACT container populated with: defaulted configs, an index container /// and an empty root, encoding, install and download file /// </summary> /// <param name="product"></param> /// <param name="locale"></param> /// <param name="build"></param> public void Create(string product, Locale locale, uint build) { Build = build; ManifestContainer = new Configs.ManifestContainer(product, locale); ManifestContainer.Create(); ConfigContainer = new Configs.ConfigContainer(); ConfigContainer.Create(); IndexContainer = new Indices.IndexContainer(); RootFile = new Root.RootFile(); EncodingFile = new Encoding.EncodingFile(); InstallFile = new Install.InstallFile(); DownloadFile = new Download.DownloadFile(); ApplyVersionSpecificSettings(build); // set the default tag entries InstallFile.SetDefaultTags(build); DownloadFile.SetDefaultTags(build); DownloadSizeFile?.SetDefaultTags(build); }
/// <summary> /// Loads the CDNs/Versions manifests and optional stores the base directory /// </summary> /// <param name="product"></param> /// <param name="locale"></param> /// <param name="manifestDirectory"></param> /// <param name="baseDirectory"></param> public TACTRepo(string product, Locale locale, string manifestDirectory, string baseDirectory = "") { ManifestContainer = new Configs.ManifestContainer(product, locale); ManifestContainer.OpenLocal(manifestDirectory); BaseDirectory = baseDirectory; }
/// <summary> /// Streams an existing TACT container from an external CDN /// </summary> /// <param name="product"></param> /// <param name="locale"></param> public void OpenRemote(string product, Locale locale) { ManifestContainer = new Configs.ManifestContainer(product, locale); ConfigContainer = new Configs.ConfigContainer(); ConfigContainer.OpenRemote(ManifestContainer); if (uint.TryParse(ManifestContainer?.VersionsFile?.GetValue("BuildId", locale), out uint build)) { Build = build; } // stream Indicies IndexContainer = new Indices.IndexContainer(); IndexContainer.OpenRemote(ConfigContainer, ManifestContainer, true); var cdnClient = new CDNClient(ManifestContainer); if (ConfigContainer.EncodingEKey.Value != null) { // Stream EncodingFile EncodingFile = new Encoding.EncodingFile(cdnClient, ConfigContainer.EncodingEKey); // Stream RootFile if (EncodingFile.TryGetCKeyEntry(ConfigContainer.RootCKey, out var entry)) { RootFile = new Root.RootFile(cdnClient, entry.EKeys[0]); } // Stream InstallFile if (ConfigContainer.InstallEKey.Value != null) { InstallFile = new Install.InstallFile(cdnClient, ConfigContainer.InstallEKey); } else if (EncodingFile.TryGetCKeyEntry(ConfigContainer.InstallCKey, out entry)) { InstallFile = new Install.InstallFile(cdnClient, entry.EKeys[0]); } // Stream DownloadFile if (ConfigContainer.DownloadEKey.Value != null) { DownloadFile = new Download.DownloadFile(cdnClient, ConfigContainer.DownloadEKey); } else if (EncodingFile.TryGetCKeyEntry(ConfigContainer.DownloadCKey, out entry)) { DownloadFile = new Download.DownloadFile(cdnClient, entry.EKeys[0]); } // Stream DownloadSizeFile if (ConfigContainer.DownloadSizeEKey.Value != null) { DownloadSizeFile = new Download.DownloadSizeFile(cdnClient, ConfigContainer.DownloadSizeEKey); } else if (EncodingFile.TryGetCKeyEntry(ConfigContainer.DownloadSizeCKey, out entry)) { DownloadSizeFile = new Download.DownloadSizeFile(cdnClient, entry.EKeys[0]); } } // Stream PatchFile if (ConfigContainer.PatchEKey.Value != null) { PatchFile = new Patch.PatchFile(cdnClient, ConfigContainer.PatchEKey); } }
/// <summary> /// Download and load the config files from remote /// </summary> /// <param name="directory"></param> public void DownloadRemote(string directory, ManifestContainer manifestContainer) { OpenRemote(manifestContainer); Save(directory, manifestContainer); }