private void OnOpen(object sender, EventArgs e) { if (this.openFileDialog.ShowDialog() != DialogResult.OK) { return; } string indexName = this.openFileDialog.FileName; if (indexName.EndsWith("_dir.vpk") == false) { MessageBox.Show(String.Format("{0} does not end in _dir.vpk.", Path.GetFileName(indexName)), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.savePathDialog.SelectedPath = Path.GetDirectoryName(indexName); if (this.savePathDialog.ShowDialog() != DialogResult.OK) { return; } string basePath = indexName.Substring(0, indexName.Length - 8); string savePath = this.savePathDialog.SelectedPath; PackageFile package = new PackageFile(); Stream indexStream = File.OpenRead(indexName); package.Deserialize(indexStream); indexStream.Close(); this.progressBar.Minimum = 0; this.progressBar.Maximum = package.Entries.Count; this.progressBar.Value = 0; ExtractThreadInfo info = new ExtractThreadInfo(); info.BasePath = basePath; info.SavePath = savePath; info.Package = package; this.ExtractThread = new Thread(new ParameterizedThreadStart(ExtractFiles)); this.ExtractThread.Start(info); this.EnableButtons(false); }
public override ArcFile TryOpen(ArcView file) { uint index_size = file.View.ReadUInt32(0); if (index_size <= 12 || index_size >= file.MaxOffset) { return(null); } if (file.View.ReadInt32(5) != 1 || file.View.ReadInt32(9) != -1) { return(null); } using (var hstream = file.CreateStream(4, index_size)) { var pf = new PackageFile(); var index = pf.Deserialize(hstream); if (null == index) { return(null); } string type = ""; if (index is PFAudioHeaders) { type = "audio"; } else if (index is PFImageHeaders) { type = "image"; } uint data_offset = index_size + 4; var dir = index.headers.Select(h => new PackedEntry { Name = h.FileName, Type = type, Offset = h.readStartBytePos + data_offset, Size = (uint)h.ByteLength } as Entry).ToList(); return(new ArcFile(file, this, dir)); } }
public static void Main(string[] args) { bool showHelp = false; OptionSet options = new OptionSet() { { "h|help", "show this message and exit", v => showHelp = v != null }, }; List <string> extras; try { extras = options.Parse(args); } catch (OptionException e) { Console.Write("{0}: ", GetExecutableName()); Console.WriteLine(e.Message); Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName()); return; } if (extras.Count != 0 || showHelp == true) { Console.WriteLine("Usage: {0} [OPTIONS]+", GetExecutableName()); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return; } Console.WriteLine("Loading project..."); var manager = Setup.Manager.Load(); if (manager.ActiveProject == null) { Console.WriteLine("Nothing to do: no active project loaded."); return; } var project = manager.ActiveProject; var installPath = project.InstallPath; var listsPath = project.ListsPath; if (installPath == null) { Console.WriteLine("Could not detect install path."); return; } else if (listsPath == null) { Console.WriteLine("Could not detect lists path."); return; } Console.WriteLine("Searching for packages..."); var inputPaths = new List <string>(); inputPaths.AddRange(Directory.GetFiles(installPath, "*.sdpk2", SearchOption.AllDirectories)); var outputPaths = new List <string>(); Console.WriteLine("Processing..."); foreach (var inputpath in inputPaths) { var outputPath = GetListPath(installPath, inputpath); if (outputPath == null) { throw new InvalidOperationException(); } Console.WriteLine(outputPath); outputPath = Path.Combine(listsPath, outputPath); if (outputPaths.Contains(outputPath) == true) { throw new InvalidOperationException(); } outputPaths.Add(outputPath); var pkg = new PackageFile(); using (var input = File.OpenRead(inputpath)) { pkg.Deserialize(input); } var localBreakdown = new Breakdown(); var names = new List <string>(); foreach (var entry in pkg.Entries) { var name = project.GetFileName(entry.NameHash); if (name != null) { if (names.Contains(name) == false) { names.Add(name); localBreakdown.Known++; } } localBreakdown.Total++; } names.Sort(); Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); using (var output = new StreamWriter(outputPath)) { output.WriteLine("; {0}", localBreakdown); foreach (string name in names) { output.WriteLine(name); } } } }
public static void Main(string[] args) { bool showHelp = false; bool extractUnknowns = true; bool overwriteFiles = false; OptionSet options = new OptionSet() { { "o|overwrite", "overwrite existing files", v => overwriteFiles = v != null }, { "u|no-unknowns", "don't extract unknown files", v => extractUnknowns = v == null }, { "h|help", "show this message and exit", v => showHelp = v != null }, }; List <string> extras; try { extras = options.Parse(args); } catch (OptionException e) { Console.Write("{0}: ", GetExecutableName()); Console.WriteLine(e.Message); Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName()); return; } if (extras.Count < 1 || extras.Count > 2 || showHelp == true) { Console.WriteLine("Usage: {0} [OPTIONS]+ input_sdpk2 [output_dir]", GetExecutableName()); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); return; } string inputPath = extras[0]; string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null); var manager = Setup.Manager.Load(); if (manager.ActiveProject != null) { manager.ActiveProject.Load(); } else { Console.WriteLine("Warning: no active project loaded."); } Setup.Project project = manager.ActiveProject; using (var input = File.Open(inputPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { var pkg = new PackageFile(); pkg.Deserialize(input); if (pkg.CompressionFormat != FileFormats.Package.CompressionFormat.ZLib) { Console.WriteLine("Can't extract non-zlib packages."); } else { long current = 1; long total = pkg.Entries.Count; foreach (var entry in pkg.Entries) { string name = null; bool isUnknown = false; if (project != null) { name = project.GetFileName(entry.NameHash); } if (name == null) { if (extractUnknowns == false) { continue; } isUnknown = true; string extension; // detect type { var guess = new byte[16]; int read = 0; if (entry.UncompressedSize > 0) { input.Seek(entry.Offset, SeekOrigin.Begin); var uncompressedBlockSize = (uint)Math.Min(pkg.DataBlockSize, entry.UncompressedSize); var compressedBlockSize = pkg.CompressedBlockSizes[entry.CompressedBlockSizeIndex]; if (compressedBlockSize > uncompressedBlockSize) { throw new InvalidOperationException(); } if (compressedBlockSize == 0 || entry.UncompressedSize == compressedBlockSize) { if (compressedBlockSize == 0) { compressedBlockSize = pkg.DataBlockSize; } read = input.Read(guess, 0, (int)Math.Min(uncompressedBlockSize, guess.Length)); } else { var compressedBlock = input.ReadToMemoryStream(compressedBlockSize); var uncompressedBlock = new InflaterInputStream(compressedBlock); read = uncompressedBlock.Read(guess, 0, (int)Math.Min(uncompressedBlockSize, guess.Length)); } } extension = FileExtensions.Detect(guess, read); } name = entry.NameHash.ToString(); name = Path.ChangeExtension(name, "." + extension); name = Path.Combine(extension, name); name = Path.Combine("__UNKNOWN", name); } else { name = name.Replace("/", "\\"); if (name.StartsWith("\\") == true) { name = name.Substring(1); } } Console.WriteLine("[{0}/{1}] {2}", current, total, name); current++; var entryPath = Path.Combine(outputPath, name); Directory.CreateDirectory(Path.GetDirectoryName(entryPath)); if (overwriteFiles == false && File.Exists(entryPath) == true) { continue; } using (var output = File.Create(entryPath)) { if (entry.UncompressedSize > 0) { input.Seek(entry.Offset, SeekOrigin.Begin); var index = entry.CompressedBlockSizeIndex; var uncompressedSize = entry.UncompressedSize; while (uncompressedSize > 0) { var uncompressedBlockSize = Math.Min(pkg.DataBlockSize, uncompressedSize); var compressedBlockSize = pkg.CompressedBlockSizes[index++]; if (compressedBlockSize > uncompressedBlockSize) { throw new InvalidOperationException(); } if (compressedBlockSize == 0 || uncompressedSize == compressedBlockSize) { if (compressedBlockSize == 0) { compressedBlockSize = pkg.DataBlockSize; } output.WriteFromStream(input, compressedBlockSize); if (uncompressedBlockSize != compressedBlockSize) { throw new InvalidOperationException(); } uncompressedSize -= compressedBlockSize; } else { var compressedBlock = input.ReadToMemoryStream(compressedBlockSize); var uncompressedBlock = new InflaterInputStream(compressedBlock); output.WriteFromStream(uncompressedBlock, uncompressedBlockSize); uncompressedSize -= uncompressedBlockSize; // why would there be junk data...? :argh: if (compressedBlock.Position != compressedBlock.Length) { //throw new InvalidOperationException(); } } } } } } } } }