protected NomadObject ReadMapData(BinaryStream stream) { var check = stream.ReadInt32(); var result = new NomadObject() { Id = "FCXMapData" }; if (check != 0x26) { // non-editor map? stream.Position -= 4; UID = stream.Read <Guid>(); ReadPadding(stream, 1); Version = 0; IsUserMap = false; } else { var magic = stream.ReadInt32(); if (magic != MGX_MAPDATA) { throw new InvalidDataException("Invalid FCX map data -- bad data magic!"); } Version = check; IsUserMap = true; ReadPadding(stream, 3); MetaData = ReadFCBChunk(stream, result); ConfigData = ReadFCBChunk(stream, result); ReadPadding(stream, 5); var thumbSize = stream.ReadInt32(); if (thumbSize > 0) { ThumbData = stream.ReadBytes(thumbSize); } ReadPadding(stream, 1); } var mapSize = (int)(stream.Length - stream.Position); MapData = stream.ReadBytes(mapSize); return(result); }
public void Serialize(BinaryStream stream, int baseOffset = 0) { if (Type == DataType.RML) { throw new InvalidOperationException("Cannot serialize RML data directly!"); } var ptr = (int)stream.Position; var oldSize = Size; if (Size > 0) { var writeData = true; if (CanBeCached) { if (WriteCache.IsCached(this)) { var cache = WriteCache.GetData(this); if (cache.Size == Size) { stream.Position = (cache.Offset + 1); var buf = stream.ReadBytes(cache.Size); var key = Memory.GetCRC32(Buffer); var bufKey = Memory.GetCRC32(buf); stream.Position = ptr; // slow as f**k, but there's no room for error if (key == bufKey) { var nD = DescriptorTag.CreateReference(cache.Offset, ReferenceType.Offset); nD.WriteTo(stream, baseOffset); writeData = false; } } } else { WriteCache.Cache(ptr, this); } } if (writeData) { var nD = DescriptorTag.Create(Size); nD.WriteTo(stream, baseOffset); stream.Write(Buffer); } } else { // nothing to write! stream.WriteByte(0); } }
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()); }
public void Deserialize(BinaryStream input) { LastSortedCRC = input.ReadInt32(); CompressedSize = input.ReadInt32(); DecompressedSize = input.ReadInt32(); CompressedBytes = input.ReadBytes(CompressedSize); }
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); }
public XElement CreateXmlElement(NomadObject obj, XElement parent = null) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var name = XName.Get(obj.Id); var elem = new XElement(name); if (parent != null) { parent.Add(elem); } foreach (var attr in obj.Attributes) { if (attr.Id == "RML_DATA") { using (var bs = new BinaryStream(attr.Data.Buffer)) { var rmlSize = bs.ReadInt32(); var rmlBuffer = bs.ReadBytes(rmlSize); using (var rs = new BinaryStream(rmlBuffer)) { var rmlData = new NomadRmlSerializer(); var rml = rmlData.Deserialize(rs); var rmlRoot = new XElement("RML_DATA"); var rmlElem = CreateXmlElement(rml, rmlRoot); elem.Add(rmlRoot); } } } else { CreateXmlAttribute(attr, elem); } } foreach (var child in obj.Children) { CreateXmlElement(child, elem); } return(elem); }
protected NomadObject ReadFCBChunk(BinaryStream stream, NomadObject parent) { var fcbSize = stream.ReadInt32(); var fcbData = stream.ReadBytes(fcbSize); using (var bs = new BinaryStream(fcbData)) { var serializer = new NomadResourceSerializer(); var root = serializer.Deserialize(bs); if (parent != null) { parent.Children.Add(root); } return(root); } }
protected NomadObject ReadObject_FmtA(BinaryStream stream, NomadObject parent = null) { Context.State = ContextStateType.Object; Context.ObjectIndex++; var ptr = (int)stream.Position; var nChildren = DescriptorTag.Read(stream, ReferenceType.Index); if (nChildren.Type == DescriptorType.Reference) { throw new InvalidOperationException("Cannot deserialize an object reference directly!"); } var hash = stream.ReadInt32(); var id = StringId.Parse(hash); var result = new NomadObject(id); Context.AddRef(result, ptr); if (result.IsRml) { var next = DescriptorTag.Read(stream, ReferenceType.Index); var rmlBase = (int)stream.Position; var rmlSize = stream.ReadInt32(); var rmlBuffer = stream.ReadBytes(rmlSize); using (var bs = new BinaryStream(rmlBuffer)) { var rmlData = new NomadRmlSerializer(); var rml = rmlData.Deserialize(bs); result.Children.Add(rml); } stream.Position = (rmlBase + next); } else { var nAttrs = DescriptorTag.Read(stream, ReferenceType.Index); for (int i = 0; i < nAttrs; i++) { ReadAttribute_FmtA(stream, result); } for (int i = 0; i < nChildren; i++) { var cP = (int)stream.Position; var cD = DescriptorTag.Read(stream, ReferenceType.Index); // rip if (cD.IsIndex) { var idx = cD.Value; var childRef = Context.GetRefByIdx(idx) as NomadObject; result.Children.Add(childRef); } else { // move back stream.Position = cP; ReadObject_FmtA(stream, result); } } } if (parent != null) { parent.Children.Add(result); } return(result); }