Beispiel #1
0
        public XAttribute CreateXmlAttribute(NomadValue val, XElement parent = null)
        {
            Context.State = ContextStateType.Member;
            Context.MemberIndex++;

            var id   = val.Id;
            var data = val.Data;

            try
            {
                var name  = XName.Get(id);
                var value = data.ToString();

                var attr = new XAttribute(name, value);

                if (parent != null)
                {
                    parent.Add(attr);
                }

                return(attr);
            }
            catch (Exception e)
            {
                throw new XmlException($"Error parsing attribute '{id}' in '{parent.Name}' of type '{data.Type}' : {e.Message}", e);
            }
        }
Beispiel #2
0
        protected void WriteAttribute_FmtB(BinaryStream stream, NomadValue attr, int baseOffset)
        {
            Context.State = ContextStateType.Member;
            Context.MemberIndex++;

            WriteAttributeData(stream, attr, baseOffset);
        }
Beispiel #3
0
        public NomadObject ReadRmlObject(XElement rml, NomadObject parent)
        {
            var result = new NomadObject(true)
            {
                Id = rml.Name.LocalName,
            };

            foreach (var rmlAttr in rml.Attributes())
            {
                var value = rmlAttr.Value;

                var attr = new NomadValue(DataType.RML, rmlAttr.Value)
                {
                    Id = rmlAttr.Name.LocalName,
                };

                result.Attributes.Add(attr);
            }

            foreach (var rmlChild in rml.Elements())
            {
                ReadRmlObject(rmlChild, result);
            }

            if (parent != null)
            {
                parent.Children.Add(result);
            }

            return(result);
        }
Beispiel #4
0
        protected NomadValue ReadRmlAttribute(BinaryStream _stream, NomadObject parent = null)
        {
            Context.State = ContextStateType.Member;
            Context.ObjectIndex++;

            var unk = (byte)_stream.ReadByte();

            if (unk != 0)
            {
                throw new InvalidOperationException("Invalid RML attribute data.");
            }

            var nameIdx = DescriptorTag.Read(_stream, ReferenceType.Index);
            var valIdx  = DescriptorTag.Read(_stream, ReferenceType.Index);

            var buffer = Utils.GetStringBuffer(_strings[valIdx]);

            var result = new NomadValue(DataType.RML, buffer)
            {
                Id = _strings[nameIdx],
            };

            if (parent != null)
            {
                parent.Attributes.Add(result);
            }

            return(result);
        }
Beispiel #5
0
        protected void ReadPrototypeEntry(BinaryStream stream)
        {
            long uid = 0;

            if (Use64Bit)
            {
                uid = stream.ReadInt64();
            }
            else
            {
                uid = stream.ReadUInt32();
            }

            var buffer = (Use64Bit)
                ? BitConverter.GetBytes(uid)
                : BitConverter.GetBytes((uint)uid);

            var lookup = new EntityPrototypeInfo(stream, 8);
            var obj    = Context.GetRefByPtr(lookup.Offset) as NomadObject;

            if (obj == null)
            {
                throw new InvalidDataException($"Couldn't find library '{uid:X8}' at offset {lookup.Offset:X8}!");
            }

            // remove before writing
            var libId = new NomadValue("UID", DataType.BinHex, buffer);

            obj.Attributes.Add(libId);

            Prototypes.Add(uid, obj);
        }
Beispiel #6
0
        protected void WriteAttributeRmlData(BinaryStream stream, NomadValue attr)
        {
            var rmlBuffer = attr.Data.Buffer;

            var rmlSize = DescriptorTag.Create(rmlBuffer.Length);

            rmlSize.WriteTo(stream);

            stream.Write(rmlBuffer);
        }
