コード例 #1
0
        private void PatchPointers()
        {
            _buffer?.Dispose();

            //Make a copy of the file's data that we can patch with offsets
            _buffer = new UnsafeBuffer(WorkingUncompressed.Length);
            Memory.Move(_buffer.Address, WorkingUncompressed.Address, (uint)WorkingUncompressed.Length);

            HKXHeader *           header  = (HKXHeader *)_buffer.Address;
            PhysicsOffsetSection *section = header->OffsetSections;

            for (int i = 0; i < header->_sectionCount; i++, section++)
            {
                int     dataOffset = section->_dataOffset;
                VoidPtr data = _buffer.Address + dataOffset;
                int     local = section->LocalPatchesLength, global = section->GlobalPatchesLength;

                if (section->ExportsLength > 0)
                {
                    Console.WriteLine("Has exports");
                }

                if (section->ImportsLength > 0)
                {
                    Console.WriteLine("Has imports");
                }

                //Global patches have to be made before local ones
                if (global > 0)
                {
                    //Global patches set offsets from this section to data in another section (or this one)
                    VoidPtr      start = data + section->_globalPatchesOffset;
                    GlobalPatch *patch = (GlobalPatch *)start;
                    while ((int)patch - (int)start < global && patch->_dataOffset >= 0 && patch->_pointerOffset >= 0)
                    {
                        //Make the pointer offset relative to itself so it's self-contained
                        int   ptrOffset = patch->_pointerOffset;
                        bint *ptr       = (bint *)(data + ptrOffset);
                        PhysicsOffsetSection *otherSection = &header->OffsetSections[patch->_sectionIndex];
                        int dOffset = patch->_dataOffset + otherSection->_dataOffset - dataOffset;
                        int offset  = dOffset - ptrOffset;
                        *   ptr     = offset;
                        patch++;
                    }
                }

                if (local > 0)
                {
                    //Local patches set offsets to data located elsewhere in this section
                    VoidPtr     start = data + section->_localPatchesOffset;
                    LocalPatch *patch = (LocalPatch *)start;
                    while ((int)patch - (int)start < local && patch->_dataOffset >= 0)
                    {
                        //Make the pointer offset relative to itself so it's self-contained
                        int   ptrOffset = patch->_pointerOffset;
                        bint *ptr       = (bint *)(data + ptrOffset);
                        *     ptr       = patch->_dataOffset - ptrOffset;
                        patch++;
                    }
                }
            }
        }
