Exemplo n.º 1
0
        public void Export(FieldDefinition fieldDef,
                           FieldType arrayFieldType,
                           byte[] data,
                           int offset,
                           int count,
                           XmlWriter writer,
                           out int read)
        {
            if (Helpers.HasLeft(data, 0, data.Length, 5) == false)
            {
                throw new FormatException("Rml requires at least 5 bytes");
            }

            var rez = new XmlResourceFile();

            using (var input = new MemoryStream(data, 0, data.Length, false))
            {
                rez.Deserialize(input);
                read = data.Length;
            }

            writer.WriteStartElement("rml");
            ConvertXml.Program.WriteNode(writer, rez.Root);
            writer.WriteEndElement();
        }
Exemplo n.º 2
0
        public static void Main(string[] args)
        {
            var  mode     = Mode.Unknown;
            bool showHelp = false;

            OptionSet options = new OptionSet()
            {
                {
                    "rml",
                    "convert XML to RML",
                    v => mode = v != null ? Mode.ToRML : mode
                },
                {
                    "xml",
                    "convert RML to XML",
                    v => mode = v != null ? Mode.ToXML : mode
                },
                {
                    "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 (mode == Mode.Unknown &&
                extras.Count >= 1)
            {
                var extension = Path.GetExtension(extras[0]);

                if (extension == ".rml")
                {
                    mode = Mode.ToXML;
                }
                else if (extension == ".xml")
                {
                    mode = Mode.ToRML;
                }
            }

            if (showHelp == true ||
                mode == Mode.Unknown ||
                extras.Count < 1 ||
                extras.Count > 2)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input [output]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            if (mode == Mode.ToRML)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(Path.ChangeExtension(inputPath, null) + "_converted", ".rml");

                var rez = new XmlResourceFile();
                using (var input = File.OpenRead(inputPath))
                {
                    var doc = new XPathDocument(input);
                    var nav = doc.CreateNavigator();

                    if (nav.MoveToFirstChild() == false)
                    {
                        throw new FormatException();
                    }

                    rez.Root = ReadNode(nav);
                }

                using (var output = File.Create(outputPath))
                {
                    rez.Serialize(output);
                }
            }
            else if (mode == Mode.ToXML)
            {
                string inputPath  = extras[0];
                string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(Path.ChangeExtension(inputPath, null) + "_converted", ".xml");

                var rez = new XmlResourceFile();
                using (var input = File.OpenRead(inputPath))
                {
                    rez.Deserialize(input);
                }

                var settings = new XmlWriterSettings();
                settings.Encoding           = Encoding.UTF8;
                settings.Indent             = true;
                settings.OmitXmlDeclaration = true;

                using (var writer = XmlWriter.Create(outputPath, settings))
                {
                    writer.WriteStartDocument();
                    WriteNode(writer, rez.Root);
                    writer.WriteEndDocument();
                }
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Exemplo n.º 3
0
        private static void WriteNode(
            XmlWriter writer,
            BinaryResourceFile.Object node,
            IDefinitionProvider provider)
        {
            var def = provider.GetClassDefinition(node.TypeHash);

            writer.WriteStartElement("object");

            if (def.Name != null)
            {
                writer.WriteAttributeString("type", def.Name);
            }
            else
            {
                writer.WriteAttributeString("hash", node.TypeHash.ToString("X8"));
            }

            if (node.Values != null &&
                node.Values.Count > 0)
            {
                foreach (var kv in node.Values)
                {
                    writer.WriteStartElement("value");

                    var member = def.GetMemberDefinition(kv.Key);

                    if (member != null && member.Name != null)
                    {
                        writer.WriteAttributeString("name", member.Name);
                    }
                    else
                    {
                        writer.WriteAttributeString("hash", kv.Key.ToString("X8"));
                    }

                    if (member == null)
                    {
                        writer.WriteAttributeString("type", MemberType.BinHex.ToString());
                        writer.WriteBinHex(kv.Value, 0, kv.Value.Length);
                    }
                    else
                    {
                        writer.WriteAttributeString("type", member.Type.ToString());

                        switch (member.Type)
                        {
                        case MemberType.BinHex:
                        {
                            writer.WriteBinHex(kv.Value, 0, kv.Value.Length);
                            break;
                        }

                        case MemberType.Hash:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString("X8", CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.String:
                        {
                            if (kv.Value.Length < 1)
                            {
                                throw new FormatException();
                            }
                            else if (kv.Value[kv.Value.Length - 1] != 0)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(Encoding.UTF8.GetString(kv.Value, 0, kv.Value.Length - 1));
                            break;
                        }

                        case MemberType.Enum:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Bool:
                        {
                            if (kv.Value.Length != 1)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString((kv.Value[0] != 0 ? true : false).ToString());
                            break;
                        }

                        case MemberType.Float:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Int32:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt32:
                        {
                            if (kv.Value.Length != 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt32(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Int64:
                        {
                            if (kv.Value.Length != 8)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToInt64(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt64:
                        {
                            if (kv.Value.Length != 8)
                            {
                                throw new FormatException();
                            }

                            writer.WriteString(BitConverter.ToUInt64(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector2:
                        {
                            if (kv.Value.Length != 4 * 2)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector3:
                        {
                            if (kv.Value.Length != 4 * 3)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("z", BitConverter.ToSingle(kv.Value, 8).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.Vector4:
                        {
                            if (kv.Value.Length != 4 * 4)
                            {
                                throw new FormatException();
                            }

                            writer.WriteElementString("x", BitConverter.ToSingle(kv.Value, 0).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("y", BitConverter.ToSingle(kv.Value, 4).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("z", BitConverter.ToSingle(kv.Value, 8).ToString(CultureInfo.InvariantCulture));
                            writer.WriteElementString("w", BitConverter.ToSingle(kv.Value, 12).ToString(CultureInfo.InvariantCulture));
                            break;
                        }

                        case MemberType.UInt32Array:
                        {
                            if (kv.Value.Length < 4)
                            {
                                throw new FormatException();
                            }

                            var count = BitConverter.ToInt32(kv.Value, 0);
                            if (kv.Value.Length != 4 + (count * 4))
                            {
                                throw new FormatException();
                            }

                            for (int i = 0, offset = 4; i < count; i++, offset += 4)
                            {
                                writer.WriteElementString("item", BitConverter.ToUInt32(kv.Value, offset).ToString(CultureInfo.InvariantCulture));
                            }

                            break;
                        }

                        case MemberType.HashArray:
                        {
                            if (kv.Value.Length < 4)
                            {
                                throw new FormatException();
                            }

                            var count = BitConverter.ToInt32(kv.Value, 0);
                            if (kv.Value.Length != 4 + (count * 4))
                            {
                                throw new FormatException();
                            }

                            for (int i = 0, offset = 4; i < count; i++, offset += 4)
                            {
                                writer.WriteElementString("item", BitConverter.ToUInt32(kv.Value, offset).ToString("X8"));
                            }

                            break;
                        }

                        case MemberType.Rml:
                        {
                            var rez = new XmlResourceFile();
                            using (var input = new MemoryStream(kv.Value))
                            {
                                rez.Deserialize(input);
                            }

                            writer.WriteStartElement("rml");
                            ConvertXml.Program.WriteNode(writer, rez.Root);
                            writer.WriteEndElement();
                            break;
                        }

                        default:
                        {
                            throw new NotSupportedException();
                        }
                        }
                    }

                    writer.WriteEndElement();
                }
            }

            if (node.Children != null &&
                node.Children.Count > 0)
            {
                foreach (var child in node.Children)
                {
                    WriteNode(writer, child, def);
                }
            }

            writer.WriteEndElement();
        }
        public static void Deserialize(XmlWriter writer,
                                       FieldDefinition fieldDef,
                                       byte[] data)
        {
            int read;

            switch (fieldDef.Type)
            {
            case FieldType.BinHex:
            {
                writer.WriteBinHex(data, 0, data.Length);
                read = data.Length;
                break;
            }

            case FieldType.Boolean:
            case FieldType.UInt8:
            case FieldType.Int8:
            case FieldType.UInt16:
            case FieldType.Int16:
            case FieldType.UInt32:
            case FieldType.Int32:
            case FieldType.UInt64:
            case FieldType.Int64:
            case FieldType.Float32:
            case FieldType.Float64:
            case FieldType.Vector2:
            case FieldType.Vector3:
            case FieldType.Vector4:
            case FieldType.String:
            case FieldType.Hash32:
            case FieldType.Hash64:
            case FieldType.Id32:
            case FieldType.Id64:
            {
                Deserialize(writer, fieldDef.Type, data, 0, data.Length, out read);
                break;
            }

            case FieldType.Enum:
            {
                var value = Deserialize <int>(fieldDef.Type, data, 0, data.Length, out read);

                if (fieldDef.Enum != null)
                {
                    var enumDef = fieldDef.Enum.Elements.FirstOrDefault(ed => ed.Value == value);
                    if (enumDef != null)
                    {
                        writer.WriteString(enumDef.Name);
                        break;
                    }
                }

                writer.WriteString(value.ToString(CultureInfo.InvariantCulture));
                break;
            }

            case FieldType.Rml:
            {
                if (HasLeft(data, 0, data.Length, 5) == false)
                {
                    throw new FormatException("field type Rml requires at least 5 bytes");
                }

                var rez = new XmlResourceFile();
                using (var input = new MemoryStream(data, 0, data.Length, false))
                {
                    rez.Deserialize(input);
                    read = data.Length;
                }

                writer.WriteStartElement("rml");
                ConvertXml.Program.WriteNode(writer, rez.Root);
                writer.WriteEndElement();
                break;
            }

            case FieldType.Array32:
            {
                if (HasLeft(data, 0, data.Length, 4) == false)
                {
                    throw new FormatException("field type Array32 requires at least 4 bytes");
                }

                var itemCount = BitConverter.ToUInt32(data, 0);

                read = 4;
                int offset    = 4;
                int remaining = data.Length - offset;
                for (uint i = 0; i < itemCount; i++)
                {
                    writer.WriteStartElement("item");
                    int itemRead;
                    Deserialize(writer, fieldDef.ArrayType, data, offset, remaining, out itemRead);
                    offset    += itemRead;
                    remaining -= itemRead;
                    writer.WriteEndElement();

                    read += itemRead;
                }

                break;
            }

            default:
            {
                throw new NotSupportedException("unsupported field type");
            }
            }

            if (read != data.Length)
            {
                if (string.IsNullOrEmpty(fieldDef.Name) == false)
                {
                    throw new FormatException(
                              string.Format("did not consume all data for field '{0}' (read {1}, total {2})",
                                            fieldDef.Name,
                                            read,
                                            data.Length));
                }

                throw new FormatException(
                          string.Format("did not consume all data for field 0x{0:X8}  (read {1}, total {2})",
                                        fieldDef.Hash,
                                        read,
                                        data.Length));
            }
        }