Beispiel #1
0
        public static Dictionary <string, string> DecompileToMemory(Stream ms)
        {
            Dictionary <string, string> fileMapping = new Dictionary <string, string>();
            var coal = new CoalescedFileXml();

            coal.Deserialize(ms);

            XDocument xDoc;
            XElement  rootElement;


            foreach (var file in coal.Files)
            {
                var fileId = Path.GetFileNameWithoutExtension(file.Name);
                fileId = ProperNames.FirstOrDefault(s => s.Equals(fileId, StringComparison.InvariantCultureIgnoreCase));

                xDoc = new XDocument();

                rootElement = new XElement("CoalesceAsset");
                rootElement.SetAttributeValue("id", fileId);
                rootElement.SetAttributeValue("name", Path.GetFileName(file.Name));
                rootElement.SetAttributeValue("source", file.Name);

                var sectionsElement = new XElement("Sections");

                foreach (var section in file.Sections)
                {
                    var sectionElement = new XElement("Section");
                    sectionElement.SetAttributeValue("name", section.Key);

                    //
                    //var classes = Namespace.FromStrings(section.Value.Keys);

                    //

                    foreach (var property in section.Value)
                    {
                        var propertyElement = new XElement("Property");
                        propertyElement.SetAttributeValue("name", property.Key);

                        if (property.Value.Count > 1)
                        {
                            foreach (var value in property.Value)
                            {
                                var valueElement  = new XElement("Value");
                                var propertyValue = value.Value;
                                valueElement.SetAttributeValue("type", value.Type);

                                if (!string.IsNullOrEmpty(propertyValue))
                                {
                                    propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                }

                                valueElement.SetValue(propertyValue ?? "null");

                                propertyElement.Add(valueElement);
                            }
                        }
                        else
                        {
                            switch (property.Value.Count)
                            {
                            case 1:
                            {
                                propertyElement.SetAttributeValue("type", property.Value[0].Type);
                                var propertyValue = property.Value[0].Value;

                                if (!string.IsNullOrEmpty(propertyValue))
                                {
                                    propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                }

                                propertyElement.SetValue(propertyValue ?? "null");
                                break;
                            }

                            case 0:
                            {
                                propertyElement.SetAttributeValue("type", CoalesceProperty.DefaultValueType);
                                propertyElement.SetValue("");
                                break;
                            }
                            }
                        }

                        sectionElement.Add(propertyElement);
                    }

                    sectionsElement.Add(sectionElement);
                }

                rootElement.Add(sectionsElement);
                xDoc.Add(rootElement);

                //
                using (StringWriter writer = new Utf8StringWriter())
                {
                    // Build Xml with xw.
                    //xw.IndentChar = '\t';
                    //xw.Indentation = 1;
                    //xw.Formatting = Formatting.Indented;

                    //xDoc.Save(xw);

                    ;
                    xDoc.Save(writer, SaveOptions.None);
                    fileMapping[$"{fileId}.xml"] = writer.ToString();
                }

                //

                //xDoc.Save(iniPath, SaveOptions.None);
            }
            return(fileMapping);
        }
