Пример #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);
        }
Пример #2
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()));
        }
Пример #3
0
        private void ExtractWithPrefetch(List <string> prefetch, Dictionary <ulong, PackfileReader> files, bool streams = false)
        {
            CheckDirectory(OutputDir);

            Console.WriteLine($"Starting extracting {prefetch.Count} files");
            using (var progressBar = new ProgressBar())
            {
                progressValue = 0;
                int lastProgress = 0;
                progressBar.Report(0);
                var tasks = new ParallelTasks <string>(
                    Environment.ProcessorCount, file =>
                {
                    void extractFromPack(string fileName, bool stream)
                    {
                        var hash   = Packfile.GetHashForPath(fileName, stream);
                        var output = Path.Combine(OutputDir, fileName);
                        if (files.TryGetValue(hash, out var pack))
                        {
                            CheckDirectory(Path.GetDirectoryName(output));
                            pack.ExtractFile(hash, output, true);
                        }
                    }

                    extractFromPack(file + ".core", false);
                    if (streams)
                    {
                        extractFromPack(file + ".core.stream", true);
                    }

                    Interlocked.Increment(ref progressValue);
                    var val = (int)((progressValue * 1.0 / prefetch.Count) * 100);
                    if (val > lastProgress)
                    {
                        lastProgress = (int)val;
                        progressBar.Report(val / 100.0);
                    }
                });

                tasks.Start();
                foreach (var x in prefetch.Where(x => !Ignored.Any(x.StartsWith)))
                {
                    tasks.AddItem(x);
                }
                tasks.WaitForComplete();
            }
            Console.WriteLine("");
            Console.WriteLine("Extraction complete");
        }
Пример #4
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());
        }
Пример #5
0
        private bool TryExtractFile(string path, Stream stream, string file)
        {
            if (!File.Exists(path))
            {
                throw new HzdException($"Unable to extract file, source path not found: {path}");
            }

            var pack = LoadPack(path, false);
            var hash = Packfile.GetHashForPath(file);

            if (pack.FileEntries.All(x => x.PathHash != hash))
            {
                return(false);
            }

            pack.ExtractFile(hash, stream);
            return(true);
        }
Пример #6
0
        private bool TryExtractFileFromDir(string dir, HashSet <string> fileFilter, Stream stream, string file)
        {
            if (!Directory.Exists(dir))
            {
                throw new HzdException($"Unable to extract file, directory not found: {dir}");
            }

            var packs   = GetPackFiles(dir, fileFilter, PackExt);
            var fileMap = BuildFileMap(packs, true);

            var hash = Packfile.GetHashForPath(file);

            if (!fileMap.TryGetValue(hash, out var packFile))
            {
                return(false);
            }

            var pack = LoadPack(packFile, true);

            pack.ExtractFile(hash, stream);

            return(true);
        }
Пример #7
0
        private void ExtractDir(string path, bool game, bool streams)
        {
            if (!Directory.Exists(path))
            {
                Console.WriteLine("Error, directory not found: " + path);
                return;
            }

            var prefetchHash = Packfile.GetHashForPath(Prefetch);

            var packs = game ? GetGameFiles(path) : Directory.GetFiles(path);
            var files = BuildPackMap(packs);

            if (!files.ContainsKey(prefetchHash))
            {
                Console.WriteLine("Prefetch not found, directory cannot be extracted");
                return;
            }

            var prefetch = LoadPrefetch(files[prefetchHash]);

            ExtractWithPrefetch(prefetch, files, streams);
        }