Exemplo n.º 1
0
        public GameCacheContextGen3(MapFile mapFile, EndianReader reader)
        {
            BaseMapFile         = mapFile;
            Version             = BaseMapFile.Version;
            Deserializer        = new TagDeserializer(Version);
            LocalesKey          = SetLocalesKey();
            StringsKey          = SetStringsKey();
            TagsKey             = SetTagsKey();
            NetworkKey          = SetNetworkKey();
            StringMods          = SetStringMods();
            LocaleGlobalsSize   = SetLocaleGlobalsSize();
            LocaleGlobalsOffset = SetLocaleGlobalsOffset();


            var interop = mapFile.Header.GetInterop();

            if (interop != null && interop.ResourceBaseAddress == 0)
            {
                Magic = (int)(interop.RuntimeBaseAddress - mapFile.Header.GetMemoryBufferSize());
            }
            else
            {
                mapFile.Header.ApplyMagic(mapFile.Header.GetStringIDsIndicesOffset() - mapFile.Header.GetHeaderSize(mapFile.Version));
                var resourcePartition = mapFile.Header.GetPartitions()[(int)CacheFilePartitionType.Resources];
                var resourceSection   = interop.Sections[(int)CacheFileSectionType.Resource];
                Magic = BitConverter.ToInt32(BitConverter.GetBytes(resourcePartition.BaseAddress), 0) - (interop.DebugSectionSize + resourceSection.Size);
            }

            if (mapFile.Header.GetTagIndexAddress() == 0)
            {
                return;
            }

            mapFile.Header.SetTagIndexAddress(BitConverter.ToUInt32(BitConverter.GetBytes(mapFile.Header.GetTagIndexAddress() - Magic), 0));

            IndexHeader = mapFile.GetIndexHeader(reader, Magic);
            Strings     = CreateStringTable(reader);
            IndexItems  = CreateCacheIndexTable(reader);

            LocaleTables = new List <CacheLocaleTable>();

            switch (mapFile.Version)
            {
            case CacheVersion.Halo3Retail:
                Resolver = new StringIdResolverHalo3();
                break;

            case CacheVersion.Halo3ODST:
                Resolver = new StringIdResolverHalo3ODST();
                break;

            case CacheVersion.HaloReach:
                Resolver = new StringIdResolverHaloReach();
                break;

            default:
                throw new NotSupportedException(CacheVersionDetection.GetBuildName(mapFile.Version));
            }

            foreach (var language in Enum.GetValues(typeof(GameLanguage)))
            {
                LocaleTables.Add(CreateLocaleTable(reader, (GameLanguage)language));
            }
        }
Exemplo n.º 2
0
        private CacheIndexTable CreateCacheIndexTable(EndianReader reader)
        {
            CacheIndexTable indexTable = new CacheIndexTable();

            indexTable.ClassList = new List <TagClass>();

            #region Read Class List
            reader.SeekTo(IndexHeader.TagGroupsOffset);
            for (int i = 0; i < IndexHeader.TagGroupCount; i++)
            {
                var tc = new TagClass()
                {
                    ClassCode = reader.ReadString(4),
                    Parent    = reader.ReadString(4),
                    Parent2   = reader.ReadString(4),
                    StringID  = reader.ReadInt32()
                };
                indexTable.ClassList.Add(tc);
            }
            #endregion

            #region Read Tags Info
            reader.SeekTo(IndexHeader.TagsOffset);
            for (int i = 0; i < IndexHeader.TagCount; i++)
            {
                var            classIndex = reader.ReadInt16();
                var            tagClass   = classIndex == -1 ? null : indexTable.ClassList[classIndex];
                string         groupName  = classIndex == -1 ? "" : Strings.GetItemByID(tagClass.StringID);
                CacheIndexItem item       = new CacheIndexItem(classIndex, (reader.ReadInt16() << 16) | i, reader.ReadInt32() - Magic, i, tagClass, groupName);
                indexTable.Add(item);
            }
            #endregion

            #region Read Indices
            reader.SeekTo(BaseMapFile.Header.GetTagNamesIndicesOffset());
            int[] indices = new int[IndexHeader.TagCount];
            for (int i = 0; i < IndexHeader.TagCount; i++)
            {
                indices[i] = reader.ReadInt32();
            }
            #endregion

            #region Read Names
            reader.SeekTo(BaseMapFile.Header.GetTagNamesBufferOffset());

            EndianReader newReader = null;

            if (TagsKey == "" || TagsKey == null)
            {
                newReader = new EndianReader(new MemoryStream(reader.ReadBytes(BaseMapFile.Header.GetTagNamesBufferSize())), EndianFormat.BigEndian);
            }
            else
            {
                reader.BaseStream.Position = BaseMapFile.Header.GetTagNamesBufferOffset();
                newReader = new EndianReader(reader.DecryptAesSegment(BaseMapFile.Header.GetTagNamesBufferSize(), TagsKey), EndianFormat.BigEndian);
            }

            for (int i = 0; i < indices.Length; i++)
            {
                if (indices[i] == -1)
                {
                    indexTable[i].Name = "<null>";
                    continue;
                }

                newReader.SeekTo(indices[i]);

                int length;
                if (i == indices.Length - 1)
                {
                    length = BaseMapFile.Header.GetTagNamesBufferSize() - indices[i];
                }
                else
                {
                    if (indices[i + 1] == -1)
                    {
                        int index = -1;

                        for (int j = i + 1; j < indices.Length; j++)
                        {
                            if (indices[j] != -1)
                            {
                                index = j;
                                break;
                            }
                        }

                        length = (index == -1) ? BaseMapFile.Header.GetTagNamesBufferSize() - indices[i] : indices[index] - indices[i];
                    }
                    else
                    {
                        length = indices[i + 1] - indices[i];
                    }
                }

                if (length == 1)
                {
                    indexTable[i].Name = "<blank>";
                    continue;
                }

                if (length < 0)
                {
                    int i0 = indices[i];
                    int i1 = indices[i + 1];
                    int i2 = indices[i + 2];
                    int i3 = indices[i + 3];
                }

                indexTable[i].Name = newReader.ReadString(length);
            }

            newReader.Close();
            newReader.Dispose();
            #endregion

            return(indexTable);
        }