コード例 #1
0
        public static void Main(string[] args)
        {
            bool overwriteFiles     = false;
            bool lowercaseFileNames = false;
            bool verbose            = false;
            bool showHelp           = false;

            var options = new OptionSet()
            {
                {
                    "o|overwrite",
                    "overwrite files",
                    v => overwriteFiles = v != null
                },
                {
                    "l|lowercase",
                    "lowercase file names (so they are not all annoyingly uppercase!)",
                    v => lowercaseFileNames = v != null
                },
                {
                    "v|verbose",
                    "show verbose messages",
                    v => verbose = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extra;

            try
            {
                extra = 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 (extra.Count < 1 || extra.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_wad [output_path]", GetExecutableName());
                Console.WriteLine("Unpack a Duels of the Planewalkers WAD.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var inputPath  = Path.GetFullPath(extra[0]);
            var outputPath = extra.Count > 1 ? extra[1] : Path.ChangeExtension(inputPath, null) + "_unpacked";

            using (var input = File.OpenRead(inputPath))
            {
                ushort checkMagic, checkVersion;
                string checkReason;
                if (WadFile.IsBadHeader(input, out checkMagic, out checkVersion, out checkReason) == true)
                {
                    Console.WriteLine("Error: {0} (magic = 0x{1:X4}, version = 0x{2:X4})",
                                      checkReason,
                                      checkMagic,
                                      checkVersion);
                    return;
                }
                input.Seek(0, SeekOrigin.Begin);

                var wad = new WadFile();

                Console.WriteLine("Reading header...");
                wad.Deserialize(input);

                if ((wad.Flags & ~Wad.ArchiveFlags.ValidFlags) != Wad.ArchiveFlags.None)
                {
                    Console.WriteLine("Warning: unknown archive flags present! (things may blow up past this point)");
                    Console.WriteLine("  {0}", wad.Flags);
                }

                Console.WriteLine("Writing files...");

                var hasCompressedFiles = (wad.Flags & Wad.ArchiveFlags.HasCompressedFiles) ==
                                         Wad.ArchiveFlags.HasCompressedFiles;

                if (wad.Version >= 0x202)
                {
                    Directory.CreateDirectory(outputPath);
                    var headerPath = Path.Combine(outputPath, "@header.xml");
                    using (var output = File.Create(headerPath))
                    {
                        output.WriteBytes(wad.HeaderXml);
                    }
                }

                foreach (var entry in wad.AllFiles)
                {
                    var entryName = MakePath(entry);

                    if (lowercaseFileNames == true)
                    {
                        entryName = entryName.ToLowerInvariant();
                    }

                    var entryPath = Path.Combine(outputPath, entryName);

                    if (overwriteFiles == false &&
                        File.Exists(entryPath) == true)
                    {
                        continue;
                    }

                    if (verbose == true)
                    {
                        Console.WriteLine(">> {0}", entryName);
                    }

                    var entryDirectory = Path.GetDirectoryName(entryPath);
                    if (entryDirectory != null)
                    {
                        Directory.CreateDirectory(entryDirectory);
                    }

                    input.Seek(wad.DataOffsets[entry.OffsetIndex], SeekOrigin.Begin);

                    using (var output = File.Create(entryPath))
                    {
                        if (hasCompressedFiles == false)
                        {
                            output.WriteFromStream(input, entry.Size);
                        }
                        else
                        {
                            int length = input.ReadValueS32(wad.Endian);

                            if (length == -1)
                            {
                                // no compression
                                output.WriteFromStream(input, entry.Size - 4);
                            }
                            else
                            {
                                using (var temp = input.ReadToMemoryStream(entry.Size - 4))
                                {
                                    var zlib = new InflaterInputStream(temp);
                                    output.WriteFromStream(zlib, length);
                                }
                            }
                        }
                    }
                }

                Console.WriteLine("Done!");
            }
        }