Example #1
0
        public int GetSize(Meta_GTA5_pc meta, int typeKey)
        {
            switch (typeKey)
            {
            case 0x00000007:
                return(8);

            case 0x00000010:
                return(1);

            case 0x00000011:
                return(1);

            case 0x00000013:
                return(2);

            case 0x00000015:
                return(4);

            case 0x00000021:
                return(4);

            case 0x00000033:
                return(16);

            case 0x0000004A:
                return(4);

            default:
                return((int)GetInfo(meta, typeKey).StructureLength);
            }
        }
Example #2
0
 private void MetaInitialize()
 {
     meta             = new Meta_GTA5_pc();
     meta.VFT         = 0x405bc808;
     meta.Unknown_4h  = 1;
     meta.Unknown_10h = 0x50524430;
     meta.Unknown_14h = 0x0079;
 }
Example #3
0
        public static EnumInfo_GTA5_pc GetEnumInfo(Meta_GTA5_pc meta, int structureKey)
        {
            EnumInfo_GTA5_pc info = null;

            foreach (var x in meta.EnumInfos)
            {
                if (x.EnumNameHash == structureKey)
                {
                    info = x;
                }
            }
            return(info);
        }
Example #4
0
        public static StructureInfo_GTA5_pc GetStructureInfo(Meta_GTA5_pc meta, int structureKey)
        {
            StructureInfo_GTA5_pc info = null;

            foreach (var x in meta.StructureInfos)
            {
                if (x.StructureNameHash == structureKey)
                {
                    info = x;
                }
            }
            return(info);
        }
Example #5
0
 public MetaStructure(Meta_GTA5_pc meta, StructureInfo_GTA5_pc info)
 {
     this.meta = meta;
     this.info = info;
 }
Example #6
0
        public IMetaValue Parse(Meta_GTA5_pc meta)
        {
            var blockKeys = new List <int>();
            var blocks    = new List <List <IMetaValue> >();

            //////////////////////////////////////////////////
            // first step: flat conversion
            //////////////////////////////////////////////////

            foreach (var block in meta.DataBlocks)
            {
                blockKeys.Add(block.StructureNameHash);
                switch (block.StructureNameHash)
                {
                case 0x00000007:
                    blocks.Add(ReadBlock(block, () => new MetaGeneric()));     // has no special type declaration in .meta -> pointer
                    break;

                case 0x00000010:
                    blocks.Add(ReadBlock(block, () => new MetaByte_A()));     // char_array
                    break;

                case 0x00000011:
                    blocks.Add(ReadBlock(block, () => new MetaByte_B()));      // has no special type declaration in .meta -> string
                    break;

                case 0x00000013:
                    blocks.Add(ReadBlock(block, () => new MetaInt16_B()));     // probably short_array
                    break;

                case 0x00000015:
                    blocks.Add(ReadBlock(block, () => new MetaInt32_B()));     // int_array
                    break;

                case 0x00000021:
                    blocks.Add(ReadBlock(block, () => new MetaFloat()));     // float_array
                    break;

                case 0x00000033:
                    blocks.Add(ReadBlock(block, () => new MetaFloat4_XYZ()));     // vector3_array
                    break;

                case 0x0000004A:
                    blocks.Add(ReadBlock(block, () => new MetaInt32_Hash()));     // probably list of <Item>HASH_OF_SOME_NAME</Item>
                    break;

                default:
                    blocks.Add(ReadBlock(block, () => new MetaStructure(meta, GetInfo(meta, block.StructureNameHash))));     // has no special type declaration in .meta -> structure
                    break;
                }
            }

            //////////////////////////////////////////////////
            // second step: map references
            //////////////////////////////////////////////////

            var referenced = new HashSet <IMetaValue>();
            var stack      = new Stack <IMetaValue>();

            foreach (var block in blocks)
            {
                foreach (var entry in block)
                {
                    stack.Push(entry);
                }
            }
            while (stack.Count > 0)
            {
                var entry = stack.Pop();
                if (entry is MetaArray)
                {
                    var arrayEntry     = entry as MetaArray;
                    var realBlockIndex = arrayEntry.BlockIndex - 1;
                    if (realBlockIndex >= 0)
                    {
                        arrayEntry.Entries = new List <IMetaValue>();
                        var realEntryIndex = arrayEntry.Offset / GetSize(meta, blockKeys[realBlockIndex]);
                        for (int i = 0; i < arrayEntry.NumberOfEntries; i++)
                        {
                            var x = blocks[realBlockIndex][realEntryIndex + i];
                            arrayEntry.Entries.Add(x);
                            referenced.Add(x);
                        }
                    }
                }
                if (entry is MetaCharPointer)
                {
                    var charPointerEntry = entry as MetaCharPointer;
                    var realBlockIndex   = charPointerEntry.DataBlockIndex - 1;
                    if (realBlockIndex >= 0)
                    {
                        string value = "";
                        for (int i = 0; i < charPointerEntry.StringLength; i++)
                        {
                            var x = (MetaByte_A)blocks[realBlockIndex][i + charPointerEntry.DataOffset];
                            value += (char)x.Value;
                        }
                        charPointerEntry.Value = value;
                    }
                }
                if (entry is MetaDataBlockPointer)
                {
                    var dataPointerEntry = entry as MetaDataBlockPointer;
                    var realBlockIndex   = dataPointerEntry.BlockIndex - 1;
                    if (realBlockIndex >= 0)
                    {
                        byte[] b = ToBytes(meta.DataBlocks[realBlockIndex].Data);
                        dataPointerEntry.Data = b;
                    }
                }
                if (entry is MetaGeneric)
                {
                    var genericEntry   = entry as MetaGeneric;
                    var realBlockIndex = genericEntry.BlockIndex - 1;
                    var realEntryIndex = genericEntry.Offset * 16 / GetSize(meta, blockKeys[realBlockIndex]);
                    var x = blocks[realBlockIndex][realEntryIndex];
                    genericEntry.Value = x;
                    referenced.Add(x);
                }
                if (entry is MetaStructure)
                {
                    var structureEntry = entry as MetaStructure;
                    foreach (var x in structureEntry.Values)
                    {
                        stack.Push(x.Value);
                    }
                }
            }

            //////////////////////////////////////////////////
            // third step: find root
            //////////////////////////////////////////////////

            var rootSet = new HashSet <IMetaValue>();

            foreach (var x in blocks)
            {
                foreach (var y in x)
                {
                    if (y is MetaStructure && !referenced.Contains(y))
                    {
                        rootSet.Add(y);
                    }
                }
            }

            var res = rootSet.First();

            if (res != blocks[(int)meta.RootBlockIndex - 1][0])
            {
                throw new System.Exception("wrong root block index");
            }

            return(res);
        }