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 Deserialize(BinaryStream stream) { var offset = stream.ReadInt32(); var length = offset - 4; Data = new byte[length]; if (stream.Read(Data, 0, length) != length) { throw new FormatException(); } var blockCount = stream.ReadInt32(); Blocks = new List <Block>(); for (int i = 0; i < blockCount; i++) { var block = new Block() { VirtualOffset = stream.ReadUInt32(), FileOffset = stream.ReadUInt32(), }; block.IsCompressed = (block.FileOffset & 0x80000000) != 0; block.FileOffset &= 0x7FFFFFFF; Blocks.Add(block); } if (Blocks.Count == 0) { throw new FormatException(); } if (Blocks.First().FileOffset != 4) { throw new FormatException(); } if (Blocks.Last().FileOffset != (4 + length)) { throw new FormatException(); } }
public void Deserialize(BinaryStream stream) { var ptr = (int)stream.Position; var nD = DescriptorTag.Read(stream, ReferenceType.Offset); if (nD.IsOffset) { stream.Position = nD.Value; Deserialize(stream); // move past offset stream.Position = (ptr + nD.Size); } else { var size = nD.Value; Buffer = new byte[size]; stream.Read(Buffer, 0, size); } }
public unsafe void Deserialize(BinaryStream stream) { var buffer = new byte[0x24]; var len = stream.Read(buffer, 0, buffer.Length); IsValid = (len != 0); if (!IsValid) return; fixed(byte *ptr = buffer) { IsNomad = (*(int *)ptr == Nomad.Magic); if (!IsNomad) { // rml hacks if (*(short *)ptr == 0x00) { IsNomad = true; // allow the filters to do their job RootId = "RML_DATA"; Version = 1; return; } if ((*(int *)ptr == FCXMapSerializer.MGX_CONTAINER) || (*(int *)(ptr + 0x14) == FCXMapArchive.Signature)) { IsNomad = true; RootId = "FCXMapData"; Version = 2; return; } Offset = 2; while (*(int *)(ptr + Offset) != Nomad.Magic) { Offset += 2; if (Offset >= buffer.Length) { Offset = -1; break; } } // doesn't seem to be a nomad resource if (Offset == -1) { return; } // found the nomad header IsNomad = true; } var dataPtr = (ptr + Offset); switch (Offset) { // 'reference' files? case 0x2: if (*(ushort *)ptr == 0x8BF2) { HasExternalRef = true; } break; // sequence? //case 0x14: // todo } if (IsNomad) { var version = *(short *)(dataPtr + 4); Flags = *(short *)(dataPtr + 6); Version = version & 0xFF; VersionFlags = (version >> 8) & 0xFF; // validate EntityLibrary if (Version == 5) { if (VersionFlags != 0x40) { throw new InvalidDataException("Malformed EntityLibrary data!"); } } NumObjects = *(int *)(dataPtr + 8); NumSubObjects = *(int *)(dataPtr + 12); NumChildren = *(dataPtr + 16); if (NumChildren < 254) { RootId = *(int *)(dataPtr + 17); } else { NumChildren = *(int *)(dataPtr + 17); RootId = *(int *)(dataPtr + 21); } } } }
public void SaveBinary(string filename) { var root = GetNodeClass(); byte[] buffer; Debug.WriteLine(">> Generating binary data..."); using (var stream = new BinaryStream(BufferSize)) { // list of references sorted by their UID var references = GetEntityReferences(true); // we need to write the offset to our infos here Debug.WriteLine(">> Writing infos header..."); var ptr = stream.Position; stream.Position += 4; stream.Write(references.Count); Debug.WriteLine(">> Writing FCB header..."); stream.Write((int)Magic); stream.Write((short)Type); stream.Write((short)MagicNumber.FB); // ;) var nodesCount = Utils.GetTotalNumberOfNodes(root); var attrCount = root.Attributes.Count; if (attrCount == 0) { attrCount = 1; } var totalCount = (nodesCount + attrCount); stream.Write(totalCount); stream.Write(nodesCount); root.Serialize(stream); //Debug.WriteLine(">> Optimizing data..."); //using (var bs = new BinaryStream(BufferSize)) //{ // root.Serialize(bs); // // var dataLen = bs.Position; // bs.SetLength(dataLen); // // var data = OptimizedData.Create(nodesCount, bs.ToArray()); // data.WriteTo(stream); //} var refsOffset = (int)(Memory.Align(stream.Position, 8) - ptr); Debug.WriteLine(">> Writing infos offset..."); stream.Position = ptr; stream.Write(refsOffset); Debug.WriteLine(">> Writing infos..."); stream.Position = refsOffset; foreach (var reference in references) { var refData = new EntityReferenceData(reference) { Use32Bit = Use32Bit, }; refData.Serialize(stream); } var size = (int)stream.Position; buffer = new byte[size]; Debug.WriteLine(">> Copying to buffer..."); stream.Position = 0; stream.Read(buffer, 0, size); } Debug.WriteLine(">> Writing to file..."); File.WriteAllBytes(filename, buffer); }