Beispiel #2
0
        public static void Main(string[] args)
        {
            /*var helpWriter = new StringWriter();
             * var parser = new Parser(
             *      settings =>
             *      {
             *              settings.EnableDashDash = true;
             *              settings.HelpWriter = helpWriter;
             *      });
             *
             * var result = parser.ParseArguments<ProgramOptions>(args);
             * var options = result.Value;*/
            var parser = ProgramOptions.Create(args);
            var result = parser.Parse(args);

            if (result.HasErrors)
            {
                parser.HelpOption.ShowHelp(parser.Options);

                return;
            }

            var options = parser.Object;

            if (options.CoalesceMode == ProgramCoalesceMode.Unknown && !options.Source.IsNullOrWhiteSpace())
            {
                if (File.Exists(options.Source))
                {
                    if (options.Source.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
                    {
                        options.CoalesceMode = ProgramCoalesceMode.ToBin;
                    }
                    else if (options.Source.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
                    {
                        options.CoalesceMode = ProgramCoalesceMode.ToXml;
                    }
                }
            }

            if (options.CoalesceMode == ProgramCoalesceMode.ToXml)
            {
                var sourcePath      = options.Source;
                var destinationPath = options.Destination;

                if (destinationPath.IsNullOrWhiteSpace())
                {
                    destinationPath = Path.ChangeExtension(sourcePath, null);
                }

                if (!Path.IsPathRooted(destinationPath))
                {
                    destinationPath = Path.Combine(GetExePath(), destinationPath);
                }

                if (!File.Exists(sourcePath))
                {
                    return;
                }

                BuildSettings.Current.SourcePath      = sourcePath;
                BuildSettings.Current.SourceDirectory = Path.GetDirectoryName(sourcePath);
                BuildSettings.Current.OutputPath      = destinationPath;
                BuildSettings.Current.OutputDirectory = Path.GetDirectoryName(destinationPath);

                using (var input = File.OpenRead(sourcePath))
                {
                    var coal = new CoalescedFileXml();
                    coal.Deserialize(input);

                    var inputId   = Path.GetFileNameWithoutExtension(sourcePath) ?? "Coalesced";
                    var inputName = Path.GetFileName(sourcePath) ?? "Coalesced.bin";

                    var setup =
                        new Setup
                    {
                        Endian  = coal.ByteOrder,
                        Version = coal.Version
                    };

                    XDocument xDoc;
                    XElement  rootElement;

                    if (!Directory.Exists(destinationPath))
                    {
                        Directory.CreateDirectory(destinationPath);
                    }

                    foreach (var file in coal.Files)
                    {
                        var fileId = Path.GetFileNameWithoutExtension(file.Name);
                        fileId = ProperNames.FirstOrDefault(s => s.Equals(fileId, StringComparison.InvariantCultureIgnoreCase));

                        var iniPath = string.Format("{0}/{1}.xml", destinationPath, fileId);

                        setup.Files.Add(Path.GetFileName(iniPath));

                        xDoc = new XDocument();

                        rootElement = new XElement("CoalesceAsset");
                        rootElement.SetAttributeValue("id", fileId);
                        rootElement.SetAttributeValue("name", Path.GetFileName(file.Name));
                        rootElement.SetAttributeValue("source", file.Name);

                        var sectionsElement = new XElement("Sections");

                        foreach (var section in file.Sections)
                        {
                            var sectionElement = new XElement("Section");
                            sectionElement.SetAttributeValue("name", section.Key);

                            //
                            //var classes = Namespace.FromStrings(section.Value.Keys);

                            //

                            foreach (var property in section.Value)
                            {
                                var propertyElement = new XElement("Property");
                                propertyElement.SetAttributeValue("name", property.Key);

                                if (property.Value.Count > 1)
                                {
                                    foreach (var value in property.Value)
                                    {
                                        var valueElement  = new XElement("Value");
                                        var propertyValue = value.Value;
                                        valueElement.SetAttributeValue("type", value.Type);

                                        if (!propertyValue.IsNullOrWhiteSpace())
                                        {
                                            propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                        }

                                        valueElement.SetValue(propertyValue ?? "null");

                                        propertyElement.Add(valueElement);
                                    }
                                }
                                else
                                {
                                    switch (property.Value.Count)
                                    {
                                    case 1:
                                    {
                                        propertyElement.SetAttributeValue("type", property.Value[0].Type);
                                        var propertyValue = property.Value[0].Value;

                                        if (!propertyValue.IsNullOrWhiteSpace())
                                        {
                                            propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                        }

                                        propertyElement.SetValue(propertyValue ?? "null");
                                        break;
                                    }

                                    case 0:
                                    {
                                        propertyElement.SetAttributeValue("type", CoalesceProperty.DefaultValueType);
                                        propertyElement.SetValue("");
                                        break;
                                    }
                                    }
                                }

                                sectionElement.Add(propertyElement);
                            }

                            sectionsElement.Add(sectionElement);
                        }

                        rootElement.Add(sectionsElement);
                        xDoc.Add(rootElement);

                        //
                        using (var writer = new XmlTextWriter(iniPath, Encoding.UTF8))
                        {
                            writer.IndentChar  = '\t';
                            writer.Indentation = 1;
                            writer.Formatting  = Formatting.Indented;

                            xDoc.Save(writer);
                        }

                        //

                        //xDoc.Save(iniPath, SaveOptions.None);
                    }

                    xDoc = new XDocument();

                    rootElement = new XElement("CoalesceFile");
                    rootElement.SetAttributeValue("id", inputId);
                    rootElement.SetAttributeValue("name", inputName);

                    //rootElement.SetAttributeValue("Source", "");

                    var assetsElement = new XElement("Assets");

                    foreach (var file in setup.Files)
                    {
                        var assetElement = new XElement("Asset");
                        var path         = string.Format("{0}", file);
                        assetElement.SetAttributeValue("source", path);

                        assetsElement.Add(assetElement);
                    }

                    rootElement.Add(assetsElement);
                    xDoc.Add(rootElement);

                    //
                    using (var writer = new XmlTextWriter(Path.Combine(destinationPath, string.Format("{0}.xml", inputId)), Encoding.UTF8))
                    {
                        writer.IndentChar  = '\t';
                        writer.Indentation = 1;
                        writer.Formatting  = Formatting.Indented;

                        xDoc.Save(writer);
                    }

                    //

                    //xDoc.Save(Path.Combine(destinationPath, string.Format("{0}.xml", inputId)), SaveOptions.None);
                }
            }
            else if (options.CoalesceMode == ProgramCoalesceMode.ToXmlNamed)
            {
                var sourcePath      = options.Source;
                var destinationPath = options.Destination;

                if (destinationPath.IsNullOrWhiteSpace())
                {
                    destinationPath = Path.ChangeExtension(sourcePath, null);
                }

                if (!Path.IsPathRooted(destinationPath))
                {
                    destinationPath = Path.Combine(GetExePath(), destinationPath);
                }

                if (!File.Exists(sourcePath))
                {
                    return;
                }

                BuildSettings.Current.SourcePath      = sourcePath;
                BuildSettings.Current.SourceDirectory = Path.GetDirectoryName(sourcePath);
                BuildSettings.Current.OutputPath      = destinationPath;
                BuildSettings.Current.OutputDirectory = Path.GetDirectoryName(destinationPath);

                using (var input = File.OpenRead(sourcePath))
                {
                    var coal = new CoalescedFileXml();
                    coal.Deserialize(input);

                    var inputId   = Path.GetFileNameWithoutExtension(sourcePath) ?? "Coalesced";
                    var inputName = Path.GetFileName(sourcePath) ?? "Coalesced.bin";

                    var setup =
                        new Setup
                    {
                        Endian  = coal.ByteOrder,
                        Version = coal.Version
                    };

                    XDocument xDoc;
                    XElement  rootElement;

                    if (!Directory.Exists(destinationPath))
                    {
                        Directory.CreateDirectory(destinationPath);
                    }

                    foreach (var file in coal.Files)
                    {
                        var fileId = Path.GetFileNameWithoutExtension(file.Name);
                        fileId = ProperNames.FirstOrDefault(s => s.Equals(fileId, StringComparison.InvariantCultureIgnoreCase));

                        var iniPath = string.Format("{0}/{1}.xml", destinationPath, fileId);

                        setup.Files.Add(Path.GetFileName(iniPath));

                        //
                        // Name, IsClass, IsProperty, IsValue
                        var sectionKeys = new SortedSet <Tuple <string, bool, bool, bool> >();

                        // section (class) -> property ->
                        foreach (var sectionClass in file.Sections)
                        {
                            var className = sectionClass.Key.Replace(" ", "--");

                            sectionKeys.Add(new Tuple <string, bool, bool, bool>(className, true, false, false));

                            foreach (var classProperty in sectionClass.Value)
                            {
                                var propertyName = classProperty.Key;

                                if (propertyName.Length > 0 && propertyName[0].IsDigit())
                                {
                                    propertyName = propertyName.Insert(0, "__") + "__";
                                }

                                //propertyName = string.Format("{0}.{1}", className, classProperty.Key);
                                propertyName = string.Format("{0}.{1}", className, propertyName);

                                sectionKeys.Add(new Tuple <string, bool, bool, bool>(propertyName, false, true, false));

                                /*foreach (var propertyValue in classProperty.Value)
                                 * {
                                 *      var valueName = string.Format("{0}=>{1}", propertyName, propertyValue.Value);
                                 *
                                 *      //sectionKeys.Add(new Tuple<string, bool, bool, bool>(valueName, false, false, true));
                                 * }*/
                            }
                        }

                        var elementNames = Namespace.FromStrings(sectionKeys.Select(tuple => tuple.Item1));
                        var elements     = new XElement("BioGame");
                        Namespace.ToXElements(elements, elementNames);
                        elements.Save("Sections.xml");

                        //

                        xDoc = new XDocument();

                        rootElement = new XElement("CoalesceAsset");
                        rootElement.SetAttributeValue("id", fileId);
                        rootElement.SetAttributeValue("name", Path.GetFileName(file.Name));
                        rootElement.SetAttributeValue("source", file.Name);

                        var sectionsElement = new XElement("Sections");

                        foreach (var section in file.Sections)
                        {
                            var sectionElement = new XElement("Section");
                            sectionElement.SetAttributeValue("name", section.Key);

                            foreach (var property in section.Value)
                            {
                                var propertyElement = new XElement("Property");
                                propertyElement.SetAttributeValue("name", property.Key);

                                if (property.Value.Count > 1)
                                {
                                    foreach (var value in property.Value)
                                    {
                                        var valueElement  = new XElement("Value");
                                        var propertyValue = value.Value;
                                        valueElement.SetAttributeValue("type", value.Type);

                                        if (!propertyValue.IsNullOrWhiteSpace())
                                        {
                                            propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                        }

                                        valueElement.SetValue(propertyValue ?? "null");

                                        propertyElement.Add(valueElement);
                                    }
                                }
                                else
                                {
                                    switch (property.Value.Count)
                                    {
                                    case 1:
                                    {
                                        propertyElement.SetAttributeValue("type", property.Value[0].Type);
                                        var propertyValue = property.Value[0].Value;

                                        if (!propertyValue.IsNullOrWhiteSpace())
                                        {
                                            propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                        }

                                        propertyElement.SetValue(propertyValue ?? "null");
                                        break;
                                    }

                                    case 0:
                                    {
                                        propertyElement.SetAttributeValue("type", CoalesceProperty.DefaultValueType);
                                        propertyElement.SetValue("");
                                        break;
                                    }
                                    }
                                }

                                sectionElement.Add(propertyElement);
                            }

                            sectionsElement.Add(sectionElement);
                        }

                        rootElement.Add(sectionsElement);
                        xDoc.Add(rootElement);

                        //
                        using (var writer = new XmlTextWriter(iniPath, Encoding.UTF8))
                        {
                            writer.IndentChar  = '\t';
                            writer.Indentation = 1;
                            writer.Formatting  = Formatting.Indented;

                            xDoc.Save(writer);
                        }

                        //

                        //xDoc.Save(iniPath, SaveOptions.None);
                    }

                    xDoc = new XDocument();

                    rootElement = new XElement("CoalesceFile");
                    rootElement.SetAttributeValue("id", inputId);
                    rootElement.SetAttributeValue("name", inputName);

                    //rootElement.SetAttributeValue("Source", "");

                    var assetsElement = new XElement("Assets");

                    foreach (var file in setup.Files)
                    {
                        var assetElement = new XElement("Asset");
                        var path         = string.Format("{0}", file);
                        assetElement.SetAttributeValue("source", path);

                        assetsElement.Add(assetElement);
                    }

                    rootElement.Add(assetsElement);
                    xDoc.Add(rootElement);

                    //
                    using (var writer = new XmlTextWriter(Path.Combine(destinationPath, string.Format("{0}.xml", inputId)), Encoding.UTF8))
                    {
                        writer.IndentChar  = '\t';
                        writer.Indentation = 1;
                        writer.Formatting  = Formatting.Indented;

                        xDoc.Save(writer);
                    }

                    //

                    //xDoc.Save(Path.Combine(destinationPath, string.Format("{0}.xml", inputId)), SaveOptions.None);
                }
            }
            else if (options.CoalesceMode == ProgramCoalesceMode.ToCSharp)
            {
            }
            else
            {
                var inputPath  = Path.IsPathRooted(options.Source) ? options.Source : Path.Combine(GetExePath(), options.Source);
                var outputPath = !options.Destination.IsNullOrWhiteSpace() ? options.Destination : Path.ChangeExtension(inputPath, ".bin");

                if (!Path.IsPathRooted(outputPath))
                {
                    outputPath = Path.Combine(GetExePath(), outputPath);
                }

                if (!File.Exists(inputPath))
                {
                    return;
                }

                BuildSettings.Current.SourcePath      = inputPath;
                BuildSettings.Current.SourceDirectory = Path.GetDirectoryName(inputPath);
                BuildSettings.Current.OutputPath      = outputPath;
                BuildSettings.Current.OutputDirectory = outputPath;

                var file = XmlCoalesceFile.Load(inputPath);

                var setup = new Setup
                {
                    Endian  = ByteOrder.LittleEndian,
                    Version = 1
                };

                var coal = new CoalescedFileXml
                {
                    ByteOrder = setup.Endian,
                    Version   = 1
                };

                foreach (var asset in file.Assets)
                {
                    var entry =
                        new FileEntry(asset.Source)
                    {
                        Sections = new Dictionary <string, Dictionary <string, List <PropertyValue> > >()
                    };

                    foreach (var section in asset.Sections)
                    {
                        var eSection = new Dictionary <string, List <PropertyValue> >();

                        foreach (var property in section.Value)
                        {
                            var eProperty = new List <PropertyValue>();

                            foreach (var value in property.Value)
                            {
                                if (!file.Settings.CompileTypes.Contains(value.ValueType))
                                {
                                    continue;
                                }

                                var valueValue = value.Value;

                                if (!valueValue.IsNullOrWhiteSpace())
                                {
                                    valueValue = SpecialCharacters.Aggregate(valueValue, (current, c) => current.Replace(c.Value, c.Key));
                                }

                                eProperty.Add(new PropertyValue(value.ValueType, valueValue));
                            }

                            eSection.Add(property.Key, eProperty);
                        }

                        entry.Sections.Add(section.Key, eSection);
                    }

                    coal.Files.Add(entry);
                }

                using (var output = File.Create(outputPath))
                {
                    if (file.Settings != null)
                    {
                        coal.OverrideCompileValueTypes = file.Settings.OverrideCompileValueTypes;
                        coal.CompileTypes = file.Settings.CompileTypes;
                    }

                    coal.Serialize(output);
                }
            }
        }
Beispiel #3
0
        public static void ConvertToXML(string source, string destination)
        {
            var sourcePath      = source;
            var destinationPath = destination;

            if (string.IsNullOrEmpty(destinationPath))
            {
                destinationPath = Path.ChangeExtension(sourcePath, null);
            }

            if (!Path.IsPathRooted(destinationPath))
            {
                destinationPath = Path.Combine(GetExePath(), destinationPath);
            }

            if (!File.Exists(sourcePath))
            {
                return;
            }

            using (var input = File.OpenRead(sourcePath))
            {
                var coal = new CoalescedFileXml();
                coal.Deserialize(input);

                var inputId   = Path.GetFileNameWithoutExtension(sourcePath) ?? "Coalesced";
                var inputName = Path.GetFileName(sourcePath) ?? "Coalesced.bin";

                List <string> OutputFileNames = new List <string>();

                XDocument xDoc;
                XElement  rootElement;

                if (!Directory.Exists(destinationPath))
                {
                    Directory.CreateDirectory(destinationPath);
                }

                foreach (var file in coal.Files)
                {
                    var fileId = Path.GetFileNameWithoutExtension(file.Name);
                    fileId = ProperNames.FirstOrDefault(s => s.Equals(fileId, StringComparison.InvariantCultureIgnoreCase));

                    var iniPath = $"{destinationPath}/{fileId}.xml";

                    OutputFileNames.Add(Path.GetFileName(iniPath));

                    xDoc = new XDocument();

                    rootElement = new XElement("CoalesceAsset");
                    rootElement.SetAttributeValue("id", fileId);
                    rootElement.SetAttributeValue("name", Path.GetFileName(file.Name));
                    rootElement.SetAttributeValue("source", file.Name);

                    var sectionsElement = new XElement("Sections");

                    foreach (var section in file.Sections)
                    {
                        var sectionElement = new XElement("Section");
                        sectionElement.SetAttributeValue("name", section.Key);

                        //
                        //var classes = Namespace.FromStrings(section.Value.Keys);

                        //

                        foreach (var property in section.Value)
                        {
                            var propertyElement = new XElement("Property");
                            propertyElement.SetAttributeValue("name", property.Key);

                            if (property.Value.Count > 1)
                            {
                                foreach (var value in property.Value)
                                {
                                    var valueElement  = new XElement("Value");
                                    var propertyValue = value.Value;
                                    valueElement.SetAttributeValue("type", value.Type);

                                    if (!string.IsNullOrEmpty(propertyValue))
                                    {
                                        propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                    }

                                    valueElement.SetValue(propertyValue ?? "null");

                                    propertyElement.Add(valueElement);
                                }
                            }
                            else
                            {
                                switch (property.Value.Count)
                                {
                                case 1:
                                {
                                    propertyElement.SetAttributeValue("type", property.Value[0].Type);
                                    var propertyValue = property.Value[0].Value;

                                    if (!string.IsNullOrEmpty(propertyValue))
                                    {
                                        propertyValue = SpecialCharacters.Aggregate(propertyValue, (current, c) => current.Replace(c.Key, c.Value));
                                    }

                                    propertyElement.SetValue(propertyValue ?? "null");
                                    break;
                                }

                                case 0:
                                {
                                    propertyElement.SetAttributeValue("type", CoalesceProperty.DefaultValueType);
                                    propertyElement.SetValue("");
                                    break;
                                }
                                }
                            }

                            sectionElement.Add(propertyElement);
                        }

                        sectionsElement.Add(sectionElement);
                    }

                    rootElement.Add(sectionsElement);
                    xDoc.Add(rootElement);

                    //
                    using (var writer = new XmlTextWriter(iniPath, Encoding.UTF8))
                    {
                        writer.IndentChar  = '\t';
                        writer.Indentation = 1;
                        writer.Formatting  = Formatting.Indented;

                        xDoc.Save(writer);
                    }

                    //

                    //xDoc.Save(iniPath, SaveOptions.None);
                }

                xDoc = new XDocument();

                rootElement = new XElement("CoalesceFile");
                rootElement.SetAttributeValue("id", inputId);
                rootElement.SetAttributeValue("name", inputName);

                //rootElement.SetAttributeValue("Source", "");

                var assetsElement = new XElement("Assets");

                foreach (var file in OutputFileNames)
                {
                    var assetElement = new XElement("Asset");
                    var path         = $"{file}";
                    assetElement.SetAttributeValue("source", path);

                    assetsElement.Add(assetElement);
                }

                rootElement.Add(assetsElement);
                xDoc.Add(rootElement);

                //
                using (var writer = new XmlTextWriter(Path.Combine(destinationPath, $"{inputId}.xml"), Encoding.UTF8))
                {
                    writer.IndentChar  = '\t';
                    writer.Indentation = 1;
                    writer.Formatting  = Formatting.Indented;

                    xDoc.Save(writer);
                }

                //

                //xDoc.Save(Path.Combine(destinationPath, string.Format("{0}.xml", inputId)), SaveOptions.None);
            }
        }
Beispiel #4
0
        public void Main(string[] args)
        {
            var mode = Mode.Unknown;

            var showHelp = false;

            /*var options = new OptionSet
             * {
             *      {
             *              "b|xml2bin",
             *              "convert xml to bin",
             *              v => mode = v != null ? Mode.XmlToBin : Mode.Unknown
             *      },
             *      {
             *              "x|bin2xml",
             *              "convert bin to xml",
             *              v => mode = v != null ? Mode.BinToXml : Mode.Unknown
             *      },
             *      {
             *              "h|help",
             *              "show this message and exit",
             *              v => showHelp = v != null
             *      }
             * };*/

            /*args = new[]
             * {
             *      @"C:\Users\Matthew\Documents\Gammtek\Mass Effect\Shared\GammtekMod\build\BioGame.bin",
             *      "-b",
             *      @"C:\Users\Matthew\Documents\Gammtek\Mass Effect\Shared\GammtekMod\src\Mass Effect 3\Coalesce\BioGame\Coalesced.xml",
             *      @"C:\Users\Matthew\Documents\Gammtek\Mass Effect\Shared\GammtekMod\build\BioGame.bin"
             * };*/

            List <string> extras = new List <string>();

            /*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 (mode == Mode.Unknown && extras.Count >= 1)
            {
                var testPath = extras[0];

                /*if (Directory.Exists(testPath))
                 * {
                 *      mode = Mode.XmlToBin;
                 * }*/

                if (File.Exists(testPath))
                {
                    if (testPath.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
                    {
                        mode = Mode.XmlToBin;
                    }
                    else if (testPath.EndsWith(".bin", StringComparison.OrdinalIgnoreCase))
                    {
                        mode = Mode.BinToXml;
                    }
                }
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp || mode == Mode.Unknown)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ -x input_bin [output_dir]", GetExecutableName());
                Console.WriteLine("       {0} [OPTIONS]+ -b input_dir [output_bin]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                //options.WriteOptionDescriptions(Console.Out);

                return;
            }

            if (mode == Mode.BinToXml)
            {
                var inputPath  = extras[0];
                var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null);

                //var inputPath = Path.IsPathRooted(extras[0]) ? extras[0] : Path.Combine(GetExePath(), extras[0]);
                //var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".bin");

                if (!Path.IsPathRooted(outputPath))
                {
                    outputPath = Path.Combine(GetExePath(), outputPath);
                }

                if (!File.Exists(inputPath))
                {
                    return;
                }

                BuildSettings.Current.InputPath       = inputPath;
                BuildSettings.Current.SourcePath      = Path.GetDirectoryName(inputPath);
                BuildSettings.Current.OutputDirectory = outputPath;

                using (var input = File.OpenRead(inputPath))
                {
                    var coal = new CoalescedFileXml();
                    coal.Deserialize(input);

                    var setup = new Setup
                    {
                        Endian  = coal.ByteOrder,
                        Version = coal.Version,
                    };

                    XDocument xDoc;
                    XElement  rootElement;

                    foreach (var file in coal.Files)
                    {
                        var iniPath = string.Format("{0}", Path.GetFileNameWithoutExtension(file.Name));

                        iniPath = Path.Combine(outputPath, Path.ChangeExtension(iniPath, ".xml"));

                        var iniPathDir = Path.GetDirectoryName(iniPath);

                        setup.Files.Add(Path.GetFileName(iniPath));

                        if (iniPathDir != null)
                        {
                            Directory.CreateDirectory(iniPathDir);
                        }

                        xDoc = new XDocument();

                        rootElement = new XElement("CoalesceAsset");
                        rootElement.SetAttributeValue("id", Path.GetFileNameWithoutExtension(file.Name));
                        rootElement.SetAttributeValue("name", Path.GetFileName(file.Name));
                        rootElement.SetAttributeValue("source", file.Name);

                        var sectionsElement = new XElement("Sections");

                        foreach (var section in file.Sections)
                        {
                            var sectionElement = new XElement("Section");
                            sectionElement.SetAttributeValue("name", section.Key);

                            foreach (var property in section.Value)
                            {
                                var propertyElement = new XElement("Property");
                                propertyElement.SetAttributeValue("name", property.Key);

                                if (property.Value.Count > 1)
                                {
                                    foreach (var value in property.Value)
                                    {
                                        var valueElement = new XElement("Value");
                                        valueElement.SetAttributeValue("type", value.Type);
                                        valueElement.SetValue(value.Value ?? "null");

                                        propertyElement.Add(valueElement);
                                    }
                                }
                                else if (property.Value.Count == 1)
                                {
                                    propertyElement.SetAttributeValue("type", property.Value[0].Type);
                                    propertyElement.SetValue(property.Value[0].Value ?? "null");
                                }
                                else if (property.Value.Count == 0)
                                {
                                    propertyElement.SetAttributeValue("type", CoalesceProperty.DefaultValueType);
                                    propertyElement.SetValue("");
                                }

                                sectionElement.Add(propertyElement);
                            }

                            sectionsElement.Add(sectionElement);
                        }

                        rootElement.Add(sectionsElement);
                        xDoc.Add(rootElement);
                        xDoc.Save(iniPath, SaveOptions.None);
                    }

                    Directory.CreateDirectory(outputPath);

                    xDoc = new XDocument();

                    rootElement = new XElement("CoalesceFile");
                    rootElement.SetAttributeValue("id", "");
                    rootElement.SetAttributeValue("name", "");
                    rootElement.SetAttributeValue("source", "");

                    var assetsElement = new XElement("Assets");

                    foreach (var file in setup.Files)
                    {
                        var assetElement = new XElement("Asset");
                        assetElement.SetAttributeValue("source", file);

                        assetsElement.Add(assetElement);
                    }

                    rootElement.Add(assetsElement);
                    xDoc.Add(rootElement);
                    xDoc.Save(Path.Combine(outputPath, "Coalesced.xml"), SaveOptions.None);
                }
            }
            else
            {
                var inputPath  = Path.IsPathRooted(extras[0]) ? extras[0] : Path.Combine(GetExePath(), extras[0]);
                var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, ".bin");

                if (!Path.IsPathRooted(outputPath))
                {
                    outputPath = Path.Combine(GetExePath(), outputPath);
                }

                if (!File.Exists(inputPath))
                {
                    return;
                }

                BuildSettings.Current.InputPath       = inputPath;
                BuildSettings.Current.SourcePath      = Path.GetDirectoryName(inputPath);
                BuildSettings.Current.OutputDirectory = outputPath;

                var file = XmlCoalesceFile.Load(extras[0]);

                var setup = new Setup
                {
                    Endian  = ByteOrder.LittleEndian,
                    Version = 1
                };

                var coal = new CoalescedFileXml
                {
                    ByteOrder = setup.Endian,
                    Version   = 1
                };

                foreach (var asset in file.Assets)
                {
                    var entry = new FileEntry(asset.Source)
                    {
                        Sections = new Dictionary <string, Dictionary <string, List <PropertyValue> > >()
                    };

                    foreach (var section in asset.Sections)
                    {
                        var eSection = new Dictionary <string, List <PropertyValue> >();

                        foreach (var property in section.Value)
                        {
                            var eProperty = new List <PropertyValue>();

                            foreach (var value in property.Value)
                            {
                                if (!file.Settings.CompileTypes.Contains(value.ValueType))
                                {
                                    continue;
                                }

                                eProperty.Add(new PropertyValue(value.ValueType, value.Value));
                            }

                            eSection.Add(property.Key, eProperty);
                        }

                        entry.Sections.Add(section.Key, eSection);
                    }

                    coal.Files.Add(entry);
                }

                using (var output = File.Create(outputPath))
                {
                    if (file.Settings != null)
                    {
                        coal.OverrideCompileValueTypes = file.Settings.OverrideCompileValueTypes;
                        coal.CompileTypes = file.Settings.CompileTypes;
                    }

                    coal.Serialize(output);
                }
            }
        }