Exemple #1
0
        private static void Main(string[] args)
        {
            bool showHelp = false;
            bool verbose  = false;

            var options = new OptionSet()
            {
                { "v|verbose", "be verbose", v => verbose = 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_fc3map [output_fc3map]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string inputPath  = extras[0];
            string outputPath = extras.Count > 1
                                    ? extras[1]
                                    : Path.ChangeExtension(Path.ChangeExtension(inputPath, null) + "_stripped",
                                                           Path.GetExtension(inputPath));

            var map = new CustomMapGameFile();

            using (var input = File.OpenRead(inputPath))
            {
                map.Deserialize(input);
            }

            var wantedFileNamesToStrip = new[]
            {
                @"ige\collection.mask",
                @"ige\heightmap.raw",
                @"ige\holemap.raw",
                @"ige\map.xml",
                @"ige\texture.mask",
            };
            var wantedFileHashesToStrip = wantedFileNamesToStrip
                                          .Select(fn => Dunia2.FileFormats.CRC64.Hash(fn))
                                          .ToArray();

            var strippedMap = (CustomMapGameFile)map.Clone();

            var fat = new Dunia2.FileFormats.BigFile();

            using (var input = map.Archive.Header.Unpack())
            {
                fat.Deserialize(input);
            }

            var fileHashesToStrip = fat.Entries
                                    .Select(e => e.NameHash)
                                    .Intersect(wantedFileHashesToStrip)
                                    .ToArray();

            if (verbose == true)
            {
                Console.WriteLine("Stripping {0} files...", fileHashesToStrip.Length);
            }

            if (fileHashesToStrip.Length > 0)
            {
                var strippedFat = new Dunia2.FileFormats.BigFile
                {
                    Version   = fat.Version,
                    Platform  = fat.Platform,
                    Unknown74 = fat.Unknown74
                };

                using (var input = map.Archive.Data.Unpack())
                    using (var output = new MemoryStream())
                    {
                        var strippedEntries = new List <Dunia2.FileFormats.Big.Entry>();

                        foreach (var entry in fat.Entries.Where(e => fileHashesToStrip.Contains(e.NameHash) == false))
                        {
                            var rebuiltEntry = new Dunia2.FileFormats.Big.Entry
                            {
                                NameHash          = entry.NameHash,
                                UncompressedSize  = entry.UncompressedSize,
                                CompressedSize    = entry.CompressedSize,
                                Offset            = output.Position,
                                CompressionScheme = entry.CompressionScheme
                            };

                            input.Seek(entry.Offset, SeekOrigin.Begin);
                            output.WriteFromStream(input, entry.CompressedSize);
                            output.Seek(output.Position.Align(16), SeekOrigin.Begin);

                            strippedEntries.Add(rebuiltEntry);
                        }

                        strippedFat.Entries.AddRange(strippedEntries.OrderBy(e => e.NameHash));

                        output.Position          = 0;
                        strippedMap.Archive.Data = CustomMap.CompressedData.Pack(output);
                    }

                using (var output = new MemoryStream())
                {
                    strippedFat.Serialize(output);
                    output.Position            = 0;
                    strippedMap.Archive.Header = CustomMap.CompressedData.Pack(output);
                }

                using (var output = new MemoryStream())
                {
                    var settings = new XmlWriterSettings();
                    settings.Indent             = true;
                    settings.OmitXmlDeclaration = true;
                    settings.IndentChars        = "\t";
                    settings.Encoding           = Encoding.ASCII;

                    using (var writer = XmlWriter.Create(output, settings))
                    {
                        writer.WriteStartDocument();
                        writer.WriteStartElement("FatInfo");

                        foreach (var entry in fat.Entries.OrderBy(e => e.NameHash))
                        {
                            writer.WriteStartElement("File");
                            writer.WriteAttributeString("Path",
                                                        entry.NameHash.ToString(CultureInfo.InvariantCulture));
                            writer.WriteAttributeString("Crc", entry.NameHash.ToString(CultureInfo.InvariantCulture));
                            writer.WriteAttributeString("CrcHex",
                                                        entry.NameHash.ToString("x16", CultureInfo.InvariantCulture));
                            writer.WriteAttributeString("FileTime", "0");
                            writer.WriteAttributeString("SeekPos",
                                                        entry.Offset.ToString(CultureInfo.InvariantCulture));
                            writer.WriteEndElement();
                        }

                        writer.WriteEndElement();
                        writer.WriteEndDocument();
                    }

                    output.Position = 0;
                    strippedMap.Archive.Descriptor = CustomMap.CompressedData.Pack(output);
                }
            }

            using (var output = File.Create(outputPath))
            {
                strippedMap.Serialize(output);
            }
        }
Exemple #2
0
        public static void Main(string[] args)
        {
            bool showHelp = false;
            bool useDescriptorFromFile = false;
            bool verbose = false;

            var options = new OptionSet()
            {
                { "v|verbose", "be verbose", v => verbose = v != null },
                { "fd|use-descriptor-from-file", v => useDescriptorFromFile = 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_dir [output_fc3map]", 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) + ".fc3map";

            MapConfiguration config;

            using (var input = File.OpenRead(Path.Combine(inputPath, "config.json")))
                using (var streamReader = new StreamReader(input))
                    using (var jsonReader = new JsonTextReader(streamReader))
                    {
                        var serializer = new JsonSerializer();
                        config = serializer.Deserialize <MapConfiguration>(jsonReader);
                    }

            var map = new CustomMapGameFile()
            {
                Endian = config.Endian,
            };

            map.Header = new CustomMapGameFileHeader()
            {
                Unknown2 = config.Header.Unknown2,
                Unknown3 = config.Header.Unknown3,
                Unknown4 = config.Header.Unknown4,
                Unknown5 = config.Header.Unknown5,
                Creator  = config.Header.Creator,
                Unknown7 = config.Header.Unknown7,
                Author   = config.Header.Author,
                Name     = config.Header.Name,
                MapId    = new CustomMap.MapId()
                {
                    Guid     = config.Header.MapId.Guid,
                    Unknown2 = config.Header.MapId.Unknown2,
                    Unknown3 = config.Header.MapId.Unknown3,
                },
                VersionId    = config.Header.VersionId,
                TimeModified = config.Header.TimeModified,
                TimeCreated  = config.Header.TimeCreated,
                MapSize      = config.Header.MapSize,
                PlayerRange  = config.Header.PlayerRange,
                Unknown16    = config.Header.Unknown16,
                Unknown17    = config.Header.Unknown17,
            };

            if (string.IsNullOrEmpty(config.SnapshotPath) == true)
            {
                map.Snapshot = new Snapshot();
            }
            else
            {
                using (var input = File.OpenRead(Path.Combine(inputPath, config.SnapshotPath)))
                {
                    map.Snapshot = ImportSnapshot(input, map.Endian);
                }
            }

            if (string.IsNullOrEmpty(config.ExtraSnapshotPath) == true)
            {
                map.ExtraSnapshot = new Snapshot();
            }
            else
            {
                using (var input = File.OpenRead(Path.Combine(inputPath, config.ExtraSnapshotPath)))
                {
                    map.ExtraSnapshot = ImportSnapshot(input, map.Endian);
                }
            }

            if (config.Data != null)
            {
                map.Data.Unknown1 = config.Data.Unknown1;

                if (string.IsNullOrEmpty(config.Data.Unknown2Path) == true)
                {
                    map.Data.Unknown2 = new byte[0];
                }
                else
                {
                    map.Data.Unknown2 = File.ReadAllBytes(Path.Combine(inputPath, config.Data.Unknown2Path));
                }
            }

            if (string.IsNullOrEmpty(config.FilesystemHeaderPath) == false)
            {
                using (var input = File.OpenRead(Path.Combine(inputPath, config.FilesystemHeaderPath)))
                {
                    map.Archive.Header = CustomMap.CompressedData.Pack(input);
                }
            }

            if (string.IsNullOrEmpty(config.FilesystemDataPath) == false)
            {
                using (var input = File.OpenRead(Path.Combine(inputPath, config.FilesystemDataPath)))
                {
                    map.Archive.Data = CustomMap.CompressedData.Pack(input);
                }
            }

            if (useDescriptorFromFile == true)
            {
                if (string.IsNullOrEmpty(config.FilesystemDescriptorPath) == false)
                {
                    using (var input = File.OpenRead(Path.Combine(inputPath, config.FilesystemDescriptorPath)))
                    {
                        map.Archive.Descriptor = CustomMap.CompressedData.Pack(input);
                    }
                }
            }
            else
            {
                using (var input = File.OpenRead(Path.Combine(inputPath, config.FilesystemHeaderPath)))
                {
                    var fat = new Dunia2.FileFormats.BigFile();
                    fat.Deserialize(input);

                    using (var output = new MemoryStream())
                    {
                        var settings = new XmlWriterSettings();
                        settings.Indent             = true;
                        settings.OmitXmlDeclaration = true;
                        settings.IndentChars        = "\t";
                        settings.Encoding           = Encoding.ASCII;

                        using (var writer = XmlWriter.Create(output, settings))
                        {
                            writer.WriteStartDocument();
                            writer.WriteStartElement("FatInfo");

                            foreach (var entry in fat.Entries.OrderBy(e => e.NameHash))
                            {
                                writer.WriteStartElement("File");
                                writer.WriteAttributeString("Path",
                                                            entry.NameHash.ToString(CultureInfo.InvariantCulture));
                                writer.WriteAttributeString("Crc", entry.NameHash.ToString(CultureInfo.InvariantCulture));
                                writer.WriteAttributeString("CrcHex",
                                                            entry.NameHash.ToString("x16", CultureInfo.InvariantCulture));
                                writer.WriteAttributeString("FileTime", "0");
                                writer.WriteAttributeString("SeekPos",
                                                            entry.Offset.ToString(CultureInfo.InvariantCulture));
                                writer.WriteEndElement();
                            }

                            writer.WriteEndElement();
                            writer.WriteEndDocument();
                        }

                        output.Position        = 0;
                        map.Archive.Descriptor = CustomMap.CompressedData.Pack(output);
                    }
                }
            }

            using (var output = File.Create(outputPath))
            {
                map.Serialize(output);
            }
        }