public IPsoValue Parse(PsoFile meta) { var blockKeys = new List <int>(); var blocks = new List <List <IPsoValue> >(); var t1 = (PsoStructureInfo)null; var t2 = (PsoElementIndexInfo)null; var rootHash = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].NameHash; for (int i = 0; i < meta.DefinitionSection.Count; i++) { if (meta.DefinitionSection.EntriesIdx[i].NameHash == rootHash) { t1 = (PsoStructureInfo)meta.DefinitionSection.Entries[i]; t2 = meta.DefinitionSection.EntriesIdx[i]; } } var resultStructure = new PsoStructure(meta, t1, t2, null); var reader = new PsoDataReader(meta); reader.SetSectionIndex(meta.DataMappingSection.RootIndex - 1); reader.Position = 0; resultStructure.Read(reader); return(resultStructure); }
private void WriteStructureContentXml(PsoStructure value, XmlTextWriter writer) { foreach (var field in value.Values) { var fieldNameHash = field.Key; var fieldValue = field.Value; writer.WriteStartElement(GetNameForHash(fieldNameHash)); WriteStructureElementContentXml(fieldValue, writer); writer.WriteEndElement(); } }
public static IPsoValue Make(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo) { switch (entryInfo.Type) { case DataType.Array: { switch (entryInfo.Unk_5h) { case 0: { var t = structureInfo.Entries[entryInfo.ReferenceKey & 0x0000FFFF]; return(new PsoArray0(pso, structureInfo, t)); } case 1: { var typeIndex = entryInfo.ReferenceKey & 0x0000FFFF; var num = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF; var t = structureInfo.Entries[typeIndex]; return(new PsoArray1(pso, structureInfo, t, num)); } case 4: { var typeIndex = entryInfo.ReferenceKey & 0x0000FFFF; var num = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF; var t = structureInfo.Entries[typeIndex]; return(new PsoArray4(pso, structureInfo, t, num)); } default: { throw new Exception("Unsupported array type."); } } } case DataType.String: { switch (entryInfo.Unk_5h) { case 0: { var len = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF; return(new PsoString0(len)); } case 1: { return(new PsoString1()); } case 2: { return(new PsoString2()); } case 3: { return(new PsoString3()); } case 7: { return(new PsoString7()); } case 8: { return(new PsoString8()); } default: { throw new Exception("Unsupported string type."); } } } case DataType.Enum: { switch (entryInfo.Unk_5h) { case 0: { var entryValue = new PsoEnumInt(); entryValue.TypeInfo = GetEnumInfo(pso, entryInfo.ReferenceKey); return(entryValue); } case 2: { var entryValue = new PsoEnumByte(); entryValue.TypeInfo = GetEnumInfo(pso, entryInfo.ReferenceKey); return(entryValue); } default: { throw new Exception("Unsupported enum type."); } } } case DataType.Flags: { switch (entryInfo.Unk_5h) { case 0: { var entryValue = new PsoFlagsInt(); var sidx = entryInfo.ReferenceKey & 0x0000FFFF; if (sidx != 0xfff) { var reftype = structureInfo.Entries[sidx]; entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey); } return(entryValue); } case 1: { var entryValue = new PsoFlagsShort(); var sidx = entryInfo.ReferenceKey & 0x0000FFFF; var reftype = structureInfo.Entries[sidx]; entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey); return(entryValue); } case 2: { var entryValue = new PsoFlagsByte(); var sidx = entryInfo.ReferenceKey & 0x0000FFFF; var reftype = structureInfo.Entries[sidx]; entryValue.TypeInfo = GetEnumInfo(pso, reftype.ReferenceKey); return(entryValue); } default: { throw new Exception("Unsupported flags type."); } } } case DataType.Integer: { switch (entryInfo.Unk_5h) { case 0: return(new PsoIntSigned()); case 1: return(new PsoIntUnsigned()); default: throw new Exception("Unsupported integer type."); } } case DataType.Structure: { switch (entryInfo.Unk_5h) { case 0: { var t1 = GetStructureInfo(pso, entryInfo.ReferenceKey); var t2 = GetStructureIndexInfo(pso, entryInfo.ReferenceKey); var entryValue = new PsoStructure(pso, t1, t2, entryInfo); return(entryValue); } case 3: { return(new PsoStructure3(pso, structureInfo, entryInfo)); } default: { throw new Exception("Unsupported structure type."); } } } case DataType.Map: { switch (entryInfo.Unk_5h) { case 1: { var idx1 = entryInfo.ReferenceKey & 0x0000FFFF; var idx2 = (entryInfo.ReferenceKey >> 16) & 0x0000FFFF; var reftype1 = structureInfo.Entries[idx2]; var reftype2 = structureInfo.Entries[idx1]; return(new PsoMap(pso, structureInfo, reftype1, reftype2)); } default: throw new Exception("Unsupported PsoType5 type."); } } case DataType.INT_05h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoType5()); default: throw new Exception("Unsupported PsoType5 type."); } } case DataType.Byte: { switch (entryInfo.Unk_5h) { case 0: return(new PsoByte()); default: throw new Exception("Unsupported PsoByte type."); } } case DataType.Boolean: { switch (entryInfo.Unk_5h) { case 0: return(new PsoBoolean()); default: throw new Exception("Unsupported boolean type."); } } case DataType.Float: { switch (entryInfo.Unk_5h) { case 0: return(new PsoFloat()); default: throw new Exception("Unsupported float type."); } } case DataType.Float2: { switch (entryInfo.Unk_5h) { case 0: return(new PsoFloat2()); default: throw new Exception("Unsupported float2 type."); } } case DataType.Float3: { switch (entryInfo.Unk_5h) { case 0: return(new PsoFloat4A()); default: throw new Exception("Unsupported float3 type."); } } case DataType.Float4: { switch (entryInfo.Unk_5h) { case 0: return(new PsoFloat4B()); default: throw new Exception("Unsupported float4 type."); } } case DataType.TYPE_09h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoType9()); default: throw new Exception("Unsupported PsoType9 type."); } } case DataType.LONG_20h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoType32()); default: throw new Exception("Unsupported PsoType32 type."); } } case DataType.SHORT_1Eh: { switch (entryInfo.Unk_5h) { case 0: return(new PsoXXHalf()); default: throw new Exception("Unsupported PsoType30 type."); } } case DataType.SHORT_03h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoType3()); default: throw new Exception("Unsupported PsoType3 type."); } } case DataType.SHORT_04h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoType4()); default: throw new Exception("Unsupported PsoType4 type."); } } case DataType.LONG_01h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoXXByte()); default: throw new Exception("Unsupported PsoType1 type."); } } case DataType.TYPE_14h: { switch (entryInfo.Unk_5h) { case 0: return(new PsoFloat3()); default: throw new Exception("Unsupported PsoType20 type."); } } default: throw new Exception("Unsupported type."); } }
public PsoStructure ParseStructure(XmlNode node, PsoStructureXml info) { PsoStructure resultStructure = null; foreach (var x in strList) { if (x.Item1 == info.NameHash) { resultStructure = new PsoStructure(); resultStructure.psoSection = x.Item2; resultStructure.psoEntryInfo = new PsoElementIndexInfo(); resultStructure.psoEntryInfo.NameHash = x.Item1; } } resultStructure.Values = new Dictionary <int, IPsoValue>(); foreach (var xmlEntry in info.Entries) { XmlNode xmlNode = null; foreach (XmlNode x in node.ChildNodes) { var hash = GetHashForName(x.Name); if (hash == xmlEntry.NameHash) { xmlNode = x; } } PsoStructureEntryInfo entryInfo = null; foreach (var x in resultStructure.psoSection.Entries) { if (x.EntryNameHash == xmlEntry.NameHash) { entryInfo = x; } } var type = (DataType)xmlEntry.Type; if (type == DataType.Array) { var arrayType = (DataType)xmlEntry.ArrayType.Type; if (arrayType == DataType.Structure) { PsoArray arrayValue = ReadStructureArray(xmlNode, xmlEntry.ArrayType.TypeHash); arrayValue.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey]; resultStructure.Values.Add(xmlEntry.NameHash, arrayValue); } else if (arrayType == DataType.INT_0Bh) { PsoArray arryVal = Read11Array(xmlNode); arryVal.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey]; resultStructure.Values.Add(xmlEntry.NameHash, arryVal); } else if (arrayType == DataType.SHORT_0Fh) { PsoArray arryVal = Read14Array(xmlNode); arryVal.psoSection = resultStructure.psoSection.Entries[entryInfo.ReferenceKey]; resultStructure.Values.Add(xmlEntry.NameHash, arryVal); } else { throw new Exception("Unsupported array type."); } } else if (type == DataType.INT_06h) { resultStructure.Values.Add(xmlEntry.NameHash, ReadType6(xmlNode)); } else if (type == DataType.INT_0Bh) { resultStructure.Values.Add(xmlEntry.NameHash, ReadType11(xmlNode, xmlEntry.Unknown == 0)); } else if (type == DataType.BYTE_ENUM_VALUE) { resultStructure.Values.Add(xmlEntry.NameHash, ReadType14(xmlNode)); } else if (type == DataType.SHORT_0Fh) { resultStructure.Values.Add(xmlEntry.NameHash, ReadType15(xmlNode)); } else if (type == DataType.Structure) { var xmlInfo = FindAndCheckStructure(xmlEntry.TypeHash, xmlNode); var structureValue = ParseStructure(xmlNode, xmlInfo); resultStructure.Values.Add(xmlEntry.NameHash, structureValue); } else { throw new Exception("Unsupported type."); } } return(resultStructure); }
public IPsoValue Parse(PsoFile meta) { var blockKeys = new List <int>(); var blocks = new List <List <IPsoValue> >(); var resultStructure = new PsoStructure(); resultStructure.pso = meta; var rootHash = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].NameHash; for (int i = 0; i < meta.DefinitionSection.Count; i++) { if (meta.DefinitionSection.EntriesIdx[i].NameHash == rootHash) { resultStructure.psoSection = (PsoStructureInfo)meta.DefinitionSection.Entries[i]; resultStructure.psoEntryInfo = meta.DefinitionSection.EntriesIdx[i]; } } var reader = new DataReader(new MemoryStream(meta.DataSection.Data), Endianess.BigEndian); reader.Position = meta.DataMappingSection.Entries[meta.DataMappingSection.RootIndex - 1].Offset; resultStructure.Read(reader); var stack = new Stack <PsoStructure>(); stack.Push(resultStructure); while (stack.Count > 0) { var x = stack.Pop(); foreach (var ee in x.psoSection.Entries) { if (ee.EntryNameHash == 0x100) { continue; } var value = x.Values[ee.EntryNameHash]; if (value is PsoStructure) { stack.Push((PsoStructure)value); } if (value is PsoArray) { var arrayValue = (PsoArray)value; switch (arrayValue.psoSection.Type) { case DataType.Structure: { if (arrayValue.NumberOfEntries > 0) { arrayValue.Entries = new List <IPsoValue>(); reader.Position = meta.DataMappingSection.Entries[arrayValue.BlockIndex - 1].Offset + arrayValue.Offset; for (int i = 0; i < arrayValue.NumberOfEntries; i++) { PsoStructure item = new PsoStructure(); item.pso = meta; item.psoSection = null; for (int y = 0; y < meta.DefinitionSection.Count; y++) { if (meta.DefinitionSection.EntriesIdx[y].NameHash == arrayValue.psoSection.ReferenceKey) { item.psoSection = (PsoStructureInfo)meta.DefinitionSection.Entries[y]; item.psoEntryInfo = meta.DefinitionSection.EntriesIdx[y]; } } item.Read(reader); arrayValue.Entries.Add(item); stack.Push(item); } } break; } case DataType.INT_0Bh: { if (arrayValue.NumberOfEntries > 0) { arrayValue.Entries = new List <IPsoValue>(); reader.Position = meta.DataMappingSection.Entries[arrayValue.BlockIndex - 1].Offset + arrayValue.Offset; for (int i = 0; i < arrayValue.NumberOfEntries; i++) { PsoType11 item = new PsoType11(0); item.Read(reader); arrayValue.Entries.Add(item); } } break; } default: throw new System.Exception("Unknown array type."); } } } } return(resultStructure); }
private void WriteStructure(MetaDataWriter writer, PsoStructure value) { var updateStack = new Stack <IPsoValue>(); // build stack for update... var structuresToCheck = new Stack <PsoStructure>(); structuresToCheck.Push(value); while (structuresToCheck.Count > 0) { var structureToCheck = structuresToCheck.Pop(); // add structure to list of occurring structures usedStructureKeys.Add(structureToCheck.psoEntryInfo.NameHash); foreach (var structureEntryToCheck in structureToCheck.Values) { if (structureEntryToCheck.Value is PsoArray) { updateStack.Push(structureEntryToCheck.Value); var arrayStructureEntryToCheck = structureEntryToCheck.Value as PsoArray; if (arrayStructureEntryToCheck.Entries != null) { for (int k = arrayStructureEntryToCheck.Entries.Count - 1; k >= 0; k--) { var x = arrayStructureEntryToCheck.Entries[k]; if (x is PsoStructure) { structuresToCheck.Push(x as PsoStructure); } } } } if (structureEntryToCheck.Value is PsoStructure) { structuresToCheck.Push((PsoStructure)structureEntryToCheck.Value); } } } // update structures... while (updateStack.Count > 0) { var v = updateStack.Pop(); if (v is PsoArray) { var arrayValue = (PsoArray)v; if (arrayValue.Entries != null) { if (arrayValue.psoSection.Type == DataType.Structure) { writer.SelectBlockByNameHash((int)arrayValue.psoSection.ReferenceKey); writer.Position = writer.Length; } else if (arrayValue.psoSection.Type == DataType.INT_0Bh) { writer.SelectBlockByNameHash(6); writer.Position = writer.Length; } else { throw new Exception("Unknown array type."); } arrayValue.BlockIndex = writer.BlockIndex + 1; arrayValue.Offset = (int)writer.Position; arrayValue.NumberOfEntries = arrayValue.Entries.Count; foreach (var entry in arrayValue.Entries) { entry.Write(writer); } } else { arrayValue.BlockIndex = 0; arrayValue.Offset = 0; arrayValue.NumberOfEntries = 0; } } } // now only the root itself is left... writer.SelectBlockByNameHash(value.psoEntryInfo.NameHash); writer.Position = writer.Length; value.Write(writer); }