示例#1
0
        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);
        }
示例#2
0
        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);
            }
        }
示例#3
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());
        }
示例#4
0
 public void Deserialize(BinaryStream input)
 {
     LastSortedCRC    = input.ReadInt32();
     CompressedSize   = input.ReadInt32();
     DecompressedSize = input.ReadInt32();
     CompressedBytes  = input.ReadBytes(CompressedSize);
 }
示例#5
0
        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);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
            }
        }
示例#8
0
        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);
        }