Beispiel #7
0
        protected void WriteAttributeData(BinaryStream stream, NomadValue attr, int baseOffset = 0)
        {
            var ptr = (int)stream.Position + baseOffset;

            var data = attr.Data;
            var type = data.Type;
            var size = data.Size;

            var buffer = data.Buffer;

            if (data.Type == DataType.RML)
            {
                throw new InvalidOperationException("Cannot serialize RML data directly!");
            }

            var oldSize = size;

            var attrData = (Format != FormatType.Resource)
                ? Utils.GetAttributeDataMiniBuffer(buffer, type)
                : Utils.GetAttributeDataBuffer(buffer, type);

            size = attrData.Length;

            var writeData = true;

            if (size > 4)
            {
                // return cached instance, else cache it and return empty
                var cache = WriteCache.PreCache(ptr, attrData, size);

                if (!cache.IsEmpty)
                {
                    // sizes must match
                    if (cache.Size == size)
                    {
                        var nD = DescriptorTag.CreateReference(cache.Offset, ReferenceType.Offset);
                        nD.WriteTo(stream, baseOffset);

                        writeData = false;
                    }
                }
            }

            if (writeData)
            {
                var nD = DescriptorTag.Create(size);
                nD.WriteTo(stream);

                stream.Write(attrData);
            }
        }
Beispiel #8
0
        protected NomadValue ReadAttributeData(BinaryStream stream, NomadObject parent, int hash)
        {
            var ptr = (int)stream.Position;
            var id  = StringId.Parse(hash);

            var type = (id == "RML_DATA")
                ? DataType.RML
                : AttributeTypes.GetBestType(id, parent.Id);

            var data = AttributeData.Read(stream, type);

            switch (type)
            {
            case DataType.BinHex:
            {
                if (data.Type == DataType.String)
                {
                    StringId fullType = $"{parent.Id}.{id}";

                    if (!AttributeTypes.IsTypeKnown(fullType))
                    {
                        AttributeTypes.RegisterGuessType(fullType, data.Type);
                    }
                }
            }
            break;

            case DataType.String:
            {
                if (data.Type == DataType.BinHex)
                {
                    StringId fullType = $"{parent.Id}.{id}";

                    Context.LogDebug($"**** Attribute '{fullType}' was incorrectly assumed to be a String! ****");
                }
            } break;
            }

            var result = new NomadValue()
            {
                Id   = id,
                Data = data,
            };

            if (parent != null)
            {
                parent.Attributes.Add(result);
            }

            return(result);
        }
Beispiel #9
0
        public void SetAttributeValue(StringId id, DataType type, string value)
        {
            var attr = GetAttribute(id);

            if (attr != null)
            {
                attr.Data = new AttributeData(type, value);
            }
            else
            {
                attr = new NomadValue(id, type, value);

                Attributes.Add(attr);
            }
        }
Beispiel #10
0
        protected void WriteAttribute_FmtA(BinaryStream stream, NomadValue attr)
        {
            Context.State = ContextStateType.Member;
            Context.MemberIndex++;

            stream.Write(attr.Id.Hash);

            if (attr.IsRml)
            {
                WriteAttributeRmlData(stream, attr);
            }
            else
            {
                WriteAttributeData(stream, attr);
            }
        }
Beispiel #11
0
        public NomadValue ReadXmlAttribute(XAttribute xml, NomadObject parent)
        {
            Context.State = ContextStateType.Member;
            Context.MemberIndex++;

            var name  = xml.Name.LocalName;
            var cName = xml.Parent.Name.LocalName;

            var id = StringId.Parse(name);

            var type = (parent.IsRml)
                ? DataType.RML
                : AttributeTypes.GetBestType(id, cName);

            var value = xml.Value;

            if (type == DataType.BinHex)
            {
                // handle potential strings safely
                if ((value.Length > 0) && !Utils.IsHexString(value))
                {
                    type = DataType.String;
                }
            }

            NomadValue result = null;

            try
            {
                result = new NomadValue(type, value)
                {
                    Id = id
                };

                parent.Attributes.Add(result);

                return(result);
            }
            catch (Exception e)
            {
                throw new XmlException($"Error parsing attribute '{id}' in '{parent.Id}' of type '{type}' : {e.Message}", e);
            }
        }
Beispiel #12
0
        public void Serialize(NomadObject root)
        {
            var obj = new NomadObject("PerMoveResourceInfo");

            var sizes       = new List <int>();
            var rootNodeIds = new List <int>();

            foreach (var info in Infos)
            {
                sizes.Add(info.Size);
                rootNodeIds.Add(info.RootNodeId);
            }

            var sizesAttr       = new NomadValue("sizes", DataType.Array);
            var rootNodeIdsAttr = new NomadValue("rootNodeIds", DataType.Array);

            Utils.PackArray(sizesAttr, sizes, BitConverter.GetBytes, 4);
            Utils.PackArray(rootNodeIdsAttr, rootNodeIds, BitConverter.GetBytes, 4);

            obj.Attributes.Add(sizesAttr);
            obj.Attributes.Add(rootNodeIdsAttr);

            root.Children.Add(obj);
        }
