private void ExtractFile(string path) { var pack = new PackfileReader(path); var prefetchHash = Packfile.GetHashForPath(Prefetch); var hasPrefetch = pack.FileEntries.Any(x => x.PathHash == prefetchHash); if (!hasPrefetch) { if (!Confirm("Prefetch not found, file names cannot be extracted.")) { return; } CheckDirectory(OutputDir); Console.WriteLine($"Starting extracting {pack.FileEntries.Count} files"); var tasks = new ParallelTasks <(ulong Hash, string Output)>( Environment.ProcessorCount, data => pack.ExtractFile(data.Hash, data.Output)); tasks.Start(); pack.FileEntries.ForEach(x => tasks.AddItem((x.PathHash, Path.Combine(OutputDir, $"{x.PathHash}.core")))); tasks.WaitForComplete(); Console.WriteLine(""); Console.WriteLine("Extraction complete"); return; } var prefetch = LoadPrefetch(pack); var files = pack.FileEntries.ToDictionary(x => x.PathHash, x => pack); ExtractWithPrefetch(prefetch, files); }
public static void DecodeAllArchivesTest() { string basePath = GameDataPath; var files = Directory.GetFiles(basePath, "*.bin", SearchOption.AllDirectories); foreach (string file in files) { Console.WriteLine(file); var indexFile = new PackfileIndex().FromFile(Path.ChangeExtension(file, ".idx")); var archive = new PackfileReader(file); foreach (var entry in archive.FileEntries) { if (!indexFile.ResolvePathByHash(entry.PathHash, out string fn)) { throw new Exception(); } var physicalPath = Path.Combine(basePath, "extracted", fn); var physicalDir = Path.GetDirectoryName(physicalPath); Directory.CreateDirectory(physicalDir); archive.ExtractFile(fn, physicalPath); } } }
public void TestValidateMultipleBins() { foreach (var archiveName in QuickTestArchives) { using var archive = new PackfileReader(Path.Combine(GameDataPath, archiveName)); archive.Validate(); } }
public void TestExtractSingleFileToStream() { using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive)); var testStream = new MemoryStream(); archive.ExtractFile("prefetch/fullgame.prefetch.core", testStream); Assert.IsTrue(testStream.Length > 0); }
public void TestFileExistsByPathId() { using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive)); Assert.IsTrue(Packfile.GetHashForPath(Packfile.SanitizePath("prefetch/fullgame.prefetch")) == 0x2FFF5AF65CD64C0A); Assert.IsTrue(archive.ContainsFile(0x2FFF5AF65CD64C0A)); Assert.ThrowsException <FileNotFoundException>(() => archive.ExtractFile(0xDEADC0DEDEADBEEF, new MemoryStream())); }
public void TestExtractSingleFile() { using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive)); var tempPath = Path.Combine(Path.GetTempPath(), $"{nameof(TestExtractSingleFile)}_extracted.core"); if (File.Exists(tempPath)) { File.Delete(tempPath); } archive.ExtractFile("prefetch/fullgame.prefetch.core", tempPath); Assert.IsTrue(File.Exists(tempPath)); File.Delete(tempPath); }
private List <string> LoadPrefetch(PackfileReader pack) { var prefetchHash = Packfile.GetHashForPath(Prefetch); using var ms = new MemoryStream(); pack.ExtractFile(prefetchHash, ms); ms.Position = 0; using var br = new BinaryReader(ms, Encoding.UTF8, true); var core = CoreBinary.FromData(br, true); return((core.First(x => x is PrefetchList) as PrefetchList).Files .Select(x => x.Path?.Value) .ToList()); }
private PackfileReader LoadPack(string path, bool useCache) { if (!useCache) { return(new PackfileReader(path)); } path = Path.GetFullPath(path); if (!_packCache.TryGetValue(path, out var pack)) { pack = new PackfileReader(path); _packCache.TryAdd(path, pack); } return(pack); }
public void TestFileExists() { using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive)); Assert.IsTrue(archive.ContainsFile("prefetch/fullgame.prefetch.core")); Assert.IsTrue(archive.ContainsFile(Packfile.SanitizePath("prefetch/fullgame.prefetch"))); Assert.IsTrue(archive.ContainsFile(Packfile.SanitizePath("prefetch\\fullgame.prefetch.core"))); #if false Assert.IsTrue(archive.ContainsFile("models/weapons/heavy_machinegun/model/model.core.stream"));// Need to find files present in Initial.bin Assert.IsTrue(archive.ContainsFile("sounds/effects/world/weather/habitats/fields/weather_fields.soundbank.core.stream")); #endif Assert.IsFalse(archive.ContainsFile("PREFETCH/fullgame.prefetch.core")); Assert.IsFalse(archive.ContainsFile("prefetch\\FULLGAME.prefetch.core")); Assert.IsFalse(archive.ContainsFile("some/made/up/path/here.core")); }
private Dictionary <ulong, PackfileReader> BuildPackMap(string[] packFiles) { var files = new Dictionary <ulong, PackfileReader>(); foreach (var packFile in packFiles) { var pack = new PackfileReader(packFile); for (int i = 0; i < pack.FileEntries.Count; i++) { var hash = pack.FileEntries[i].PathHash; files[hash] = pack; } } return(files); }
public void TestPackAndUnpackTrivial() { // Generate a couple useless files to pack var tempPath = Path.GetTempPath(); var tempFiles = new List <(string Path, string Text, string CoreName)>(); for (int i = 0; i < 15; i++) { var coreName = $"{nameof(TestPackAndUnpackTrivial)}_input_file{i}.core"; var path = Path.Combine(tempPath, coreName); var text = $"{i} Here's my testing file with some data! {i}\r\n"; File.WriteAllText(path, text); tempFiles.Add((path, text, coreName)); } // Write out compressed bin var packedArchivePath = Path.Combine(tempPath, $"{nameof(TestPackAndUnpackTrivial)}_packed_archive.bin"); using (var writeArchive = new PackfileWriter(packedArchivePath, false, FileMode.Create)) writeArchive.BuildFromFileList(tempPath, tempFiles.Select(x => x.CoreName)); // Open it back up and validate its contents using (var readArchive = new PackfileReader(packedArchivePath)) { readArchive.Validate(); foreach (var file in tempFiles) { Assert.IsTrue(readArchive.ContainsFile(file.CoreName)); readArchive.ExtractFile(file.CoreName, file.Path, FileMode.Create); Assert.IsTrue(File.ReadAllText(file.Path).Equals(file.Text)); File.Delete(file.Path); } } File.Delete(packedArchivePath); }
public void TestPackAndUnpack() { // Gather 500 random files to throw into a bin var archivePath = Path.Combine(Path.GetTempPath(), $"{nameof(TestPackAndUnpack)}_packed_archive.bin"); var targetDir = GameDataPathExtracted; if (!targetDir.EndsWith('\\')) { targetDir += "\\"; } var filesToCombine = Directory .EnumerateFiles(targetDir, "*.core", SearchOption.AllDirectories) .Take(500) .Select(f => f.Substring(targetDir.Length)) .ToArray(); using (var writeArchive = new PackfileWriter(archivePath, false, FileMode.Create)) writeArchive.BuildFromFileList(targetDir, filesToCombine); // Re-extract all of the contained files into memory using (var readArchive = new PackfileReader(archivePath)) { readArchive.Validate(); using var tempMS = new MemoryStream(); foreach (string file in filesToCombine) { tempMS.Position = 0; tempMS.SetLength(0); readArchive.ExtractFile(file, tempMS); var tempFilePath = Path.Combine(targetDir, file); Assert.IsTrue(tempMS.Length == new FileInfo(tempFilePath).Length); } } File.Delete(archivePath); }
public static void PackArchivesQuickTest() { string archivePath = Path.Combine(GameDataPath, "test_packed_archive.tmp"); var testArchive = new PackfileWriter(archivePath, false, true); testArchive.BuildFromFileList(GameDataPathExtracted, QuickTestFiles); var testArchive2 = new PackfileReader(archivePath); testArchive2.Validate(); // Re-extract all of the contained files foreach (string file in QuickTestFiles) { string tempFilePath = Path.Combine(GameDataPathExtracted, $"{file}.tmp"); testArchive2.ExtractFile(file, tempFilePath, true); File.Delete(tempFilePath); } File.Delete(archivePath); }
public static void PackArchivesTest() { string archivePath = Path.Combine(GameDataPath, "test_packed_archive.tmp"); string targetDir = GameDataPathExtracted; if (!targetDir.EndsWith('\\')) { targetDir += "\\"; } var filesToCombine = Directory .EnumerateFiles(targetDir, "*.core", SearchOption.AllDirectories) .Take(500) .Select(f => f.Substring(targetDir.Length)) .ToArray(); var testArchive = new PackfileWriter(archivePath, false, true); testArchive.BuildFromFileList(targetDir, filesToCombine); var testArchive2 = new PackfileReader(archivePath); testArchive2.Validate(); // Re-extract all of the contained files foreach (string file in filesToCombine) { string tempFilePath = Path.Combine(targetDir, $"{file}.tmp"); testArchive2.ExtractFile(file, tempFilePath, true); File.Delete(tempFilePath); } File.Delete(archivePath); }
public void TestValidateSingleBin() { using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive)); archive.Validate(); }