Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
 public void TestValidateMultipleBins()
 {
     foreach (var archiveName in QuickTestArchives)
     {
         using var archive = new PackfileReader(Path.Combine(GameDataPath, archiveName));
         archive.Validate();
     }
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
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()));
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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());
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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"));
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
        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);
        }
Esempio n. 15
0
 public void TestValidateSingleBin()
 {
     using var archive = new PackfileReader(Path.Combine(GameDataPath, GameRootArchive));
     archive.Validate();
 }