private void SetProject(Setup.Project project) { if (project != null) { try { project.Load(); this.openDialog.InitialDirectory = project.InstallPath; this.saveKnownFileListDialog.InitialDirectory = project.ListsPath; } catch (Exception e) { MessageBox.Show( "There was an error while loading project data." + Environment.NewLine + Environment.NewLine + e.ToString() + Environment.NewLine + Environment.NewLine + "(You can press Ctrl+C to copy the contents of this dialog)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); project = null; } } if (project != this.Manager.ActiveProject) { this.Manager.ActiveProject = project; } this.projectComboBox.SelectedItem = project; }
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(); } } } } } } } } }