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; }
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; } } }
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); }
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)); }
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 }
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(); }
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(); }
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 }