public PsoArray4(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo, int numberOfEntries) { this.pso = pso; this.structureInfo = structureInfo; this.entryInfo = entryInfo; this.numberOfEntries = numberOfEntries; }
public PsoStructureInfo GetStructureInfo(MetaName name) { PsoStructureInfo i = null; StructDict.TryGetValue(name, out i); return(i); }
public PsoStructure(PsoFile pso, PsoStructureInfo structureInfo, PsoElementIndexInfo entryIndexInfo, PsoStructureEntryInfo entryInfo) { this.pso = pso; this.structureInfo = structureInfo; this.entryIndexInfo = entryIndexInfo; this.entryInfo = entryInfo; this.Values = new Dictionary <int, IPsoValue>(); }
public void AddStructureInfo(MetaName name) { if (!StructureInfos.ContainsKey(name)) { PsoStructureInfo si = PsoInfo.GetStructureInfo(name); if (si != null) { StructureInfos[name] = si; } } }
public PsoMap( PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo keyEntryInfo, PsoStructureEntryInfo valueEntryInfo) { this.pso = pso; this.structureInfo = structureInfo; this.keyEntryInfo = keyEntryInfo; this.valueEntryInfo = valueEntryInfo; }
public static PsoStructureInfo GetStructureInfo(PsoFile meta, int structureKey) { PsoStructureInfo info = null; for (int i = 0; i < meta.DefinitionSection.Count; i++) { if (meta.DefinitionSection.EntriesIdx[i].NameHash == structureKey) { info = (PsoStructureInfo)meta.DefinitionSection.Entries[i]; } } return(info); }
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 PsoArray0(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo) { this.pso = pso; this.structureInfo = structureInfo; this.entryInfo = entryInfo; }
private void MetaBuildStructureInfos(PsoDefinitionXml xmlInfo) { //meta.DefinitionSection.EntriesIdx = new List<PsoElementIndexInfo>(); //meta.DefinitionSection.Entries = new List<PsoElementInfo>(); strList = new List <Tuple <int, PsoStructureInfo> >(); foreach (var xmlStructureInfo in xmlInfo.Structures) { var idxInfo = new PsoElementIndexInfo(); idxInfo.Offset = 0; idxInfo.NameHash = xmlStructureInfo.NameHash; var structureInfo = new PsoStructureInfo(); structureInfo.Type = 1; structureInfo.Unk = (byte)xmlStructureInfo.Unknown; structureInfo.StructureLength = xmlStructureInfo.Length; structureInfo.Entries = new List <PsoStructureEntryInfo>(); foreach (var xmlStructureEntryInfo in xmlStructureInfo.Entries) { var xmlArrayTypeStack = new Stack <PsoStructureEntryXml>(); var xmlArrayType = xmlStructureEntryInfo.ArrayType; while (xmlArrayType != null) { xmlArrayTypeStack.Push(xmlArrayType); xmlArrayType = xmlArrayType.ArrayType; } while (xmlArrayTypeStack.Count > 0) { xmlArrayType = xmlArrayTypeStack.Pop(); var arrayStructureEntryInfo = new PsoStructureEntryInfo(); arrayStructureEntryInfo.EntryNameHash = xmlArrayType.NameHash; arrayStructureEntryInfo.Type = (DataType)xmlArrayType.Type; arrayStructureEntryInfo.Unk_5h = (byte)xmlArrayType.Unknown; arrayStructureEntryInfo.DataOffset = (short)xmlArrayType.Offset; if (arrayStructureEntryInfo.Type == DataType.Array) { arrayStructureEntryInfo.ReferenceKey = (short)(structureInfo.Entries.Count - 1); } else { arrayStructureEntryInfo.ReferenceKey = 0; } arrayStructureEntryInfo.ReferenceKey = xmlArrayType.TypeHash; structureInfo.Entries.Add(arrayStructureEntryInfo); } var structureEntryInfo = new PsoStructureEntryInfo(); structureEntryInfo.EntryNameHash = xmlStructureEntryInfo.NameHash; structureEntryInfo.Type = (DataType)xmlStructureEntryInfo.Type; structureEntryInfo.Unk_5h = (byte)xmlStructureEntryInfo.Unknown; structureEntryInfo.DataOffset = (short)xmlStructureEntryInfo.Offset; if (structureEntryInfo.Type == DataType.Array) { structureEntryInfo.ReferenceKey = (short)(structureInfo.Entries.Count - 1); } else { structureEntryInfo.ReferenceKey = 0; } structureEntryInfo.ReferenceKey = xmlStructureEntryInfo.TypeHash; structureInfo.Entries.Add(structureEntryInfo); } strList.Add(new Tuple <int, PsoStructureInfo>(idxInfo.NameHash, structureInfo)); } }
private static void WriteMapNode(StringBuilder sb, int indent, PsoCont cont, int eoffset, PsoStructureEntryInfo entry, PsoStructureInfo structInfo, string ename) { var cind = indent + 1; var data = cont.Pso.DataSection.Data; switch (entry.Unk_5h) { default: ErrorXml(sb, cind, ename + ": Unexpected Map subtype: " + entry.Unk_5h.ToString()); break; case 1: var mapidx1 = entry.ReferenceKey & 0x0000FFFF; var mapidx2 = (entry.ReferenceKey >> 16) & 0x0000FFFF; var mapreftype1 = structInfo.Entries[mapidx2]; var mapreftype2 = structInfo.Entries[mapidx1]; var x1 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset)); //same as ref key? var x2 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset + 4)); //0? var x3 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset + 8)); //pointer? var x4 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset + 12)); // var x5 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset + 16)); //count/capacity? var x6 = MetaUtils.SwapBytes(BitConverter.ToInt32(data, eoffset + 20)); // //File.WriteAllText("C:\\CodeWalker.Projects\\testxml.xml", sb.ToString()); if (x1 != 0x1000000) { } if (x2 != 0) { } if (x4 != 0) { } if (x6 != 0) { } var xBlockId = x3 & 0xFFF; var xOffset = (x3 >> 12) & 0xFFFFF; var xCount1 = x5 & 0xFFFF; var xCount2 = (x5 >> 16) & 0xFFFF; //var x1a = x1 & 0xFFF; //block id? for another pointer? //var x1b = (x1 >> 12) & 0xFFFFF; //offset? //var x4u = (uint)x4; //var x4a = x4 & 0xFFF; //block id? //var x4b = (x4 >> 12) & 0xFFFFF; //offset? //var x2h = (MetaHash)(uint)x2; //var x6h = (MetaHash)(uint)x6; //if (x1a > 0) //{ } var xBlock = cont.Pso.GetBlock(xBlockId); if ((xBlock == null) && (xCount1 > 0)) { ErrorXml(sb, cind, ename + ": Couldn't find Map xBlock: " + xBlockId.ToString()); } else { if (xCount1 != xCount2) { } if (xCount1 > 0) { var xStruct = cont.GetStructureInfo((MetaName)xBlock.NameHash); var xOffset1 = xOffset; var xind = indent + 1; var aind = indent + 2; var kEntry = xStruct?.FindEntry(MetaName.Key); var iEntry = xStruct?.FindEntry(MetaName.Item); if ((xStruct == null) && (xBlock.NameHash == 0)) { SelfClosingTag(sb, cind, ename); } else if (xStruct == null) { ErrorXml(sb, aind, ename + ": Map struct type not found: " + HashString((MetaName)xBlock.NameHash)); } else if ((xStruct.IndexInfo == null)) // || (xStruct.IndexInfo.NameHash != MetaName.ARRAYINFO)) { ErrorXml(sb, aind, ename + ": Map struct was missing IndexInfo! " + (xStruct == null ? "" : xStruct.ToString())); } else if ((kEntry == null) || (iEntry == null)) { ErrorXml(sb, aind, ename + ": Map Key/Item entries not found!"); } else if (kEntry.Type != RageLib.GTA5.PSO.DataType.String) { ErrorXml(sb, aind, ename + ": Map Key was not a string!"); } else if (iEntry.Type != RageLib.GTA5.PSO.DataType.Structure) { ErrorXml(sb, aind, ename + ": Map Item was not a structure!"); } else if (iEntry.Unk_5h != 3) { ErrorXml(sb, aind, ename + ": Map Item was not a structure pointer - TODO!"); } else { OpenTag(sb, xind, ename); int xOffset2 = (int)xOffset1; int xCount = xCount1; for (int n = 0; n < xCount; n++) { //WriteNode(sb, aind, cont, xBlockId, xOffset, XmlTagMode.Item, xStruct.IndexInfo.NameHash); int sOffset = xOffset2 + xBlock.Offset; var kOffset = sOffset + kEntry.DataOffset; var iOffset = sOffset + iEntry.DataOffset; var kStr = GetStringValue(cont.Pso, kEntry, data, kOffset); var iPtr = MetaUtils.ConvertData <PsoPOINTER>(data, iOffset); iPtr.SwapEnd(); var iBlock = cont.Pso.GetBlock(iPtr.BlockID); if (iBlock == null) { OpenTag(sb, aind, "Item type=\"" + HashString((MetaName)entry.ReferenceKey) + "\" key=\"" + kStr + "\""); WriteNode(sb, aind, cont, iPtr.BlockID, (int)iPtr.ItemOffset, XmlTagMode.None, (MetaName)entry.ReferenceKey); CloseTag(sb, aind, "Item"); } else { var iStr = "Item type=\"" + HashString((MetaName)iBlock.NameHash) + "\" key=\"" + kStr + "\""; var iStruc = cont.GetStructureInfo((MetaName)iBlock.NameHash); if (iStruc?.EntriesCount == 0) { //SelfClosingTag(sb, aind, iStr); OpenTag(sb, aind, iStr); CloseTag(sb, aind, "Item"); } else { OpenTag(sb, aind, iStr); WriteNode(sb, aind, cont, iPtr.BlockID, (int)iPtr.ItemOffset, XmlTagMode.None); //, (MetaName)entry.ReferenceKey); CloseTag(sb, aind, "Item"); } } xOffset2 += xStruct.StructureLength; if ((n < (xCount - 1)) && (xBlock != null) && (xOffset >= xBlock.Length)) { ErrorXml(sb, aind, "Offset out of range! Count is " + xCount.ToString()); break; //out of range... } } CloseTag(sb, xind, ename); } } else { SelfClosingTag(sb, cind, ename); } } break; } }
private static void WriteArrayNode(StringBuilder sb, int indent, PsoCont cont, int blockId, int offset, PsoStructureEntryInfo entry, PsoStructureInfo estruct, string ename) { var block = cont.Pso.GetBlock(blockId); var boffset = offset + block.Offset; var eoffset = boffset + entry.DataOffset; var aOffset = offset + entry.DataOffset; var aBlockId = blockId; uint aCount = ((uint)entry.ReferenceKey >> 16) & 0x0000FFFF; var aind = indent + 1; string arrTag = ename; PsoStructureEntryInfo arrEntry = estruct.GetEntry((int)(entry.ReferenceKey & 0xFFFF)); if (arrEntry == null) { ErrorXml(sb, indent, "ARRAYINFO not found for " + ename + "!"); return; } var data = cont.Pso.DataSection.Data; switch (entry.Unk_5h) { default: ErrorXml(sb, indent, ename + ": WIP! Unsupported Array subtype: " + entry.Unk_5h.ToString()); break; case 0: //Array_Structure var arrStruc = MetaUtils.ConvertData <Array_Structure>(data, eoffset); arrStruc.SwapEnd(); aBlockId = (int)arrStruc.PointerDataId; aOffset = (int)arrStruc.PointerDataOffset; aCount = arrStruc.Count1; break; case 1: //Raw in-line array break; case 2: //also raw in-line array, but how different from above? break; case 4: //pointer array? default array? if (arrEntry.Unk_5h == 3) //pointers... { var arrStruc4 = MetaUtils.ConvertData <Array_Structure>(data, eoffset); arrStruc4.SwapEnd(); aBlockId = (int)arrStruc4.PointerDataId; aOffset = (int)arrStruc4.PointerDataOffset; aCount = arrStruc4.Count1; } break; case 129: //also raw inline array? in junctions.pso break; } switch (arrEntry.Type) { default: ErrorXml(sb, indent, ename + ": WIP! Unsupported array entry DataType: " + arrEntry.Type.ToString()); break; case RageLib.GTA5.PSO.DataType.Array: var rk0 = (entry.ReferenceKey >> 16) & 0x0000FFFF; if (rk0 > 0) { //var arrStruc5 = MetaUtils.ConvertDataArray<Array_StructurePointer>(data, eoffset, (int)rk0); //for (int n = 0; n < rk0; n++) arrStruc5[n].SwapEnd(); aOffset = offset + entry.DataOffset; OpenTag(sb, indent, arrTag); for (int n = 0; n < rk0; n++) //ARRAY ARRAY! { WriteArrayNode(sb, aind, cont, blockId, aOffset, arrEntry, estruct, "Item"); aOffset += 16; //ptr size... todo: what if not pointer array? } CloseTag(sb, indent, ename); } else { SelfClosingTag(sb, indent, arrTag); } break; case RageLib.GTA5.PSO.DataType.Structure: switch (arrEntry.Unk_5h) { case 0: break; case 3: //structure pointer array var arrStrucPtr = MetaUtils.ConvertData <Array_StructurePointer>(data, eoffset); arrStrucPtr.SwapEnd(); aBlockId = (int)arrStrucPtr.PointerDataId; aOffset = (int)arrStrucPtr.PointerDataOffset; aCount = arrStrucPtr.Count1; if (aCount > 0) { var ptrArr = PsoUtils.GetPointerArray(cont.Pso, arrStrucPtr); OpenTag(sb, indent, arrTag); for (int n = 0; n < aCount; n++) { var ptrVal = ptrArr[n]; WriteNode(sb, aind, cont, ptrVal.BlockID, (int)ptrVal.ItemOffset, XmlTagMode.ItemAndType); } CloseTag(sb, indent, ename); } break; default: break; } arrTag += " itemType=\"" + HashString((MetaName)arrEntry.ReferenceKey) + "\""; if (aCount > 0) { var aBlock = cont.Pso.GetBlock(aBlockId); var atyp = cont.GetStructureInfo((MetaName)arrEntry.ReferenceKey); if (aBlock == null) { ErrorXml(sb, indent, ename + ": Array block not found: " + aBlockId.ToString()); } else if ((MetaName)aBlock.NameHash != MetaName.PsoPOINTER) { OpenTag(sb, indent, arrTag); if (atyp == null) { ErrorXml(sb, indent, ename + ": Array type not found: " + HashString((MetaName)arrEntry.ReferenceKey)); } else { for (int n = 0; n < aCount; n++) { WriteNode(sb, aind, cont, aBlockId, aOffset, XmlTagMode.Item, (MetaName)arrEntry.ReferenceKey); aOffset += atyp.StructureLength; if ((n < (aCount - 1)) && (aBlock != null) && (aOffset >= aBlock.Length)) { break; } } } CloseTag(sb, indent, ename); } else { } //pointer array should get here, but it's already handled above. should improve this. } else { SelfClosingTag(sb, indent, arrTag); } break; case RageLib.GTA5.PSO.DataType.String: switch (entry.Unk_5h) { default: ErrorXml(sb, indent, ename + ": Unexpected String array subtype: " + entry.Unk_5h.ToString()); break; case 0: //hash array... var arrHash = MetaUtils.ConvertData <Array_uint>(data, eoffset); arrHash.SwapEnd(); var hashArr = PsoUtils.GetHashArray(cont.Pso, arrHash); WriteItemArray(sb, hashArr, indent, ename, "Hash", HashString); break; } break; case RageLib.GTA5.PSO.DataType.Float2: aCount = ((uint)entry.ReferenceKey >> 16) & 0x0000FFFF; arrTag += " itemType=\"Vector2\""; var v2Arr = MetaUtils.ConvertDataArray <Vector2>(data, eoffset, (int)aCount); WriteRawArray(sb, v2Arr, indent, ename, "Vector2", FormatVector2Swap, 1); break; case RageLib.GTA5.PSO.DataType.Float3: aCount = ((uint)entry.ReferenceKey >> 16) & 0x0000FFFF; arrTag += " itemType=\"Vector3\""; //this is actually aligned as vector4, the W values are crazy in places var v4Arr = MetaUtils.ConvertDataArray <Vector4>(data, eoffset, (int)aCount); WriteRawArray(sb, v4Arr, indent, ename, "Vector3", FormatVector4SwapXYZOnly, 1); break; case RageLib.GTA5.PSO.DataType.UByte: var barr = new byte[aCount]; if (aCount > 0) { var bblock = cont.Pso.GetBlock(aBlockId); var boffs = bblock.Offset + aOffset; Buffer.BlockCopy(data, boffs, barr, 0, (int)aCount); } WriteRawArray(sb, barr, indent, ename, "byte"); break; case RageLib.GTA5.PSO.DataType.Bool: var barr2 = new byte[aCount]; if (aCount > 0) { var bblock = cont.Pso.GetBlock(aBlockId); var boffs = bblock.Offset + aOffset; Buffer.BlockCopy(data, boffs, barr2, 0, (int)aCount); } WriteRawArray(sb, barr2, indent, ename, "boolean"); //todo: true/false output break; case RageLib.GTA5.PSO.DataType.Float: var arrFloat = MetaUtils.ConvertData <Array_float>(data, eoffset); arrFloat.SwapEnd(); var floatArr = PsoUtils.GetFloatArray(cont.Pso, arrFloat); WriteRawArray(sb, floatArr, indent, ename, "float"); break; case RageLib.GTA5.PSO.DataType.UShort: var arrShort = MetaUtils.ConvertData <Array_Structure>(data, eoffset); arrShort.SwapEnd(); var shortArr = PsoUtils.GetUShortArray(cont.Pso, arrShort); WriteRawArray(sb, shortArr, indent, ename, "ushort"); break; case RageLib.GTA5.PSO.DataType.UInt: var intArr = MetaUtils.ConvertDataArray <int>(data, eoffset, (int)aCount); WriteRawArray(sb, intArr, indent, ename, "int"); break; case RageLib.GTA5.PSO.DataType.SInt: var arrUint2 = MetaUtils.ConvertData <Array_uint>(data, eoffset); arrUint2.SwapEnd(); var intArr2 = PsoUtils.GetUintArray(cont.Pso, arrUint2); WriteRawArray(sb, intArr2, indent, ename, "int"); break; case RageLib.GTA5.PSO.DataType.Enum: var arrEnum = MetaUtils.ConvertData <Array_uint>(data, eoffset); arrEnum.SwapEnd(); var enumArr = PsoUtils.GetUintArray(cont.Pso, arrEnum); var enumDef = cont.GetEnumInfo((MetaName)arrEntry.ReferenceKey); WriteItemArray(sb, enumArr, indent, ename, "enum", (ie) => { var eval = enumDef?.FindEntry((int)ie); return(HashString((MetaName)(eval?.EntryNameHash ?? 0))); }); break; } }