public byte[] Unpack() { var memory = new BinaryStream(1024); using (var bs = new BinaryStream(Data)) { for (int i = 1; i < Blocks.Count; i++) { var block = Blocks[i - 1]; var next = Blocks[i]; var size = (int)(next.VirtualOffset - block.VirtualOffset); bs.Seek(block.FileOffset - 4, SeekOrigin.Begin); memory.Seek(block.VirtualOffset, SeekOrigin.Begin); if (block.IsCompressed == true) { var zlib = new InflaterInputStream(bs); zlib.CopyTo(memory); } else { var buffer = bs.ReadBytes(size); memory.Write(buffer, 0, size); } } } return(memory.ToArray()); }
protected bool WriteAttributesList_FmtB(BinaryStream stream, NomadObject obj) { var ptr = (int)stream.Position; byte[] buffer = new byte[0]; using (var bs = new BinaryStream(1024)) { WriteAttributesData_FmtB(bs, obj.Attributes, ptr); buffer = bs.ToArray(); } var length = buffer.Length; if (length > 65535) { throw new InvalidOperationException("Attribute data too large."); } stream.Write((short)length); stream.Write(buffer, 0, length); // did we write any data? return(length > 0); }
public override void Serialize(Stream stream, NomadObject _unused) { Context.Begin(); var bs = (stream as BinaryStream) ?? new BinaryStream(stream); byte[] buffer = null; using (var nb = new BinaryStream(1024)) { base.Serialize(nb, Root); buffer = nb.ToArray(); } var count = Prototypes.Count; bs.Write(buffer.Length + 8); bs.Write(count); bs.Write(buffer); // todo: prototype entries Context.Log("Writing prototypes..."); foreach (var kv in Prototypes) { var uid = kv.Key; var obj = kv.Value; // fail-safe var reference = new NomadReference(obj); var cached = reference.Get(); var ptr = (int)Context.GetPtr(cached); if (ptr == -1) { throw new InvalidDataException("Couldn't get the pointer to a prototype!"); } var info = new EntityPrototypeInfo(obj, ptr); var uidBuffer = (Use64Bit) ? BitConverter.GetBytes(uid) : BitConverter.GetBytes((uint)uid); bs.Write(uidBuffer); info.Serialize(bs); } Context.End(); }
public static FCXCompressedData Pack(BinaryStream stream) { var compressedData = new FCXCompressedData(); using (var bs = new BinaryStream(1024)) { uint virtualOffset = 0; uint realOffset = 4; while (stream.Position < stream.Length) { var length = (int)Math.Min(0x40000, (stream.Length - stream.Position)); using (var block = new BinaryStream(16)) { var zlib = new DeflaterOutputStream(block); var buffer = stream.ReadBytes(length); zlib.Write(buffer, 0, length); zlib.Finish(); compressedData.Blocks.Add(new Block() { VirtualOffset = virtualOffset, FileOffset = realOffset, IsCompressed = true, }); block.Position = 0; block.CopyTo(bs); realOffset += (uint)block.Length; } virtualOffset += (uint)length; } compressedData.Data = bs.ToArray(); compressedData.Blocks.Add(new Block() { VirtualOffset = virtualOffset, FileOffset = realOffset, IsCompressed = true, }); } return(compressedData); }
protected void WriteRmlData(BinaryStream stream, NomadObject data) { byte[] rmlBuffer = null; using (var bs = new BinaryStream(1024)) { var rmlData = new NomadRmlSerializer(); rmlData.Serialize(bs, data); rmlBuffer = bs.ToArray(); } var size = DescriptorTag.Create(rmlBuffer.Length); var next = DescriptorTag.Create(size); next.WriteTo(stream); size.WriteTo(stream); stream.Write(rmlBuffer, 0, rmlBuffer.Length); }
public bool Save(string filename) { if (Type == FileType.Xml) { var serializer = GetSerializer() as INomadXmlFileSerializer; if (serializer != null) { serializer.SaveXml(filename); return(true); } } byte[] buffer = null; using (var bs = new BinaryStream(1024)) { if (Save(bs)) { buffer = bs.ToArray(); } } if (buffer != null) { var outDir = Path.GetDirectoryName(filename); if (!Directory.Exists(outDir)) { Directory.CreateDirectory(outDir); } File.WriteAllBytes(filename, buffer); return(true); } // couldn't serialize data return(false); }
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); }
public override void Serialize(Stream stream, NomadObject data) { if (Context.State == ContextStateType.End) { Context.Reset(); } if (data.Id != "RML_DATA") { throw new InvalidOperationException("RML data wasn't prepared before initializing."); } if ((data.Children.Count != 1) || (data.Attributes.Count != 0)) { throw new InvalidOperationException("RML data is malformed and cannot be serialized properly."); } var _stream = (stream as BinaryStream) ?? new BinaryStream(stream); var rmlRoot = data.Children[0]; if (!rmlRoot.IsRml) { throw new InvalidOperationException("You can't serialize non-RML data as RML data, dumbass!"); } _strings.Clear(); var strLookup = new Dictionary <string, int>(); var strPtr = 0; var getStrIdx = new Func <string, int>((str) => { var ptr = 0; if (str == null) { str = String.Empty; } if (strLookup.ContainsKey(str)) { ptr = strLookup[str]; } else { // add to lookup ptr = strPtr; strLookup.Add(str, strPtr); // add to string table _strings.Add(strPtr, str); // must have null-terminator! var strLen = 1; if (str != null) { strLen += str.Length; } strPtr += strLen; } return(ptr); }); var entries = new List <NomadData>(); var elemsCount = 1; var attrsCount = 0; entries.Add(rmlRoot); // iterates through attributes then children (and children's children, etc.) foreach (var nd in rmlRoot) { if (!nd.IsRml) { throw new InvalidOperationException("Can't serialize non-RML data!"); } if (nd.IsAttribute) { ++attrsCount; } else if (nd.IsObject) { ++elemsCount; } entries.Add(nd); } // rough size estimate var rmlSize = ((elemsCount * 4) + (attrsCount * 2)); var strTableLen = -1; byte[] rmlBuffer = null; using (var ms = new BinaryStream(rmlSize)) { var writeInt = new Action <int>((ptr) => { var nD = DescriptorTag.Create(ptr); nD.WriteTo(ms); }); var writeRml = new Action <NomadData>((nd) => { var nameIdx = getStrIdx(nd.Id); var valIdx = -1; if (nd.IsObject) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var obj = (NomadObject)nd; valIdx = getStrIdx(obj.Tag); writeInt(nameIdx); writeInt(valIdx); writeInt(obj.Attributes.Count); writeInt(obj.Children.Count); } else if (nd.IsAttribute) { Context.State = ContextStateType.Member; Context.MemberIndex++; var attr = (NomadValue)nd; valIdx = getStrIdx(attr.Data); // required for attributes ms.WriteByte(0); writeInt(nameIdx); writeInt(valIdx); } }); writeRml(rmlRoot); // enumerates attributes, then children (+ nested children) foreach (var rml in rmlRoot) { writeRml(rml); } // setup string table size strTableLen = strPtr; // write out string table foreach (var kv in _strings) { var str = kv.Value; var strLen = (str != null) ? str.Length : 0; var strBuf = new byte[strLen + 1]; if (strLen > 0) { Encoding.UTF8.GetBytes(str, 0, strLen, strBuf, 0); } ms.Write(strBuf); } // commit buffer rmlBuffer = ms.ToArray(); rmlSize = rmlBuffer.Length; } var bufSize = 5; // header + 3 small ints // expand size as needed if (strTableLen >= 254) { bufSize += 4; } if (elemsCount >= 254) { bufSize += 4; } if (attrsCount >= 254) { bufSize += 4; } // calculate the final size (hopefully) bufSize += rmlSize; byte[] result = null; using (var ms = new BinaryStream(bufSize)) { ms.WriteByte(0); ms.WriteByte(Reserved); DescriptorTag[] descriptors = { DescriptorTag.Create(strTableLen), DescriptorTag.Create(elemsCount), DescriptorTag.Create(attrsCount), }; foreach (var desc in descriptors) { desc.WriteTo(ms); } // write RML data (+ string table) ms.Write(rmlBuffer); // profit!!! result = ms.ToArray(); } _stream.Write(result, 0, result.Length); Context.State = ContextStateType.End; }
public void Serialize(BinaryStream output) { output.Write(Name.Hash); output.Write(StringCount); foreach (var locStr in LocalizedStrings) { locStr.Serialize(output); } var vals = new List <DecompressedValues>(); var locStrs = new List <OasisLocalizedString>(); var len = 0; var crc = 0; foreach (var locStr in LocalizedStrings) { locStrs.Add(locStr); len += (locStr.Value.Length * 2); if ((len >= MAX_LENGTH) && (locStr.Enum != crc)) { var val = new DecompressedValues(locStrs); vals.Add(val); locStrs = new List <OasisLocalizedString>(); len = 0; crc = 0; } else { crc = locStr.Enum; } } if (locStrs.Count != 0) { var val = new DecompressedValues(locStrs); vals.Add(val); locStrs = new List <OasisLocalizedString>(); } output.Write(vals.Count); foreach (var val in vals) { var cpr = new CompressedValues(); using (var bs = new BinaryStream(1024)) { val.Serialize(bs); var buffer = bs.ToArray(); var size = buffer.Length; byte[] cprBuffer = null; var lz = new LZ4Compressor64(); var cprSize = lz.Compress(buffer, cprBuffer); cpr.CompressedBytes = cprBuffer; cpr.CompressedSize = cprSize; cpr.DecompressedSize = size; cpr.LastSortedCRC = val.SortedEnums.Last(); } cpr.Serialize(output); } }