示例#1
0
        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);
        }
示例#2
0
        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));
            }
        }
示例#3
0
        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);
                    }
                }
            }
        }
示例#4
0
        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();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }