Example #1
0
            public CacheIndexHeader(CacheFile cache)
            {
                cache.Reader.SeekTo(cache.Header.TagIndexAddress);

                TagGroupCount        = cache.Reader.ReadInt32();
                TagGroupsOffset      = cache.Reader.ReadInt32() - cache.Magic;
                TagCount             = cache.Reader.ReadInt32();
                TagsOffset           = cache.Reader.ReadInt32() - cache.Magic;
                TagInfoHeaderCount   = cache.Reader.ReadInt32();
                TagInfoHeaderOffset  = cache.Reader.ReadInt32() - cache.Magic;
                TagInfoHeaderCount2  = cache.Reader.ReadInt32();
                TagInfoHeaderOffset2 = cache.Reader.ReadInt32() - cache.Magic;
            }
Example #2
0
        public override void LoadResourceTags()
        {
            TagDeserializer deserializer = new TagDeserializer(Version);

            foreach (IndexItem item in IndexItems)
            {
                if (item.GroupTag == "play")
                {
                    CacheFile cacheFile   = this;
                    var       blamContext = new CacheSerializationContext(ref cacheFile, item);
                    if (cacheFile.File.FullName != File.FullName)
                    {
                        throw new InvalidOperationException();
                    }

                    ResourceLayoutTable = deserializer.Deserialize <CacheFileResourceLayoutTable>(blamContext);
                    break;
                }
            }

            foreach (IndexItem item in IndexItems)
            {
                if (item.GroupTag == "zone")
                {
                    CacheFile cacheFile   = this;
                    var       blamContext = new CacheSerializationContext(ref cacheFile, item);
                    if (cacheFile.File.FullName != File.FullName)
                    {
                        throw new InvalidOperationException();
                    }

                    ResourceGestalt = deserializer.Deserialize <CacheFileResourceGestalt>(blamContext);

                    foreach (var tagresource in ResourceGestalt.TagResources)
                    {
                        foreach (var fixup in tagresource.ResourceFixups)
                        {
                            fixup.Offset     = (int)(fixup.Address.Value & 0x0FFFFFFF);
                            fixup.Type       = (int)(fixup.Address.Value >> 28) & 0xF;
                            fixup.RawAddress = (int)fixup.Address.Value;
                        }
                    }

                    break;
                }
            }
        }
Example #3
0
            public CacheIndexHeader(CacheFile cache)
            {
                var reader = cache.Reader;

                reader.SeekTo(cache.Header.TagIndexOffset);

                TagGroupsOffset    = reader.ReadInt32();
                cache.Header.Magic = TagGroupsOffset - (cache.Header.TagIndexOffset + 32);
                TagGroupCount      = reader.ReadInt32();
                TagsOffset         = reader.ReadInt32() - cache.Header.Magic;
                ScenarioHandle     = reader.ReadDatumIndex();
                GlobalsHandle      = reader.ReadDatumIndex();
                CRC      = reader.ReadInt32();
                TagCount = reader.ReadInt32();
                reader.ReadTag(); // 'tags'

                reader.SeekTo(TagsOffset + 8);
                cache.Magic = reader.ReadInt32() - (cache.Header.TagIndexOffset + cache.Header.MemoryBufferOffset);
            }
Example #4
0
            public CacheIndexHeader(CacheFile cache)
            {
                var reader = cache.Reader;

                reader.SeekTo(cache.Header.TagsHeaderAddress32);

                TagGroupsOffset = reader.ReadInt32();
                TagGroupCount   = reader.ReadInt32();

                var addressMask = (int)(TagGroupsOffset - (cache.Header.TagsHeaderAddress32 + 32));

                TagsOffset     = reader.ReadInt32() - addressMask;
                ScenarioHandle = reader.ReadDatumIndex();
                GlobalsHandle  = reader.ReadDatumIndex();
                CRC            = reader.ReadInt32();
                TagCount       = reader.ReadInt32();
                reader.ReadTag(); // 'tags'

                reader.SeekTo(TagsOffset + 8);
                cache.Magic = (int)(reader.ReadInt32() - (cache.Header.TagsHeaderAddress32 + cache.Header.MemoryBufferOffset));
            }
Example #5
0
            public IndexTable(CacheFile cache)
            {
                Clear();

                var IH     = cache.IndexHeader;
                var CH     = cache.Header;
                var reader = cache.Reader;

                ClassList = new List <TagClass>();

                var classDic = new Dictionary <string, int>();

                var sbspOffset = new int[0];
                var sbspMagic  = new int[0];
                var sbspID     = new int[0];

                reader.SeekTo(IH.TagsOffset);
                for (int i = 0; i < IH.TagCount; i++)
                {
                    var cname = reader.ReadString(4);
                    var tname = cname.ToCharArray();
                    Array.Reverse(tname);
                    cname = new string(tname);

                    if (!classDic.TryGetValue(cname, out int index))
                    {
                        index = classDic.Count;
                        classDic.Add(cname, classDic.Count);
                    }

                    var item = new IndexItem
                    {
                        Cache      = cache,
                        ClassIndex = index,
                        ID         = reader.ReadInt32(),
                        Offset     = reader.ReadInt32(),
                        Size       = reader.ReadInt32()
                    };

                    if (item.Offset == 0 || item.ID == -1)
                    {
                        item.External = true;
                    }
                    else
                    {
                        item.Offset -= cache.Magic;
                    }

                    Add(item);

                    if (cname == "scnr" && cache.Version < CacheVersion.Halo2Vista)
                    {
                        long tempOffset = reader.Position;

                        reader.SeekTo(item.Offset + 528);
                        int jCount  = reader.ReadInt32();
                        int jOffset = reader.ReadInt32() - cache.Magic;

                        sbspOffset = new int[jCount];
                        sbspMagic  = new int[jCount];
                        sbspID     = new int[jCount];

                        for (int j = 0; j < jCount; j++)
                        {
                            reader.SeekTo(jOffset + j * 68);
                            sbspOffset[j] = reader.ReadInt32();
                            reader.ReadInt32();
                            sbspMagic[j] = reader.ReadInt32() - sbspOffset[j];
                            reader.SeekTo(jOffset + j * 68 + 20);
                            sbspID[j] = reader.ReadInt32();
                        }

                        reader.SeekTo(tempOffset);
                    }
                }

                foreach (var pair in classDic)
                {
                    ClassList.Add(new TagClass()
                    {
                        ClassCode = pair.Key
                    });
                }

                #region Read Indices

                reader.SeekTo(CH.TagNamesIndicesOffset);
                var offsets = new int[IH.TagCount];
                for (int i = 0; i < IH.TagCount; i++)
                {
                    offsets[i] = reader.ReadInt32();
                }

                #endregion

                #region Read Names
                reader.StreamOrigin = CH.TagNamesBufferOffset;

                for (int i = 0; i < offsets.Length; i++)
                {
                    this[i].Name = null;

                    if (offsets[i] == -1)
                    {
                        continue;
                    }

                    reader.SeekTo(offsets[i]);

                    var name = "";
                    for (char c; (c = reader.ReadChar()) != '\0'; name += c)
                    {
                        ;
                    }

                    if (name.Length > 0)
                    {
                        this[i].Name = name;
                    }
                }

                reader.StreamOrigin = 0;
                #endregion
            }
Example #6
0
            public LocaleTable(CacheFile cache, GameLanguage language)
            {
                int matgOffset = -1;

                foreach (var item in cache.IndexItems)
                {
                    if (item.IsInGroup("matg"))
                    {
                        matgOffset = item.Offset;
                        break;
                    }
                }

                if (matgOffset == -1)
                {
                    return;
                }

                cache.Reader.SeekTo(matgOffset + cache.LocaleGlobalsOffset + ((int)language * cache.LocaleGlobalsSize));

                var localeCount = cache.Reader.ReadInt32();
                var tableSize   = cache.Reader.ReadInt32();
                var indexOffset = 0; // (int)(cache.Reader.ReadInt32() + cache.Header.Interop.LocaleSectionAddressToOffset); fixme
                var tableOffset = 0; // (int)(cache.Reader.ReadInt32() + cache.Header.Interop.LocaleSectionAddressToOffset); fixme later

                cache.Reader.SeekTo(indexOffset);
                var indices = new int[localeCount];

                for (var i = 0; i < localeCount; i++)
                {
                    Add(new LocalizedString(cache.Reader.ReadInt32(), "", i));
                    indices[i] = cache.Reader.ReadInt32();
                }

                cache.Reader.SeekTo(tableOffset);

                EndianReader newReader = null;

                if (cache.LocalesKey == null || cache.LocalesKey == "")
                {
                    newReader = new EndianReader(new MemoryStream(cache.Reader.ReadBytes(tableSize)), EndianFormat.BigEndian);
                }
                else
                {
                    cache.Reader.BaseStream.Position = tableOffset;
                    newReader = new EndianReader(cache.Reader.DecryptAesSegment(tableSize, cache.LocalesKey));
                }

                for (var i = 0; i < indices.Length; i++)
                {
                    if (indices[i] == -1)
                    {
                        this[i].String = "<null>";
                        continue;
                    }

                    newReader.SeekTo(indices[i]);

                    int length;
                    if (i == indices.Length - 1)
                    {
                        length = tableSize - indices[i];
                    }
                    else
                    {
                        length = (indices[i + 1] != -1)
                            ? indices[i + 1] - indices[i]
                            : indices[i + 2] - indices[i];
                    }

                    if (length == 1)
                    {
                        this[i].String = "<blank>";
                        continue;
                    }
                    this[i].String = newReader.ReadString(length);
                }

                newReader.Close();
                newReader.Dispose();
            }
