예제 #1
0
        private static string GetStringValue(PsoFile pso, PsoStructureEntryInfo entry, byte[] data, int eoffset)
        {
            switch (entry.Unk_5h)
            {
            default:
                return(null);

            case 0:
                var str0len = (int)((entry.ReferenceKey >> 16) & 0xFFFF);
                return(Encoding.ASCII.GetString(data, eoffset, str0len).Replace("\0", ""));

            case 1:
            case 2:
                var dataPtr2 = MetaUtils.ConvertData <DataBlockPointer>(data, eoffset);
                dataPtr2.SwapEnd();
                return(PsoUtils.GetString(pso, dataPtr2));

            case 3:
                var charPtr3 = MetaUtils.ConvertData <CharPointer>(data, eoffset);
                charPtr3.SwapEnd();
                var strval = PsoUtils.GetString(pso, charPtr3);
                return(strval ?? "");

            case 7:
            case 8:
                MetaName hashVal = (MetaName)MetaUtils.SwapBytes(MetaUtils.ConvertData <uint>(data, eoffset));
                return(HashString(hashVal));
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
 public PsoArray4(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo, int numberOfEntries)
 {
     this.pso             = pso;
     this.structureInfo   = structureInfo;
     this.entryInfo       = entryInfo;
     this.numberOfEntries = numberOfEntries;
 }
예제 #4
0
 private void Convert()
 {
     if (arguments[0].EndsWith(".ymap.xml") ||
         arguments[0].EndsWith(".ytyp.xml") ||
         arguments[0].EndsWith(".ymt.xml"))
     {
         ConvertXmlToResource();
     }
     else if (arguments[0].EndsWith(".ymap") ||
              arguments[0].EndsWith(".ytyp") ||
              arguments[0].EndsWith(".ymt"))
     {
         if (ResourceFile_GTA5_pc.IsResourceFile(arguments[0]))
         {
             ConvertResourceToXml();
         }
         else if (PsoFile.IsPSO(arguments[0]))
         {
             ConvertPsoToXml();
         }
         else
         {
             ConvertRbfToXml();
         }
     }
     else if (arguments[0].EndsWith(".ymf"))
     {
         ConvertPsoToXml();
     }
     else
     {
         Console.WriteLine("No supported file name specified.");
         Console.ReadLine();
     }
 }
예제 #5
0
        public IPsoValue Read(Stream fileStream)
        {
            var resource = new PsoFile();

            resource.Load(fileStream);
            return(Parse(resource));
        }
예제 #6
0
 private void MetaInitialize()
 {
     meta = new PsoFile();
     meta.DataMappingSection = new PsoDataMappingSection();
     meta.DataSection        = new PsoDataSection();
     meta.DefinitionSection  = new PsoDefinitionSection();
 }
예제 #7
0
 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>();
 }
예제 #8
0
 public PsoMap(
     PsoFile pso,
     PsoStructureInfo structureInfo,
     PsoStructureEntryInfo keyEntryInfo,
     PsoStructureEntryInfo valueEntryInfo)
 {
     this.pso            = pso;
     this.structureInfo  = structureInfo;
     this.keyEntryInfo   = keyEntryInfo;
     this.valueEntryInfo = valueEntryInfo;
 }
예제 #9
0
        public static PsoElementIndexInfo GetStructureIndexInfo(PsoFile meta, int structureKey)
        {
            PsoElementIndexInfo info = null;

            for (int i = 0; i < meta.DefinitionSection.Count; i++)
            {
                if (meta.DefinitionSection.EntriesIdx[i].NameHash == structureKey)
                {
                    info = (PsoElementIndexInfo)meta.DefinitionSection.EntriesIdx[i];
                }
            }
            return(info);
        }
예제 #10
0
        public static string GetXml(PsoFile pso)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine(XmlHeader);

            if ((pso != null) && (pso.DataSection != null) && (pso.DataMappingSection != null))
            {
                var cont = new PsoCont(pso);

                WriteNode(sb, 0, cont, pso.DataMappingSection.RootIndex, 0, XmlTagMode.Structure);
            }

            return(sb.ToString());
        }
