Example #1
0
        public void LoadBinary(string filename)
        {
            using (var stream = new BinaryStream(filename))
            {
                Debug.WriteLine(">> Reading FCB header...");
                var magic = stream.ReadInt32();

                if (magic != Magic)
                {
                    throw new InvalidOperationException("Bad magic, no FCB data to parse!");
                }

                var type = stream.ReadInt16();

                if (type != Type)
                {
                    throw new InvalidOperationException("FCB library reported the incorrect type?!");
                }

                stream.Position += 2; // ;)

                var objCount  = stream.ReadInt32();
                var attrCount = stream.ReadInt32();

                // read fcb data
                Debug.WriteLine(">> Reading objects...");

                var objRefs = new List <NodeObject>();
                Root = new NodeObject(stream, objRefs);

                Console.WriteLine($"Finished reading {Root.Children.Count} objects. Collected {objRefs.Count} nodes in total.");
            }
        }
Example #2
0
        public void Deserialize(BinaryStream stream)
        {
            Debug.WriteLine(">> Reading FCB header...");
            var magic = stream.ReadInt32();

            if (magic != Magic)
            {
                throw new InvalidOperationException("Bad magic, no FCB data to parse!");
            }

            Type = (ContainerType)stream.ReadInt16();

            stream.Position += 2; // ;)

            var totalCount = stream.ReadInt32();
            var nodesCount = stream.ReadInt32();

            // read fcb data
            switch (Type)
            {
            case ContainerType.Objects:
            {
                Debug.WriteLine(">> Reading objects...");

                var objRefs = new List <NodeObject>();
                Root = new NodeObject(stream, objRefs);
            }
            break;

            case ContainerType.Classes:
            {
                Debug.WriteLine(">> Reading classes...");
                Root = new NodeClass(stream);
            }
            break;
            }
        }
Example #3
0
        public void LoadBinary(string filename)
        {
            using (var stream = new BinaryStream(filename))
            {
                Debug.WriteLine(">> Reading infos header...");
                var infosOffset = stream.ReadInt32();
                var infosCount  = stream.ReadInt32();

                Use32Bit = ((stream.Length - (infosCount * 0xC)) == infosOffset);

                Debug.WriteLine(">> Reading FCB header...");
                var magic = stream.ReadInt32();

                if (magic != Magic)
                {
                    throw new InvalidOperationException("Bad magic, no FCB data to parse!");
                }

                var type = stream.ReadInt16();

                if (type != Type)
                {
                    throw new InvalidOperationException("FCB library reported the incorrect type?!");
                }

                stream.Position += 2;                // ;)

                var totalCount = stream.ReadInt32(); // * 3
                var nodesCount = stream.ReadInt32(); // * 4

                var dataOffset = (int)stream.Position;

                var memSize      = ((totalCount * 3) + nodesCount) * 4;
                var memSizeAlign = Memory.Align(memSize, 16);

#if DEBUG
                Console.WriteLine("[Library.Header]");
                Console.WriteLine($"  Total: {totalCount}");
                Console.WriteLine($"  Nodes: {nodesCount}");
                Console.WriteLine($"  MemSize: {memSize:X8}");
#endif

                // read the infos first!
                Debug.WriteLine(">> Reading infos...");
                stream.Position = infosOffset;

                var nInfosTotal = 0;
                var nInfosNodes = 0;

                var refDatas = new Dictionary <int, EntityReferenceData>(infosCount);

                for (int i = 0; i < infosCount; i++)
                {
                    var refData = new EntityReferenceData(stream, Use32Bit);

                    nInfosTotal += refData.TotalCount;
                    nInfosNodes += refData.NodesCount;

                    refDatas.Add(refData.Offset, refData);
                }

                var count1Diff = (totalCount - nInfosTotal);
                var count2Diff = (nodesCount - nInfosNodes);

#if DEBUG
                Console.WriteLine("[Library.Infos]");
                Console.WriteLine($"  Total: {nInfosTotal}");
                Console.WriteLine($"  Nodes: {nInfosNodes}");
                Console.WriteLine("[Library.Logging]");
                Console.WriteLine($"  TotalDiff: {count1Diff}");
                Console.WriteLine($"  NodesDiff: {count2Diff}");
#endif

                // read fcb data
                Debug.WriteLine(">> Reading libraries...");
                stream.Position = dataOffset;

                var root = new NodeClass(stream);

                Libraries = new List <EntityLibrary>(root.Children.Count);

                foreach (var library in root.Children)
                {
                    // deserialize from the class
                    var lib = new EntityLibrary()
                    {
                        Use32Bit = Use32Bit,
                    };

                    lib.Deserialize(library);

                    // update UIDs
                    foreach (var entry in lib.Entries)
                    {
                        var node   = entry.GroupNode;
                        var offset = node.Offset;

                        if (refDatas.ContainsKey(offset))
                        {
                            var entRef = refDatas[offset];
                            entry.UID = entRef.UID;
                        }
                    }

                    Libraries.Add(lib);
                }

                Console.WriteLine($"Finished reading {Libraries.Count} libraries. Collected {Utils.GetTotalNumberOfNodes(root)} nodes in total.");
            }
        }
