public async Task TocSizeTest() { var path = @"E:\FakeCDs\PS3 Games\ird"; var result = new List <(string filename, long size)>(); foreach (var f in Directory.EnumerateFiles(path, "*.ird", SearchOption.TopDirectoryOnly)) { var bytes = await File.ReadAllBytesAsync(f).ConfigureAwait(false); var ird = IrdParser.Parse(bytes); using (var header = GetDecompressHeader(ird)) result.Add((Path.GetFileName(f), header.Length)); } Assert.That(result.Count, Is.GreaterThan(0)); var groupedStats = (from t in result group t by t.size into g select new { size = g.Key, count = g.Count() } ).OrderByDescending(i => i.count) .ThenByDescending(i => i.size) .ToList(); var largest = groupedStats.Max(i => i.size); var largestItem = result.First(i => i.size == largest); Console.WriteLine($"Largest TOC: {largestItem.filename} ({largest.AsStorageUnit()})"); foreach (var s in groupedStats) { Console.WriteLine($"{s.count} items of size {s.size}"); } Assert.That(groupedStats.Count, Is.EqualTo(1)); }
private void selectIrdButton_Click(object sender, EventArgs e) { var dialog = new OpenFileDialog { CheckFileExists = true, DefaultExt = ".ird", Filter = "IRD file (*.ird)|*.ird|Redump disc key file (*.dkey)|*.dkey|All supported files|*.ird;*.dkey|All files|*", FilterIndex = 2, Title = "Select a disc key file", SupportMultiDottedExtensions = true, InitialDirectory = settings.IrdDir, }; var dialogResult = dialog.ShowDialog(); if (dialogResult != DialogResult.OK || string.IsNullOrEmpty(dialog.FileName) || !File.Exists(dialog.FileName)) { return; } var discKeyPath = dialog.FileName; try { var discKey = File.ReadAllBytes(discKeyPath); DiscKeyInfo keyInfo; if (discKey.Length > 256 / 8) { var ird = IrdParser.Parse(discKey); keyInfo = new DiscKeyInfo(ird.Data1, null, discKeyPath, KeyType.Ird, ird.Crc32.ToString("x8")); } else { keyInfo = new DiscKeyInfo(null, discKey, discKeyPath, KeyType.Redump, discKey.ToHexString()); } var discKeyFilename = Path.GetFileName(discKeyPath); var cacheFilename = Path.Combine(settings.IrdDir, discKeyFilename); if (!File.Exists(cacheFilename)) { File.Copy(discKeyPath, cacheFilename); } //todo: proper check if (!currentDumper.IsValidDiscKey(discKey)) { MessageBox.Show("Selected disk key file contains incompatible file set, and cannot be used with the selected PS3 game disc.", "IRD file check", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } selectIrdButton.Visible = false; selectIrdButton.Enabled = false; FindMatchingIrdFinished(sender, new RunWorkerCompletedEventArgs(currentDumper, null, currentDumper?.Cts.IsCancellationRequested ?? true)); } catch (Exception ex) { MessageBox.Show(ex.Message, "IRD Check Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public void ParsingTest() { var baseDir = TestContext.CurrentContext.TestDirectory; var testFiles = Directory.GetFiles(baseDir, "*.ird", SearchOption.AllDirectories); Assert.That(testFiles.Length, Is.GreaterThan(0)); foreach (var file in testFiles) { var bytes = File.ReadAllBytes(file); Assert.That(() => IrdParser.Parse(bytes), Throws.Nothing, "Failed to parse " + Path.GetFileName(file)); } }
public async Task <Ird> DownloadAsync(SearchResultItem irdInfo, string localCachePath, CancellationToken cancellationToken) { Ird result = null; try { var localCacheFilename = Path.Combine(localCachePath, irdInfo.Filename); // first we search local cache and try to load whatever data we can try { if (File.Exists(localCacheFilename)) { return(IrdParser.Parse(File.ReadAllBytes(localCacheFilename))); } } catch (Exception e) { Log.Warn(e, "Error accessing local IRD cache: " + e.Message); } try { var resultBytes = await client.GetByteArrayAsync(GetDownloadLink(irdInfo.Filename)).ConfigureAwait(false); result = IrdParser.Parse(resultBytes); try { if (!Directory.Exists(localCachePath)) { Directory.CreateDirectory(localCachePath); } File.WriteAllBytes(localCacheFilename, resultBytes); } catch (Exception ex) { Log.Warn(ex, $"Failed to write {irdInfo.Filename} to local cache: {ex.Message}"); } } catch (Exception e) { Log.Warn(e, $"Failed to download {irdInfo.Filename}: {e.Message}"); } return(result); } catch (Exception e) { Log.Error(e); return(result); } }
public void HeaderParsingTest() { var baseDir = TestContext.CurrentContext.TestDirectory; var testFiles = Directory.GetFiles(baseDir, "*.ird", SearchOption.AllDirectories); Assert.That(testFiles.Length, Is.GreaterThan(0)); foreach (var file in testFiles) { var bytes = File.ReadAllBytes(file); var ird = IrdParser.Parse(bytes); Assert.That(ird.FileCount, Is.GreaterThan(0)); var fileList = ird.GetFilenames(); Assert.That(fileList.Count, Is.EqualTo(ird.FileCount)); } }
public async Task <List <Ird> > DownloadAsync(string productCode, string localCachePath, CancellationToken cancellationToken) { var result = new List <Ird>(); try { // first we search local cache and try to load whatever data we can var localCacheItems = new List <string>(); try { var tmpCacheItemList = Directory.GetFiles(localCachePath, productCode + "*.ird", SearchOption.TopDirectoryOnly).Select(Path.GetFileName).ToList(); foreach (var item in tmpCacheItemList) { try { result.Add(IrdParser.Parse(File.ReadAllBytes(Path.Combine(localCachePath, item)))); localCacheItems.Add(item); } catch (Exception ex) { ApiConfig.Log.Warn(ex, "Error reading local IRD file: " + ex.Message); } } } catch (Exception e) { ApiConfig.Log.Warn(e, "Error accessing local IRD cache: " + e.Message); } ApiConfig.Log.Debug($"Found {localCacheItems.Count} cached items for {productCode}"); SearchResult searchResult = null; // then try to do IRD Library search try { searchResult = await SearchAsync(productCode, cancellationToken).ConfigureAwait(false); } catch (Exception e) { ApiConfig.Log.Error(e); } var tmpFilesToGet = searchResult?.Data.Select(i => i.Filename).Except(localCacheItems, StringComparer.InvariantCultureIgnoreCase).ToList(); if ((tmpFilesToGet?.Count ?? 0) == 0) { return(result); } // as IRD Library could return more data than we found, try to check for all the items locally var filesToDownload = new List <string>(); foreach (var item in tmpFilesToGet) { try { var localItemPath = Path.Combine(localCachePath, item); if (File.Exists(localItemPath)) { result.Add(IrdParser.Parse(File.ReadAllBytes(localItemPath))); localCacheItems.Add(item); } else { filesToDownload.Add(item); } } catch (Exception ex) { ApiConfig.Log.Warn(ex, "Error reading local IRD file: " + ex.Message); filesToDownload.Add(item); } } ApiConfig.Log.Debug($"Found {tmpFilesToGet.Count} total matches for {productCode}, {result.Count} already cached"); if (filesToDownload.Count == 0) { return(result); } // download the remaining .ird files foreach (var item in filesToDownload) { try { var resultBytes = await client.GetByteArrayAsync(GetDownloadLink(item)).ConfigureAwait(false); result.Add(IrdParser.Parse(resultBytes)); try { File.WriteAllBytes(Path.Combine(localCachePath, item), resultBytes); } catch (Exception ex) { ApiConfig.Log.Warn(ex, $"Failed to write {item} to local cache: {ex.Message}"); } } catch (Exception e) { ApiConfig.Log.Warn(e, $"Failed to download {item}: {e.Message}"); } } ApiConfig.Log.Debug($"Returning {result.Count} .ird files for {productCode}"); return(result); } catch (Exception e) { ApiConfig.Log.Error(e); return(result); } }
public async Task <HashSet <DiscKeyInfo> > EnumerateAsync(string discKeyCachePath, string ProductCode, CancellationToken cancellationToken) { ProductCode = ProductCode?.ToUpperInvariant(); var result = new HashSet <DiscKeyInfo>(); var knownFilenames = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); Log.Trace("Searching local cache for a match..."); if (Directory.Exists(discKeyCachePath)) { var matchingIrdFiles = Directory.GetFiles(discKeyCachePath, "*.ird", SearchOption.TopDirectoryOnly); foreach (var irdFile in matchingIrdFiles) { try { try { var ird = IrdParser.Parse(File.ReadAllBytes(irdFile)); result.Add(new DiscKeyInfo(ird.Data1, null, irdFile, KeyType.Ird, ird.Crc32.ToString("x8"))); knownFilenames.Add(Path.GetFileName(irdFile)); } catch (InvalidDataException) { File.Delete(irdFile); continue; } catch (Exception e) { Log.Warn(e); continue; } } catch (Exception e) { Log.Warn(e, e.Message); } } } Log.Trace("Searching IRD Library for match..."); var irdInfoList = await Client.SearchAsync(ProductCode, cancellationToken).ConfigureAwait(false); var irdList = irdInfoList?.Data?.Where( i => !knownFilenames.Contains(i.Filename) && i.Filename.Substring(0, 9).ToUpperInvariant() == ProductCode ).ToList() ?? new List <SearchResultItem>(0); if (irdList.Count == 0) { Log.Debug("No matching IRD file was found in the Library"); } else { Log.Info($"Found {irdList.Count} new match{(irdList.Count == 1 ? "" : "es")} in the IRD Library"); foreach (var irdInfo in irdList) { var ird = await Client.DownloadAsync(irdInfo, discKeyCachePath, cancellationToken).ConfigureAwait(false); result.Add(new DiscKeyInfo(ird.Data1, null, Path.Combine(discKeyCachePath, irdInfo.Filename), KeyType.Ird, ird.Crc32.ToString("x8"))); knownFilenames.Add(irdInfo.Filename); } } if (knownFilenames.Count == 0) { Log.Warn("No valid matching IRD file could be found"); Log.Info($"If you have matching IRD file, you can put it in '{discKeyCachePath}' and try dumping the disc again"); } Log.Info($"Found {result.Count} IRD files"); return(result); }