예제 #11
0
        public PsoFile GetPso()
        {
            var pso = new PsoFile();

            pso.DefinitionSection  = new PsoDefinitionSection();
            pso.DataMappingSection = new PsoDataMappingSection();
            pso.DataSection        = new PsoDataSection();

            // DefinitionSection
            foreach (var si in this.StructureInfos)
            {
                PsoElementIndexInfo indexInfo = new PsoElementIndexInfo();
                indexInfo.Offset   = 0;
                indexInfo.NameHash = si.Value.IndexInfo.NameHash;

                pso.DefinitionSection.EntriesIdx.Add(indexInfo);
                pso.DefinitionSection.Entries.Add(si.Value);
            }

            foreach (var ei in this.EnumInfos)
            {
                PsoElementIndexInfo indexInfo = new PsoElementIndexInfo();
                indexInfo.Offset   = 0;
                indexInfo.NameHash = ei.Value.IndexInfo.NameHash;

                pso.DefinitionSection.EntriesIdx.Add(indexInfo);
                pso.DefinitionSection.Entries.Add(ei.Value);
            }

            pso.DefinitionSection.Count = (uint)pso.DefinitionSection.Entries.Count;

            // DataMappingSection
            pso.DataMappingSection.Entries = new List <PsoDataMappingEntry>();
            MemoryStream memoryStream = new MemoryStream();

            memoryStream.Position = 16L;

            byte[] array2 = new byte[memoryStream.Length];
            memoryStream.Position = 0L;
            memoryStream.Read(array2, 0, array2.Length);
            pso.DataSection.Data = array2;

            pso.DataMappingSection.RootIndex = 1;


            return(pso);
        }
예제 #12
0
            public PsoCont(PsoFile pso)
            {
                Pso = pso;

                if ((pso.DefinitionSection == null) || (pso.DefinitionSection.Entries == null) || (pso.DefinitionSection.EntriesIdx == null))
                {
                    return;
                }


                for (int i = 0; i < pso.DefinitionSection.Entries.Count; i++)
                {
                    var entry      = pso.DefinitionSection.Entries[i];
                    var enuminfo   = entry as PsoEnumInfo;
                    var structinfo = entry as PsoStructureInfo;

                    if (enuminfo != null)
                    {
                        if (!EnumDict.ContainsKey((MetaName)enuminfo.IndexInfo.NameHash))
                        {
                            EnumDict.Add((MetaName)enuminfo.IndexInfo.NameHash, enuminfo);
                        }
                        else
                        {
                            //PsoEnumInfo oldei = EnumDict[enuminfo.IndexInfo.NameHash];
                            //if (!ComparePsoEnumInfos(oldei, enuminfo))
                            //{
                            //}
                        }
                    }
                    else if (structinfo != null)
                    {
                        if (!StructDict.ContainsKey((MetaName)structinfo.IndexInfo.NameHash))
                        {
                            StructDict.Add((MetaName)structinfo.IndexInfo.NameHash, structinfo);
                        }
                        else
                        {
                            //PsoStructureInfo oldsi = StructDict[structinfo.IndexInfo.NameHash];
                            //if (!ComparePsoStructureInfos(oldsi, structinfo))
                            //{
                            //}
                        }
                    }
                }
            }
예제 #13
0
        private void ConvertPsoToXml()
        {
            string inputFileName  = arguments[0];
            string outputFileName = inputFileName + ".pso.xml";

            var pso = new PsoFile();

            pso.Load(inputFileName);

            AddHashForStrings("MetaTool.Lists.PsoTypeNames.txt");
            AddHashForStrings("MetaTool.Lists.PsoFieldNames.txt");
            AddHashForStrings("MetaTool.Lists.PsoEnumValues.txt");
            AddHashForStrings("MetaTool.Lists.PsoCommon.txt");
            AddHashForStrings("MetaTool.Lists.FileNames.txt");
            AddHashForStrings("MetaTool.Lists.PsoCollisions.txt");

            var xml = PsoXml.GetXml(pso);

            File.WriteAllText(outputFileName, xml);
        }
예제 #14
0
 public PsoDataReader(PsoFile psoFile) : base(null, Endianess.BigEndian)
 {
     this.psoFile = psoFile;
 }
