Example #1
0
        private static StashTableEntry <T>[] ReadStashTable <T>(
            this RuntimeBase runtime, IntPtr pointer, Func <IntPtr, T> callback)
        {
            if (pointer == IntPtr.Zero)
            {
                return(new StashTableEntry <T> [0]);
            }

            StashTableHeader header;

            if (runtime.Is32Bit == false)
            {
                header = runtime.ReadStructure <StashTableHeader>(pointer);
            }
            else
            {
                header = runtime.ReadStructure <x32.StashTableHeader>(pointer).Upgrade();
            }

            if (header.AllocatedCount == 0)
            {
                return(new StashTableEntry <T> [0]);
            }

            StashTableEntry[] entries;
            if (runtime.Is32Bit == false)
            {
                entries = runtime.ReadStructureArray <StashTableEntry>(header.EntriesPointer, header.AllocatedCount);
            }
            else
            {
                var entries32 = runtime.ReadStructureArray <x32.StashTableEntry>(header.EntriesPointer, header.AllocatedCount);
                entries = new StashTableEntry[header.AllocatedCount];
                for (int i = 0; i < header.AllocatedCount; i++)
                {
                    entries[i] = entries32[i].Upgrade();
                }
            }

            var items = new StashTableEntry <T> [header.AllocatedCount];
            int o     = 0;

            for (int i = 0; i < header.AllocatedCount; i++)
            {
                var entry = entries[i];
                if (entry.NamePointer == default && entry.ValuePointer == default)
                {
                    continue;
                }
                var name  = runtime.ReadStringZ(entry.NamePointer, Encoding.ASCII);
                var value = callback(entry.ValuePointer);
                items[o] = new StashTableEntry <T>(name, value);
                o++;
            }
            Array.Resize(ref items, o);
            return(items);
        }
Example #2
0
 public static StashTableEntry <string>[] ReadStringStashTable(this RuntimeBase runtime, IntPtr pointer)
 {
     return(runtime.ReadStashTable(pointer, p => runtime.ReadStringZ(p, Encoding.ASCII)));
 }
Example #3
0
        private static uint HashTable(RuntimeBase runtime, IntPtr address, uint hash)
        {
            throw new NotImplementedException();

            var columns        = new List <KeyValuePair <ParseColumn, string> >();
            var currentAddress = address;

            while (true)
            {
                var column = runtime.ReadStructure <ParseColumn>(currentAddress);
                currentAddress += 40;

                var name = runtime.ReadStringZ(column.NamePointer, Encoding.ASCII);

                if (column.Type == 0)
                {
                    if (string.IsNullOrEmpty(name) == true)
                    {
                        break;
                    }
                }

                columns.Add(new KeyValuePair <ParseColumn, string>(column, name));
            }

            foreach (var kv in columns)
            {
                var column = kv.Key;

                if (column.Flags.HasAny(Parse.ColumnFlags.REDUNDANTNAME |
                                        Parse.ColumnFlags.UNOWNED) == true)
                {
                    continue;
                }

                var name = kv.Value;

                if (string.IsNullOrEmpty(name) == false)
                {
                    hash = Adler32.Hash(name, hash);
                }

                hash = Adler32.Hash(column.Type, hash);

                var token = Parse.GlobalTokens.GetToken(column.Token);

                switch (token.GetParameter(column.Flags, 0))
                {
                case Parse.ColumnParameter.NumberOfElements:
                case Parse.ColumnParameter.Default:
                case Parse.ColumnParameter.StringLength:
                case Parse.ColumnParameter.Size:
                {
                    hash = Adler32.Hash(column.Parameter0.Int32, hash);
                    break;
                }

                case Parse.ColumnParameter.BitOffset:
                {
                    hash = Adler32.Hash(column.Parameter0.Int32 >> 16, hash);
                    break;
                }

                case Parse.ColumnParameter.DefaultString:
                case Parse.ColumnParameter.CommandString:
                {
                    if (column.Parameter0.Pointer != default)
                    {
                        hash = Adler32.Hash(runtime.ReadStringZ(column.Parameter0.Pointer, Encoding.ASCII), hash);
                    }
                    break;
                }
                }

                var param1 = token.GetParameter(column.Flags, 1);

                if (column.Parameter1.Pointer != default &&
                    (column.Token == 20 || column.Token == 21) &&
                    address != column.Parameter1.Pointer &&
                    column.Flags.HasAny(Parse.ColumnFlags.STRUCT_NORECURSE) == false)
                {
                    hash = HashTable(runtime, column.Parameter1.Pointer, hash);
                }

                if (column.Parameter1.Pointer != default &&
                    param1 == Parse.ColumnParameter.StaticDefineList)
                {
                    hash = HashStaticDefineList(runtime, column.Parameter1.Pointer, hash);
                }

                if (column.Token == 23)
                {
                    var formatString = runtime.ReadStringZ(column.FormatStringPointer, Encoding.ASCII);
                    if (string.IsNullOrEmpty(formatString) == false)
                    {
                        hash = Adler32.Hash(formatString, hash);
                    }
                }
            }

            return(hash);
        }
Example #4
0
        private static uint HashStaticDefineList(RuntimeBase runtime, IntPtr baseAddress, uint hash)
        {
            var valueType = 4;

            while (true)
            {
                var type = runtime.ReadValueU32(baseAddress);
                if (type == 0)
                {
                    break;
                }

                switch (type)
                {
                case 1:
                {
                    valueType    = 1;
                    baseAddress += 8;
                    break;
                }

                case 2:
                {
                    valueType    = 2;
                    baseAddress += 8;
                    break;
                }

                case 3:
                {
                    var listAddress = runtime.ReadPointer(baseAddress + 4);
                    baseAddress += 8;

                    if (listAddress != IntPtr.Zero)
                    {
                        hash = HashKeyValueList(runtime, listAddress, hash);
                    }

                    break;
                }

                case 5:
                {
                    var parent = runtime.ReadPointer(baseAddress + 4);
                    return(HashStaticDefineList(runtime, parent, hash));
                }

                default:
                {
                    // TODO(gibbed): FIXME
                    var name = runtime.ReadStringZ(new IntPtr(type), Encoding.ASCII);
                    hash = Adler32.Hash(name, hash);

                    switch (valueType)
                    {
                    case 1:
                    {
                        var value = runtime.ReadValueU32(baseAddress + 4);
                        hash         = Adler32.Hash(value, hash);
                        baseAddress += 8;
                        break;
                    }

                    case 2:
                    {
                        var value = runtime.ReadStringZ(baseAddress + 4, Encoding.ASCII);
                        hash         = Adler32.Hash(value, hash);
                        baseAddress += 8;
                        break;
                    }

                    default:
                    {
                        throw new NotImplementedException();
                    }
                    }

                    break;
                }
                }
            }

            return(hash);
        }