public static async Task <PluginInfo> FetchAsync(CancellationToken ct = default) { App.Current.Logger.Info(nameof(PluginInfo), "Downloading plugin info"); using (var client = new ArksLayerHttpClient()) { using (var request = await client.GetAsync(DownloadConfiguration.PluginsFile, ct)) { var downloadText = await request.Content.ReadAsStringAsync(); var downloadJson = JsonConvert.DeserializeObject <Dictionary <string, PluginEntry> >(downloadText); return(new PluginInfo { PSO2hDll = downloadJson["PluginLoader"], DDrawDll = downloadJson["PluginHook"], TelepipeProxyDll = downloadJson["TelepipeProxy"], PSO2BlockRenameDll = downloadJson["BlockTranslation"], PSO2ItemTranslatorDll = downloadJson["ItemTranslation"], PSO2RAISERSystemDll = downloadJson["TextTranslation"], PSO2TitleTranslatorDll = downloadJson["TitleTranslation"] }); } } }
public async Task ValidateFileAsync(string filePath, CancellationToken ct = default) { var valid = await Task.Run(() => { if (File.Exists(filePath)) { using (var md5 = MD5.Create()) using (var fs = File.OpenRead(filePath)) { var hashBytes = md5.ComputeHash(fs); var hashString = string.Concat(hashBytes.Select(b => b.ToString("X2", CultureInfo.InvariantCulture))); if (hashString == Hash) { return(true); } } } File.Delete(filePath); return(false); }); if (valid) { return; } using (var client = new ArksLayerHttpClient()) using (var ns = await client.GetStreamAsync(new Uri(DownloadConfiguration.PluginsRoot, FileName))) using (var fs = File.Create(filePath, 4096, FileOptions.Asynchronous)) { await ns.CopyToAsync(fs); } }
public static async Task <Dictionary <string, TranslationInfo> > FetchAllAsync(CancellationToken ct = default) { App.Current.Logger.Info(nameof(TranslationInfo), "Downloading translation info"); using (var client = new ArksLayerHttpClient()) { using (var request = await client.GetAsync(DownloadConfiguration.TranslationsFile, ct)) { var downloadText = await request.Content.ReadAsStringAsync(); return(JsonConvert.DeserializeObject <Dictionary <string, TranslationInfo> >(downloadText)); } } }
public static async Task <PluginInfo> FetchAsync(CancellationToken ct = default) { App.Logger.Info(nameof(PluginInfo), "Downloading plugin info"); using (var client = new ArksLayerHttpClient()) { using (var request = await client.GetAsync(DownloadConfiguration.TranslationsFile, ct)) { var downloadText = await request.Content.ReadAsStringAsync(); var downloadJson = JsonConvert.DeserializeObject <Dictionary <string, PluginEntry> >(downloadText); return(new PluginInfo { PluginLoader = downloadJson["Plugin Loader"], ProxyLoader = downloadJson["Proxy Loader"], BlockTranslation = downloadJson["Translate Blocks"], ItemTranslation = downloadJson["Translate Items"], TextTranslation = downloadJson["Translate Interface & Dialogue"], TitleTranslation = downloadJson["Translate Titles"] }); } } }
public async Task ValidateAsync(InstallConfiguration installConfiguration, CancellationToken ct = default) { async Task ValidateFileAsync(string relativePath, string hash, string url) { var path = Path.Combine(installConfiguration.PSO2BinDirectory, relativePath); if (File.Exists(path)) { using (var md5 = MD5.Create()) using (var fs = File.OpenRead(path)) { var hashBytes = md5.ComputeHash(fs); var hashString = string.Concat(hashBytes.Select(b => b.ToString("X2", CultureInfo.InvariantCulture))); if (hashString == Hash) { return; } } } App.Logger.Info(nameof(PluginInfo), $"Downloading plugin file english data: \"{relativePath}\""); using (var client = new ArksLayerHttpClient()) using (var response = await client.GetAsync(url, ct)) { App.Logger.Info(nameof(PluginInfo), $"Download plugin file english data status code: {response.StatusCode}"); response.EnsureSuccessStatusCode(); App.Logger.Info(nameof(PluginInfo), $"Reading plugin data: \"{relativePath}\""); using (var ns = await response.Content.ReadAsStreamAsync()) { if (Path.GetExtension(new Uri(url).LocalPath).ToLowerInvariant() != ".rar") { App.Logger.Info(nameof(PluginInfo), $"Writing file: \"{relativePath}\""); using (var fs = File.Create(path, 4096, FileOptions.Asynchronous)) await ns.CopyToAsync(fs); return; } App.Logger.Info(nameof(PluginInfo), $"Extracting archive file: \"{relativePath}\""); // when the file is an archive we hash against the file named the same using (var archive = RarArchive.Open(ns)) { var fileEntries = archive.Entries.Where(e => !e.IsDirectory).ToArray(); if (fileEntries.Length == 0) { var entryNames = fileEntries.Select(e => e.Key).ToArray(); throw new Exception($"Expected more than one file in archive"); } if (fileEntries.Length == 1) { using (var fs = File.Create(path, 4096, FileOptions.Asynchronous)) using (var es = fileEntries.First().OpenEntryStream()) await es.CopyToAsync(fs); return; } App.Logger.Info(nameof(PluginInfo), "Multiple entries present in archive"); var primaryEntry = fileEntries.First(e => e.Key.ToLowerInvariant() == Path.GetFileName(path).ToLowerInvariant()); var otherEntries = fileEntries.Where(e => e != primaryEntry).ToArray(); using (var fs = File.Create(path, 4096, FileOptions.Asynchronous)) using (var es = primaryEntry.OpenEntryStream()) await es.CopyToAsync(fs); foreach (var entry in otherEntries) { var directory = Path.GetDirectoryName(path); var otherPath = Path.Combine(directory, entry.Key); using (var fs = File.Create(otherPath, 4096, FileOptions.Asynchronous)) using (var es = entry.OpenEntryStream()) await es.CopyToAsync(fs); } } } } } App.Logger.Info(nameof(PluginInfo), $"Validating plugin file: \"{FilePath}\""); await Task.Run(async() => await ValidateFileAsync(FilePath, Hash, Url)); if (EnglishData != null) { App.Logger.Info(nameof(PluginInfo), $"Validating plugin file english data: \"{EnglishData.FilePath}\""); await Task.Run(async() => await ValidateFileAsync(EnglishData.FilePath, EnglishData.Hash, EnglishData.Url)); } }