Example #4
0
        protected NomadObject ReadObject_FmtB(BinaryStream stream, NomadObject parent = null)
        {
            Context.State = ContextStateType.Object;
            Context.ObjectIndex++;

            var ptr = (int)stream.Position;

            var nD = DescriptorTag.Read(stream, ReferenceType.Offset);

            NomadObject result = null;

            if (nD.IsOffset)
            {
                result = Context.GetRefByPtr(nD.Value) as NomadObject;

                // this should never happen
                if (result == null)
                {
                    throw new InvalidDataException("Malformed data!");
                }
            }
            else
            {
                var nChildren = nD.Value;

                var hash = stream.ReadInt32();
                var size = stream.ReadInt16();

                if (size == 0)
                {
                    throw new NotImplementedException("Zero-length nodes are not covered under TrumpCare(tm).");
                }

                var id = StringId.Parse(hash);

                result = new NomadObject(id);

                Context.AddRef(result, ptr);

                var attrsPtr = (int)stream.Position;
                var next     = (attrsPtr + size);

                var nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                var adjustPtr = false;

                if (nhD.IsOffset)
                {
                    stream.Position = nhD.Value;

                    // adjust ptr to attributes
                    attrsPtr += nhD.Size;
                    adjustPtr = true;

                    // read again
                    nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                    if (nhD.IsOffset)
                    {
                        throw new InvalidOperationException("Cannot have nested offsets!");
                    }
                }

                var nAttrs = nhD.Value;
                var hashes = new int[nAttrs];

                // read attribute hash list
                for (int i = 0; i < nAttrs; i++)
                {
                    hashes[i] = stream.ReadInt32();
                }

                // move to the attributes if needed
                if (adjustPtr)
                {
                    stream.Position = attrsPtr;
                }

                // deserialize attributes
                if (nAttrs > 0)
                {
                    ReadAttributes_FmtB(stream, result, hashes);
                }

                if (stream.Position != next)
                {
                    Context.LogDebug($"Something went wrong when reading attributes for '{result.Id}':");
                    Context.LogDebug($" - Expected to read {size} bytes but only read {stream.Position - attrsPtr}");

                    foreach (var attr in result.Attributes)
                    {
                        Context.LogDebug($" - '{attr.Id}' : {attr.Data.Type} ({attr.Data.Size} bytes)");
                    }

                    stream.Position = next;
                }

                // read children
                for (int n = 0; n < nChildren; n++)
                {
                    ReadObject_FmtB(stream, result);
                }
            }

            if (parent != null)
            {
                parent.Children.Add(result);
            }

            return(result);
        }
Example #5
0
        public override 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);

                stream.Position = (ptr + nD.Size);
            }
            else
            {
                Offset = ptr;

                var nChildren = nD.Value;

                Children = new List <NodeClass>(nChildren);

                var hash = stream.ReadInt32();
                var size = stream.ReadInt16();

                var name = StringHasher.ResolveHash(hash);

                if (name != null)
                {
                    Name = name;
                }
                else
                {
                    Hash = hash;
                }

                var attrsPtr = (int)stream.Position;
                var next     = (attrsPtr + size);

                if (size != 0)
                {
                    var nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                    var adjustPtr = false;

                    if (nhD.IsOffset)
                    {
                        stream.Position = nhD.Value;

                        // read again
                        nhD = DescriptorTag.Read(stream, ReferenceType.Offset);

                        if (nhD.IsOffset)
                        {
                            throw new InvalidOperationException("Cannot have nested offsets!");
                        }

                        // adjust ptr to attributes
                        attrsPtr += nhD.Size;
                        adjustPtr = true;
                    }

                    var nAttrs = nhD.Value;

                    Attributes = new List <NodeAttribute>(nAttrs);

                    for (int i = 0; i < nAttrs; i++)
                    {
                        var attr = new NodeAttribute(stream, Name);
                        Attributes.Add(attr);
                    }

                    // move to the attributes if needed
                    if (adjustPtr)
                    {
                        stream.Position = attrsPtr;
                    }

                    // deserialize attribute data
                    foreach (var attr in Attributes)
                    {
                        attr.Deserialize(stream);
                    }
                }
                else
                {
                    throw new NotImplementedException("Zero-length nodes are not covered under TrumpCare™.");
                }

                if (stream.Position != next)
                {
                    throw new InvalidOperationException("You dun f****d up, son!");
                }

                // read children
                for (int n = 0; n < nChildren; n++)
                {
                    var child = new NodeClass(stream);
                    Children.Add(child);
                }
            }
        }