internal static async Task DownloadFromList(string listPath, string downloadDir, int maxThreads = 8) { maxThreads = maxThreads < -1 ? -1 : maxThreads; maxThreads = maxThreads == 0 ? 1 : maxThreads; Stopwatch stopwatch = Stopwatch.StartNew(); Log.Instance.Info($"Beginning download from the list '{listPath}' with {(maxThreads > -1 ? maxThreads.ToString() : "unlimited")} max thread{(maxThreads != 1 ? "s" : "")}."); string[] listLines = await File.ReadAllLinesAsync(listPath); using HttpClient client = new HttpClient(); Parallel.ForEach(listLines, new ParallelOptions { MaxDegreeOfParallelism = maxThreads }, async line => { string[] lineParts = line.Split(' ').Select(l => l.Trim()).ToArray(); if (lineParts.Length < 2) { return; } Log.Instance.Info(line); string titleDir = Path.Combine(downloadDir, lineParts[0]); Directory.CreateDirectory(titleDir); await DownloadTitleFile(client, titleDir, lineParts[0], lineParts[1]); }); Log.Instance.Info($"Completed the download from the list in {stopwatch.ElapsedAfterStopped().ToNiceString()}."); }
public static async Task DownloadMiscFiles(string downloadDir) { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Instance.Info($"Beginning download of miscellaneous files for download dir '{downloadDir}'."); using HttpClient client = new HttpClient(); foreach (string titleDir in Directory.EnumerateDirectories(downloadDir)) { string titleId = Path.GetFileName(titleDir); Log.Instance.Info($"Downloading miscellaneous files for '{titleId}'"); // Download the icon and all screenshots uint fileIndex = ShopDataStartIndex; bool lastFileMissing = false; while (true) { Log.Instance.Debug($"Attempting to download {fileIndex:X8}"); string result = await DownloadTitleFile(client, titleDir, titleId, fileIndex ++.ToString("X8"), false); if (result == null && lastFileMissing) { break; } lastFileMissing = result == null; } // Download the mysterious empty file for each title Log.Instance.Debug($"Attempting to download {EmptyContentIndex:X8}"); string emptyFilePath = await DownloadTitleFile(client, titleDir, titleId, EmptyContentIndex.ToString("X8")); if (!string.IsNullOrWhiteSpace(emptyFilePath) && new FileInfo(emptyFilePath)?.Length > 0) { Log.Instance.Warn($"File '{emptyFilePath}' is not empty!"); } // Download the ticket at it's content index Log.Instance.Debug($"Attempting to download {TicketContentIndex:X8}"); await DownloadTitleFile(client, titleDir, titleId, TicketContentIndex.ToString("X8"), false); // Download the metadata files at their content indices fileIndex = MetadataStartIndex; lastFileMissing = false; while (true) { Log.Instance.Debug($"Attempting to download {fileIndex:X8}"); string result = await DownloadTitleFile(client, titleDir, titleId, fileIndex --.ToString("X8"), false); if (result == null && lastFileMissing) { break; } lastFileMissing = result == null; } } Log.Instance.Info($"Completed the download of miscellaneous files in {stopwatch.ElapsedAfterStopped().ToNiceString()}."); }
internal static async Task DecryptEntries(byte[] commonKey, string archiveDir, bool makeQolFiles = false /*, int maxThreads = -1*/) { Stopwatch stopwatch = Stopwatch.StartNew(); Log.Instance.Info($"Beginning batch processing of the folder '{archiveDir}', with QoL files {(!makeQolFiles ? "not " : "")}being created."); //Parallel.ForEach(Directory.EnumerateDirectories(archiveDir), new ParallelOptions { MaxDegreeOfParallelism = maxThreads }, async titleDir => foreach (string titleDir in Directory.EnumerateDirectories(archiveDir)) { await DecryptEntry(commonKey, titleDir, makeQolFiles); } //); Log.Instance.Info($"Completed the batch processing in {stopwatch.ElapsedAfterStopped().ToNiceString()}."); }