Example #7
0
            public StringTable(CacheFile cache)
            {
                Cache = cache;
                var reader      = Cache.Reader;
                var cacheHeader = Cache.Header;

                reader.SeekTo(cacheHeader.StringIDsIndicesOffset);
                int[] indices = new int[cacheHeader.StringIDsCount];
                for (var i = 0; i < cacheHeader.StringIDsCount; i++)
                {
                    indices[i] = reader.ReadInt32();
                    Add("");
                }

                reader.SeekTo(cacheHeader.StringIDsBufferOffset);

                EndianReader newReader = null;

                if (Cache.StringsKey == "" || Cache.StringsKey == null)
                {
                    newReader = new EndianReader(new MemoryStream(reader.ReadBytes(cacheHeader.StringIDsBufferSize)), reader.Format);
                }
                else
                {
                    reader.BaseStream.Position = cacheHeader.StringIDsBufferOffset;
                    newReader = new EndianReader(reader.DecryptAesSegment(cacheHeader.StringIDsBufferSize, Cache.StringsKey), reader.Format);
                }

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

                    newReader.SeekTo(indices[i]);

                    int length;
                    if (i == indices.Length - 1)
                    {
                        length = cacheHeader.StringIDsBufferSize - indices[i];
                    }
                    else
                    {
                        length = (indices[i + 1] != -1)
                            ? indices[i + 1] - indices[i]
                            : indices[i + 2] - indices[i];
                    }

                    if (length == 1)
                    {
                        this[i] = "";
                        continue;
                    }

                    this[i] = newReader.ReadString(length);
                }
                newReader.Close();
                newReader.Dispose();
            }
Example #8
0
            public IndexTable(CacheFile cache)
            {
                var indexHeader = cache.IndexHeader;
                var cacheHeader = cache.Header;
                var reader      = cache.Reader;

                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()
                    };
                    ClassList.Add(tc);
                }
                #endregion

                #region Read Tags Info
                reader.SeekTo(indexHeader.TagsOffset);
                for (int i = 0; i < indexHeader.TagCount; i++)
                {
                    IndexItem item = new IndexItem()
                    {
                        Cache = cache
                    };
                    item.ClassIndex = reader.ReadInt16();
                    item.ID         = (reader.ReadInt16() << 16) | i;
                    item.Offset     = reader.ReadInt32() - cache.Magic;
                    item.Index      = i;
                    Add(item);
                }
                #endregion

                #region Read Indices
                reader.SeekTo(cacheHeader.TagNamesIndicesOffset);
                int[] indices = new int[indexHeader.TagCount];
                for (int i = 0; i < indexHeader.TagCount; i++)
                {
                    indices[i] = reader.ReadInt32();
                }
                #endregion

                #region Read Names
                reader.SeekTo(cacheHeader.TagNamesBufferOffset);

                EndianReader newReader = null;

                if (cache.TagsKey == "" || cache.TagsKey == null)
                {
                    newReader = new EndianReader(new MemoryStream(reader.ReadBytes(cacheHeader.TagNamesBufferSize)), EndianFormat.BigEndian);
                }
                else
                {
                    reader.BaseStream.Position = cacheHeader.TagNamesBufferOffset;
                    newReader = new EndianReader(reader.DecryptAesSegment(cacheHeader.TagNamesBufferSize, cache.TagsKey), EndianFormat.BigEndian);
                }

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

                    newReader.SeekTo(indices[i]);

                    int length;
                    if (i == indices.Length - 1)
                    {
                        length = cacheHeader.TagNamesBufferSize - 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) ? cacheHeader.TagNamesBufferSize - indices[i] : indices[index] - indices[i];
                        }
                        else
                        {
                            length = indices[i + 1] - indices[i];
                        }
                    }

                    if (length == 1)
                    {
                        this[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];
                    }

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

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