예제 #1
0
        public void LoadXml(string filename)
        {
            Libraries = new List <EntityLibrary>();

            var root = Path.GetDirectoryName(filename);

            Debug.WriteLine(">> Loading XML file...");
            var xml = new XmlDocument();

            xml.Load(filename);

            var libsElem = xml.DocumentElement;

            if ((libsElem == null) || (libsElem.Name != "EntityLibraries"))
            {
                throw new InvalidOperationException("Not a valid EntityLibraries node");
            }

            var attr32Bit = new AttributeData(DataType.Bool, libsElem.GetAttribute("Use32Bit"));

            Use32Bit = attr32Bit.ToBool();

            Debug.WriteLine(">> Loading libraries...");
            foreach (var node in libsElem.ChildNodes.OfType <XmlElement>())
            {
                if (node.Name != "EntityLibrary")
                {
                    throw new InvalidOperationException($"What the hell do I do with a '{node.Name}' element?!");
                }

                var file = node.GetAttribute("File");

                if (file != null)
                {
                    var libName = Path.GetFileNameWithoutExtension(file);
                    var libFile = Path.Combine(root, file);

                    var libDoc = new XmlDocument();
                    libDoc.Load(libFile);

                    var library = new EntityLibrary()
                    {
                        Use32Bit = Use32Bit,
                        Name     = libName,
                    };

                    library.Deserialize(libDoc);

                    Libraries.Add(library);
                    Console.WriteLine($" > Loaded library '{libName}' via XML");
                }
                else
                {
                    throw new InvalidOperationException("Sorry, cannot load embedded EntityLibrary nodes :(");
                }
            }

            Console.WriteLine($"Processed {Libraries.Count} XML libraries and collected {Utils.GetTotalNumberOfNodes(GetNodeClass())} nodes in total.");
        }
예제 #2
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.");
            }
        }