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 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())); }
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"); }
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 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); }
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); }
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); }