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); } }
protected void WriteAttribute_FmtB(BinaryStream stream, NomadValue attr, int baseOffset) { Context.State = ContextStateType.Member; Context.MemberIndex++; WriteAttributeData(stream, attr, baseOffset); }
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); }
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); }
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); }
protected void WriteAttributeRmlData(BinaryStream stream, NomadValue attr) { var rmlBuffer = attr.Data.Buffer; var rmlSize = DescriptorTag.Create(rmlBuffer.Length); rmlSize.WriteTo(stream); stream.Write(rmlBuffer); }
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); } }
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); }
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); } }
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); } }
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); } }
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); }
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); }
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); }