コード例 #2
0
        public override void OnPopulate()
        {
            HKXHeader *           header  = (HKXHeader *)_buffer.Address;
            PhysicsOffsetSection *section = header->OffsetSections;

            PhysicsOffsetSection *classes = &section[header->_classNameSectionIndex];
            sbyte *classNames             = (sbyte *)(_buffer.Address + classes->_dataOffset);

            VoidPtr dataAddr = classNames;
            VoidPtr baseAddr = dataAddr;

            while (dataAddr - baseAddr < classes->DataLength && *(byte *)(dataAddr + 4) == 9)
            {
                uint   signature = *(buint *)dataAddr;
                string c         = new string((sbyte *)dataAddr + 5);
                if (!_allSignatures.ContainsKey(c))
                {
                    _allSignatures.Add(c, signature);
                }

                dataAddr += 5 + c.Length + 1;
            }

            //Types have to be parsed first so that they can be used to parse the data last
            for (int i = 0; i < header->_sectionCount; i++, section++)
            {
                if (i == header->_classNameSectionIndex || i == header->_dataSectionIndex)
                {
                    continue;
                }

                int     dataOffset = section->_dataOffset;
                VoidPtr data       = _buffer.Address + dataOffset;

                int classNamePatchLength = section->ClassNamePatchesLength;
                if (classNamePatchLength > 0)
                {
                    HavokSectionNode sectionNode = new HavokSectionNode
                    {
                        //sectionNode._name = section->Name;
                        _name = "Classes"
                    };
                    sectionNode.Initialize(this, data, section->DataLength);

                    //HavokGroupNode classGroup = new HavokGroupNode() { _parent = sectionNode, _name = "Classes" };
                    //sectionNode.Children.Add(classGroup);

                    //HavokGroupNode enumGroup = new HavokGroupNode() { _parent = sectionNode, _name = "Enums" };
                    //sectionNode.Children.Add(enumGroup);

                    VoidPtr         start = data + section->_classNamePatchesOffset;
                    ClassNamePatch *patch = (ClassNamePatch *)start;

                    int x = 0;
                    while ((int)patch - (int)start < classNamePatchLength && patch->_dataOffset >= 0)
                    {
                        string className = new string(classNames + patch->_classNameOffset);
                        uint   signature = *(buint *)(classNames + (patch->_classNameOffset - 5));
                        if (!_mainTypeSignatures.ContainsKey(className))
                        {
                            _mainTypeSignatures.Add(className, signature);
                        }

                        HavokClassNode entry = GetClassNode(className, false);
                        if (entry != null)
                        {
                            entry._signature = signature;
                            entry._className = className;
                            entry.Initialize(sectionNode, data + patch->_dataOffset, 0);
                        }

                        patch++;
                        x++;
                    }

                    sectionNode._classCache = sectionNode._children.Select(b => b as HavokClassNode).ToList();
                    if (AssignClassParents)
                    {
                        sectionNode._children.Clear();
                        for (int r = 0; r < sectionNode._classCache.Count; r++)
                        {
                            HavokClassNode n = sectionNode._classCache[r];
                            if (n == null)
                            {
                                continue;
                            }

                            n.Populate(0);
                            n._parent = sectionNode;
                            if (n is hkClassNode)
                            {
                                hkClassNode c = n as hkClassNode;
                                if (!string.IsNullOrEmpty(c.ParentClass))
                                {
                                    for (int w = 0; w < sectionNode._classCache.Count; w++)
                                    {
                                        HavokClassNode n2 = sectionNode._classCache[w];
                                        if (w != r && n2 is hkClassNode && n2.Name == c.ParentClass)
                                        {
                                            n._parent = n2;
                                        }
                                    }
                                }
                            }
                        }

                        foreach (HavokClassNode n in sectionNode._classCache)
                        {
                            if (n == null)
                            {
                                continue;
                            }

                            if (n._parent._children == null)
                            {
                                n._parent._children = new List <ResourceNode>();
                            }

                            n._parent._children.Add(n);
                        }
                    }

                    foreach (HavokClassNode classNode in sectionNode._classCache)
                    {
                        if (classNode is hkClassNode)
                        {
                            hkClassNode c = classNode as hkClassNode;
                            c.GetInheritance();
                        }
                    }
                }
            }

            //Parse data using class types, unless the data is explicitly supported
            if (header->_dataSectionIndex >= 0)
            {
                section = &header->OffsetSections[header->_dataSectionIndex];
                int     dataOffset = section->_dataOffset;
                VoidPtr data       = _buffer.Address + dataOffset;

                int classNamePatchLength = section->ClassNamePatchesLength;
                if (classNamePatchLength > 0)
                {
                    HavokSectionNode sectionNode = new HavokSectionNode
                    {
                        //sectionNode._name = section->Name;
                        _name = "Instances"
                    };
                    sectionNode.Initialize(this, data, section->DataLength);
                    sectionNode._classCache = new List <HavokClassNode>();
                    _dataSection            = sectionNode;

                    uint rootOffset = header->_rootClassNameOffset;

                    VoidPtr         start = data + section->_classNamePatchesOffset;
                    ClassNamePatch *patch = (ClassNamePatch *)start;

                    int x = 0;
                    while ((int)patch - (int)start < classNamePatchLength && patch->_dataOffset >= 0)
                    {
                        string className = new string(classNames + patch->_classNameOffset);
                        uint   signature = *(buint *)(classNames + (patch->_classNameOffset - 5));

                        if (!_mainDataSignatures.ContainsKey(className))
                        {
                            _mainDataSignatures.Add(className, signature);
                        }

                        HavokClassNode entry = GetClassNode(className);
                        if (entry != null && patch->_classNameOffset == rootOffset)
                        {
                            new HavokMetaObjectNode(entry as hkClassNode)
                            {
                                _signature = signature
                            }
                            .Initialize(sectionNode, data + patch->_dataOffset, 0);
                        }

                        patch++;
                        x++;
                    }
                }
            }
        }