public void AddStructureInfo(MetaName name) { if (!StructureInfos.ContainsKey(name)) { MetaStructureInfo si = MetaTypes.GetStructureInfo(name); if (si != null) { StructureInfos[name] = si; } } }
private static byte[] Traverse(XmlNode node, MetaBuilder mb, MetaName type = 0, bool isRoot = false) { if (type == 0) { type = (MetaName)(uint)GetHash(node.Name); } var infos = MetaTypes.GetStructureInfo(type); if (infos != null) { byte[] data = new byte[infos.StructureSize]; var arrayResults = new ArrayResults(); arrayResults.Structures = new Dictionary <int, Array_Structure>(); arrayResults.StructurePointers = new Dictionary <int, Array_StructurePointer>(); arrayResults.UInts = new Dictionary <int, Array_uint>(); arrayResults.UShorts = new Dictionary <int, Array_ushort>(); arrayResults.UBytes = new Dictionary <int, Array_byte>(); arrayResults.Floats = new Dictionary <int, Array_float>(); arrayResults.Float_XYZs = new Dictionary <int, Array_Vector3>(); arrayResults.Hashes = new Dictionary <int, Array_uint>(); Array.Clear(data, 0, infos.StructureSize); MetaStructureEntryInfo_s arrEntry = new MetaStructureEntryInfo_s(); if (isRoot) { mb.EnsureBlock(type); } for (int i = 0; i < infos.Entries.Length; i++) { var entry = infos.Entries[i]; var cnode = GetEntryNode(node.ChildNodes, entry); if (entry.EntryNameHash == MetaName.ARRAYINFO) { arrEntry = entry; continue; } if (cnode == null) { continue; } switch (entry.DataType) { case MetaStructureEntryDataType.Array: { TraverseArray(cnode, mb, arrEntry, entry.DataOffset, arrayResults); break; } case MetaStructureEntryDataType.ArrayOfBytes: { GetParsedArrayOfBytes(cnode, data, entry, arrEntry); break; } case MetaStructureEntryDataType.ArrayOfChars: { int offset = entry.DataOffset; var split = Split(cnode.InnerText, 2); for (int j = 0; j < split.Length; j++) { byte val = Convert.ToByte(split[j], 16); data[offset] = val; offset += sizeof(byte); } break; } case MetaStructureEntryDataType.Boolean: { byte val = (cnode.Attributes["value"].Value == "false") ? (byte)0 : (byte)1; data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.ByteEnum: { byte val = Convert.ToByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.CharPointer: { if (!string.IsNullOrEmpty(cnode.InnerText)) { var ptr = mb.AddStringPtr(cnode.InnerText); var val = MetaTypes.ConvertToBytes(ptr); Buffer.BlockCopy(val, 0, data, entry.DataOffset, val.Length); } break; } case MetaStructureEntryDataType.DataBlockPointer: { // TODO break; } case MetaStructureEntryDataType.Float: { float val = FloatUtil.Parse(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.Float_XYZ: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); break; } case MetaStructureEntryDataType.Float_XYZW: { float x = FloatUtil.Parse(cnode.Attributes["x"].Value); float y = FloatUtil.Parse(cnode.Attributes["y"].Value); float z = FloatUtil.Parse(cnode.Attributes["z"].Value); float w = FloatUtil.Parse(cnode.Attributes["w"].Value); Write(x, data, entry.DataOffset); Write(y, data, entry.DataOffset + sizeof(float)); Write(z, data, entry.DataOffset + sizeof(float) * 2); Write(w, data, entry.DataOffset + sizeof(float) * 3); break; } case MetaStructureEntryDataType.Hash: { var hash = GetHash(cnode.InnerText); Write(hash, data, entry.DataOffset); break; } case MetaStructureEntryDataType.IntEnum: case MetaStructureEntryDataType.IntFlags1: case MetaStructureEntryDataType.IntFlags2: { var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); mb.AddEnumInfo(_infos.EnumNameHash); int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.ShortFlags: { var _infos = MetaTypes.GetEnumInfo(entry.ReferenceKey); mb.AddEnumInfo(_infos.EnumNameHash); int val = GetEnumInt(entry.ReferenceKey, cnode.InnerText); Write((short)val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.SignedByte: { var val = Convert.ToSByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = (byte)val; break; } case MetaStructureEntryDataType.SignedInt: { var val = Convert.ToInt32(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.SignedShort: { var val = Convert.ToInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } case MetaStructureEntryDataType.Structure: { var struc = Traverse(cnode, mb, entry.ReferenceKey); if (struc != null) { Buffer.BlockCopy(struc, 0, data, entry.DataOffset, struc.Length); } break; } case MetaStructureEntryDataType.StructurePointer: { // TODO break; } case MetaStructureEntryDataType.UnsignedByte: { var val = Convert.ToByte(cnode.Attributes["value"].Value); data[entry.DataOffset] = val; break; } case MetaStructureEntryDataType.UnsignedInt: { switch (entry.EntryNameHash) { case MetaName.color: { var val = Convert.ToUInt32(cnode.Attributes["value"].Value, 16); Write(val, data, entry.DataOffset); break; } default: { var val = Convert.ToUInt32(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } } break; } case MetaStructureEntryDataType.UnsignedShort: { var val = Convert.ToUInt16(cnode.Attributes["value"].Value); Write(val, data, entry.DataOffset); break; } default: break; } } arrayResults.WriteArrays(data); mb.AddStructureInfo(infos.StructureNameHash); if (isRoot) { mb.AddItem(type, data); } return(data); } return(null); }