private static void RecursiveGetClassIDsClasses(ref Dictionary <HavokClassNode, int> classIDs, HavokNode node, ResourceNode e) { if (e is hkClassNode) { hkClassNode type = e as hkClassNode; if (!string.IsNullOrEmpty(type.ParentClass)) { HavokClassNode c = node.GetClassNode(type.ParentClass); classIDs.Add(c, classIDs.Count + 1); } ResourceNode members = type.FindChild("Members", false); foreach (hkClassMemberNode member in members.Children) { if (!string.IsNullOrEmpty(member._class)) { HavokClassNode c = node.GetClassNode(member._class); classIDs.Add(c, classIDs.Count + 1); } if (!string.IsNullOrEmpty(member._enum)) { HavokClassNode c = node.GetClassNode(member._enum); classIDs.Add(c, classIDs.Count + 1); } } if (!classIDs.ContainsKey(type)) { classIDs.Add(type, classIDs.Count + 1); } } }
public void WriteParams(System.Xml.XmlWriter writer, Dictionary <HavokClassNode, int> classNodes) { writer.WriteStartElement("hkobject"); { writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "name"); writer.WriteString(Name); writer.WriteEndElement(); HavokClassNode c = string.IsNullOrEmpty(_class) ? null : HavokNode.GetClassNode(_class); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "class"); writer.WriteString(c != null ? HavokXML.GetObjectName(classNodes, c) : "null"); writer.WriteEndElement(); HavokClassNode e = string.IsNullOrEmpty(_enum) ? null : HavokNode.GetClassNode(_enum); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "enum"); writer.WriteString(e != null ? HavokXML.GetObjectName(classNodes, e) : "null"); writer.WriteEndElement(); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "type"); string type = Type.ToString(); if (type == "TYPE_CSTRING") { type = "TYPE_STRINGPTR"; } writer.WriteString(type); writer.WriteEndElement(); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "subtype"); writer.WriteString(SubType.ToString()); writer.WriteEndElement(); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "cArraySize"); writer.WriteString(ArraySize.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "flags"); writer.WriteString(((int)Flags).ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); writer.WriteStartElement("hkparam"); writer.WriteAttributeString("name", "offset"); writer.WriteString(OffsetInStruct.ToString(CultureInfo.InvariantCulture)); writer.WriteEndElement(); writer.WriteComment(" attributes SERIALIZE_IGNORED "); } writer.WriteEndElement(); }
public override void OnPopulate() { hkVariant * v = (hkVariant *)Data; hkClass * classData = (hkClass *)v->_classPtr.OffsetAddress; HavokClassNode entry = HavokNode.GetClassNode(new String((sbyte *)classData->_namePtr.OffsetAddress), true); if (entry != null) { new HavokMetaObjectNode(entry as hkClassNode) .Initialize(this, v->_objectPtr.OffsetAddress, classData->_size); } }
private static void RecursiveGetClassIDsData(ref Dictionary <HavokClassNode, int> classIDs, HavokNode node, ResourceNode e) { if (e is HavokMetaObjectNode || e is hkClassNode) { HavokClassNode data = e as HavokClassNode; HavokClassNode type = node.GetClassNode(data._className); RecursiveGetClassIDsClasses(ref classIDs, node, type); classIDs.Add(data, classIDs.Count + 1); } for (int i = e.Children.Count - 1; i >= 0; i--) { RecursiveGetClassIDsData(ref classIDs, node, e.Children[i]); } }
public override void WriteParams(System.Xml.XmlWriter writer, Dictionary <HavokClassNode, int> classNodes) { if (Children.Count > 0) { HavokClassNode n = Children[0] as HavokClassNode; if (n is HavokMetaObjectNode || n is hkClassNode) { writer.WriteString(HavokXML.GetObjectName(classNodes, n)); } else { n.WriteParams(writer, classNodes); } } }
public override void WriteParams(System.Xml.XmlWriter writer, Dictionary <HavokClassNode, int> classNodes) { writer.WriteAttributeString("numelements", Children.Count.ToString(System.Globalization.CultureInfo.InvariantCulture)); writer.WriteString(" "); foreach (HavokClassNode c in Children) { //Arrays embed parameters instead of pointing to an object containing them elsewhere HavokClassNode c2 = c; if (c is cmPointerNode && c.Children.Count > 0) { c2 = c.Children[0] as HavokClassNode; } if (c2 is HavokMetaObjectNode || c2 is hkClassNode) { ResourceNode[] nodes = c2.FindChildrenByClassType(null, typeof(HavokMetaObjectNode)); if (nodes == null && nodes.Length == 0) { writer.WriteStartElement("hkobject"); c2.WriteParams(writer, classNodes); writer.WriteEndElement(); } else { writer.WriteString(HavokXML.GetObjectName(classNodes, c2)); } } else if (c2 is cmStringNode) { writer.WriteStartElement("hkstring"); c2.WriteParams(writer, classNodes); writer.WriteEndElement(); } else { c2.WriteParams(writer, classNodes); } writer.WriteString(" "); } }
public HavokClassNode GetClassNode(string className, bool searchClasses = true) { HavokClassNode e = null; if (_classNodeTypes.ContainsKey(className)) { e = Activator.CreateInstance(_classNodeTypes[className]) as HavokClassNode; } if (e == null && searchClasses) { foreach (HavokSectionNode section in Children) { if (section._classCache != null) { foreach (HavokClassNode c in section._classCache) { if (c.Name == className) { e = c; break; } } } if (e != null) { break; } } } if (e == null) { Console.WriteLine("Unsupported class type: " + className); } return(e); }
public override void OnPopulate() { HKXHeader * header = (HKXHeader *)_buffer.Address; PhysicsOffsetSection *section = header->OffsetSections; PhysicsOffsetSection *classes = §ion[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++; } } } }
public static string GetObjectName(Dictionary <HavokClassNode, int> classNodes, HavokClassNode classNode) { return("#" + classNodes[classNode].ToString().PadLeft(4, '0')); }
public static void Serialize(HavokNode node, string outFile) { using (FileStream stream = new FileStream(outFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 0x1000, FileOptions.SequentialScan)) { using (XmlWriter writer = XmlWriter.Create(stream, _writerSettings)) { writer.Flush(); stream.Position = 0; node.Populate(); Dictionary <HavokClassNode, int> classIDs = new Dictionary <HavokClassNode, int>(); int i = 1; foreach (HavokSectionNode s in node.Children) { foreach (HavokClassNode c in s._classCache) { if (!classIDs.ContainsKey(c)) { classIDs.Add(c, i++); } } } //RecursiveGetClassIDsData(ref classIDs, node, node._dataSection); HavokClassNode rootClass = node._dataSection.Children[0] as HavokClassNode; List <HavokSectionNode> sections = node.Children.Select(x => x as HavokSectionNode) .Where(x => x != node._dataSection).ToList(); sections.Add(node._dataSection); writer.WriteStartDocument(); { writer.WriteStartElement("hkpackfile"); writer.WriteAttributeString("classversion", "11"); writer.WriteAttributeString("contentsversion", "hk_2014.1.0-r1"); writer.WriteAttributeString("toplevelobject", GetObjectName(classIDs, rootClass)); writer.WriteAttributeString("maxpredicate", "21"); writer.WriteAttributeString("predicates", ""); { foreach (HavokSectionNode s in sections) { writer.WriteStartElement("hksection"); writer.WriteAttributeString("name", s.Name == "Classes" ? "__types__" : "__data__"); { for (int x = s._classCache.Count - 1; x >= 0; x--) { HavokClassNode c = s._classCache[x]; //HavokCommonArrayNode array = null; //if (c.Parent is cmPointerNode && c.Parent.Parent is HavokCommonArrayNode) // array = c.Parent.Parent as HavokCommonArrayNode; //else if (c.Parent is HavokCommonArrayNode) // array = c.Parent as HavokCommonArrayNode; //if (array != null) //{ // //ResourceNode[] nodes = array.FindChildrenByClassType(null, typeof(HavokMetaObjectNode)); // //if (nodes != null && nodes.Length > 0) // continue; //} writer.WriteStartElement("hkobject"); writer.WriteAttributeString("name", GetObjectName(classIDs, c)); writer.WriteAttributeString("class", SwapName(c._className)); writer.WriteAttributeString("signature", GetSignature(c._className)); { c.WriteParams(writer, classIDs); } writer.WriteEndElement(); } } writer.WriteEndElement(); } } writer.WriteEndElement(); } writer.WriteEndDocument(); } } }
public void GetInheritance() { _inheritance = new List <hkClassNode>(); ResourceNode current = this; //First, get classes inheriting this one TOP: bool found = false; if (current != null) { foreach (HavokSectionNode section in HavokNode.Children) { if (section._classCache != null && section != HavokNode._dataSection) { foreach (HavokClassNode c in section._classCache) { hkClassNode x = c as hkClassNode; if (x != null && x != this && x.ParentClass == current.Name) { current = x; _inheritance.Insert(0, x); found = true; break; } } } if (found) { break; } } } if (found) { goto TOP; } current = this; //Now add this class and the classes it inherits while (current != null && current is hkClassNode) { hkClassNode cNode = (hkClassNode)current; _inheritance.Add(cNode); if (HavokNode.AssignClassParents) { current = current.Parent; } else if (!String.IsNullOrEmpty(cNode.ParentClass)) { current = null; HavokClassNode parent = HavokNode.GetClassNode(cNode.ParentClass); if (parent is hkClassNode) { current = parent; } } } //Start with the eldest class, added last _inheritance.Reverse(); }
public override void OnPopulate() { VoidPtr addr = WorkingUncompressed.Address; foreach (hkClassMemberNode member in _memberArray) { hkClassMember.Type type = member.Type; bool zero = type == hkClassMember.Type.TYPE_ZERO; if (zero) { type = member.SubType; } hkClassNode memberClass = null; hkClassEnumNode memberEnum = null; if (!string.IsNullOrEmpty(member._class)) { HavokClassNode c = HavokNode.GetClassNode(member._class); if (c is hkClassNode) { memberClass = c as hkClassNode; } if (memberClass == null) { Console.WriteLine("Could not find " + member._class + " class"); } } if (!string.IsNullOrEmpty(member._enum)) { //Loop through inheritance starting with the eldest class, added last foreach (hkClassNode c in _classNode._inheritance) { ResourceNode enums = c.FindChild("Enums", false); if (enums != null) { foreach (hkClassEnumNode e in enums.Children) { if (e.Name == member._enum) { memberEnum = e; break; } } } } if (memberEnum == null) { Console.WriteLine("Could not find " + member._enum + " enum in " + _classNode.Name + " class"); } } ClassMemberInstanceNode instance = TryGetMember(type); if (instance != null) { switch (type) { case hkClassMember.Type.TYPE_SIMPLEARRAY: case hkClassMember.Type.TYPE_ARRAY: case hkClassMember.Type.TYPE_INPLACEARRAY: case hkClassMember.Type.TYPE_HOMOGENEOUSARRAY: case hkClassMember.Type.TYPE_POINTER: case hkClassMember.Type.TYPE_FUNCTIONPOINTER: type = member.SubType; break; } instance._isZero = zero; instance._name = member._name; instance._memberType = type; instance._memberFlags = member._flags; instance._classNode = memberClass; instance._enumNode = memberEnum; instance.Initialize(this, addr + member._structOffset, instance.GetSize()); } } }