예제 #15
0
        public static Tuple <Dictionary <int, PsoStructureInfo>, Dictionary <int, PsoEnumInfo> > GetAllStructureInfoAndEnumInfoFromPsoMetas(string gameDirectoryName)
        {
            Dictionary <int, PsoStructureInfo> structureInfos = new Dictionary <int, PsoStructureInfo>();
            Dictionary <int, PsoEnumInfo>      enumInfos      = new Dictionary <int, PsoEnumInfo>();

            ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) =>
            {
                if (file.Name.EndsWith(".ymf") || file.Name.EndsWith(".ymt"))
                {
                    var stream = new MemoryStream();
                    file.Export(stream);

                    var buf         = new byte[stream.Length];
                    stream.Position = 0;
                    stream.Read(buf, 0, buf.Length);

                    if (file.IsEncrypted)
                    {
                        if (encryption == RageArchiveEncryption7.AES)
                        {
                            buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY);
                        }
                        else
                        {
                            var indexKey = GTA5Crypto.GetKeyIndex(file.Name, (uint)file.UncompressedSize);
                            buf          = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[indexKey]);
                        }
                    }

                    if (file.IsCompressed)
                    {
                        var def    = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
                        var bufnew = new byte[file.UncompressedSize];
                        def.Read(bufnew, 0, (int)file.UncompressedSize);
                        buf = bufnew;
                    }

                    var cleanStream = new MemoryStream(buf);
                    if (PsoFile.IsPSO(cleanStream))
                    {
                        PsoFile pso = new PsoFile();
                        pso.Load(cleanStream);

                        for (int i = 0; i < pso.DefinitionSection.Count; i++)
                        {
                            var id = pso.DefinitionSection.EntriesIdx[i];

                            var info = pso.DefinitionSection.Entries[i];

                            if (info is PsoStructureInfo structureInfo)
                            {
                                structureInfos.TryAdd(id.NameHash, structureInfo);
                            }

                            if (info is PsoEnumInfo enumInfo)
                            {
                                enumInfos.TryAdd(id.NameHash, enumInfo);
                            }
                        }

                        Console.WriteLine(file.Name);
                    }
                }
            });

            return(new Tuple <Dictionary <int, PsoStructureInfo>, Dictionary <int, PsoEnumInfo> >(structureInfos, enumInfos));
        }
예제 #16
0
        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.");
            }
        }
예제 #17
0
 public PsoArray0(PsoFile pso, PsoStructureInfo structureInfo, PsoStructureEntryInfo entryInfo)
 {
     this.pso           = pso;
     this.structureInfo = structureInfo;
     this.entryInfo     = entryInfo;
 }
예제 #18
0
 public void LoadMeta(PsoFile pso)
 {
     Xml      = PsoXml.GetXml(pso);
     modified = false;
 }
예제 #19
0
        public static HashSet <int> GetAllHashesFromPsoMetas(string gameDirectoryName)
        {
            var hashes = new HashSet <int>();

            ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) =>
            {
                if (file.Name.EndsWith(".ymf") || file.Name.EndsWith(".ymt"))
                {
                    var stream = new MemoryStream();
                    file.Export(stream);

                    var buf         = new byte[stream.Length];
                    stream.Position = 0;
                    stream.Read(buf, 0, buf.Length);

                    if (file.IsEncrypted)
                    {
                        if (encryption == RageArchiveEncryption7.AES)
                        {
                            buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY);
                        }
                        else
                        {
                            var qq = GTA5Hash.CalculateHash(file.Name);
                            var gg = (qq + (uint)file.UncompressedSize + (101 - 40)) % 0x65;
                            buf    = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[gg]);
                        }
                    }

                    if (file.IsCompressed)
                    {
                        var def    = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
                        var bufnew = new byte[file.UncompressedSize];
                        def.Read(bufnew, 0, (int)file.UncompressedSize);
                        buf = bufnew;
                    }

                    var cleanStream = new MemoryStream(buf);
                    if (PsoFile.IsPSO(cleanStream))
                    {
                        PsoFile pso = new PsoFile();
                        pso.Load(cleanStream);

                        foreach (var info in pso.DefinitionSection.EntriesIdx)
                        {
                            hashes.Add(info.NameHash);
                        }
                        foreach (var info in pso.DefinitionSection.Entries)
                        {
                            if (info is PsoStructureInfo)
                            {
                                var structureInfo = (PsoStructureInfo)info;
                                foreach (var entryInfo in structureInfo.Entries)
                                {
                                    hashes.Add(entryInfo.EntryNameHash);
                                }
                            }

                            if (info is PsoEnumInfo)
                            {
                                var enumInfo = (PsoEnumInfo)info;
                                foreach (var entryInfo in enumInfo.Entries)
                                {
                                    hashes.Add(entryInfo.EntryNameHash);
                                }
                            }
                        }

                        Console.WriteLine(file.Name);
                    }
                }
            });
            return(hashes);
        }
예제 #20
0
        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);
        }