Beispiel #13
0
        public override void Serialize(Stream stream, NomadObject _unused)
        {
            var root = new NomadObject("ROOT");

            root.Children.Add(new NomadObject("PMSVALUEDESCLIST"));

            var allFixups = new List <NomadObject>();

            foreach (var param in AllParams)
            {
                if (param.MinVersion > Version)
                {
                    continue;
                }

                var values = new NomadObject(param.ValuesId);
                values.Children.AddRange(param.Values);

                root.Children.Add(values);

                var offsets = new List <int>();
                var hashes  = new List <int>();

                foreach (var fixup in param.Fixups)
                {
                    offsets.Add(fixup.Offset);
                    hashes.Add(fixup.Hash);
                }

                var offsetsAttr = new NomadValue("offsetsArray", DataType.Array);
                var hashesAttr  = new NomadValue("hashesArray", DataType.Array);

                Utils.PackArray(offsetsAttr, offsets, BitConverter.GetBytes, 4);
                Utils.PackArray(hashesAttr, hashes, BitConverter.GetBytes, 4);

                var fixups = new NomadObject(param.FixupsId);

                fixups.Attributes.Add(offsetsAttr);
                fixups.Attributes.Add(hashesAttr);

                allFixups.Add(fixups);
            }

            root.Children.AddRange(allFixups);

            PerMoveResourceInfo.Serialize(root);

            var bs = (stream as BinaryStream)
                     ?? new BinaryStream(stream);

            byte[] fcbData = null;

            using (var nb = new BinaryStream(1024))
            {
                Format = FormatType.Objects;

                base.Serialize(nb, root);
                fcbData = nb.ToArray();
            }

            bs.Write(MoveCount);

            bs.Write(MoveData.Length);
            bs.Write(fcbData.Length);

            bs.Write(MoveData);
            bs.Write(fcbData);
        }
Beispiel #14
0
        public NomadObject ReadXmlObject(XElement xml, NomadObject parent = null)
        {
            Context.State = ContextStateType.Object;
            Context.ObjectIndex++;

            var name = xml.Name.LocalName;

            var id    = StringId.Parse(name);
            var isRml = false;

            if (parent != null)
            {
                isRml = parent.IsRml;
            }
            if (!isRml && (id == "RML_DATA"))
            {
                isRml = true;
            }

            if (isRml)
            {
                XElement rmlElem = null;

                foreach (var elem in xml.Elements())
                {
                    if (rmlElem != null)
                    {
                        throw new XmlException("Too many elements in RML_DATA node!");
                    }

                    rmlElem = elem;
                }

                if (rmlElem == null)
                {
                    throw new XmlException("Empty RML_DATA nodes are cancerous to your health!");
                }

                var rmlRoot = new NomadObject(true)
                {
                    Id = "RML_DATA"
                };

                ReadRmlObject(rmlElem, rmlRoot);

                byte[] rmlBuffer = null;

                using (var bs = new BinaryStream(1024))
                {
                    // don't write size yet
                    bs.Position += 4;

                    var rmlData = new NomadRmlSerializer();
                    rmlData.Serialize(bs, rmlRoot);

                    // write size
                    var rmlSize = (int)(bs.Position - 4);
                    bs.Position = 0;

                    bs.Write(rmlSize);

                    rmlBuffer = bs.ToArray();
                }

                if (parent != null)
                {
                    var rml = new NomadValue()
                    {
                        Id   = id,
                        Data = new AttributeData(DataType.RML, rmlBuffer),
                    };

                    parent.Attributes.Add(rml);
                }

                return(rmlRoot);
            }

            var result = new NomadObject(isRml)
            {
                Id = id
            };

            foreach (var attr in xml.Attributes())
            {
                ReadXmlAttribute(attr, result);
            }

            foreach (var node in xml.Elements())
            {
                ReadXmlObject(node, result);
            }

            if (parent != null)
            {
                parent.Children.Add(result);
            }

            return(result);
        }