internal void ReadItems() { if (items.Any()) { throw new InvalidOperationException(); } using (var reader = cache.CreateReader(cache.MetadataTranslator)) { reader.Seek(TagClassDataPointer.Address, SeekOrigin.Begin); Classes.AddRange(reader.ReadEnumerable <TagClass>(TagClassCount)); reader.Seek(TagDataPointer.Address, SeekOrigin.Begin); for (int i = 0; i < TagCount; i++) { //every Reach map has an empty tag var item = reader.ReadObject(new IndexItem(cache, i)); if (item.ClassIndex < 0) { continue; } items.Add(i, item); if (item.ClassCode != CacheFactory.ScenarioClass && CacheFactory.SystemClasses.Contains(item.ClassCode)) { sysItems.Add(item.ClassCode, item); } } reader.Seek(cache.Header.FileTableIndexPointer.Address, SeekOrigin.Begin); var indices = reader.ReadEnumerable <int>(TagCount).ToArray(); reader.Seek(cache.Header.FileTablePointer.Address, SeekOrigin.Begin); var decrypted = reader.ReadAesBytes(cache.Header.FileTableSize, cache.CacheType == CacheType.HaloReachBeta ? CacheFile.BetaKey : CacheFile.FileNamesKey); using (var ms = new MemoryStream(decrypted)) using (var tempReader = new EndianReader(ms)) { for (int i = 0; i < TagCount; i++) { if (indices[i] == -1) { Filenames.Add(i, null); continue; } tempReader.Seek(indices[i], SeekOrigin.Begin); Filenames.Add(i, tempReader.ReadNullTerminatedString()); } } } try { sysItems[CacheFactory.ScenarioClass] = items.Values.Single(i => i.ClassCode == CacheFactory.ScenarioClass && i.FullPath == cache.Header.ScenarioName); } catch { throw Exceptions.AmbiguousScenarioReference(); } }
internal void ReadItems() { if (items.Any()) { throw new InvalidOperationException(); } using (var reader = cache.CreateReader(cache.MetadataTranslator, cache.PointerExpander)) { reader.Seek(TagClassDataPointer.Address, SeekOrigin.Begin); Classes.AddRange(reader.ReadEnumerable <TagClass>(TagClassCount)); reader.Seek(TagDataPointer.Address, SeekOrigin.Begin); for (int i = 0; i < TagCount; i++) { var item = reader.ReadObject(new IndexItem(cache, i)); if (item.ClassIndex < 0) { continue; } items.Add(i, item); if (item.ClassCode != CacheFactory.ScenarioClass && CacheFactory.SystemClasses.Contains(item.ClassCode)) { sysItems.Add(item.ClassCode, item); } } var play = sysItems["play"]; if (play.MetaPointer.Value == 0) { play.MetaPointer = new Pointer(sysItems["zone"].MetaPointer.Value + 28, cache.MetadataTranslator); } reader.Seek(cache.Header.FileTableIndexPointer.Address, SeekOrigin.Begin); var indices = reader.ReadEnumerable <int>(TagCount).ToArray(); reader.Seek(cache.Header.FileTablePointer.Address, SeekOrigin.Begin); using (var tempReader = reader.CreateVirtualReader()) { for (int i = 0; i < TagCount; i++) { if (indices[i] == -1) { Filenames.Add(i, null); continue; } tempReader.Seek(indices[i], SeekOrigin.Begin); Filenames.Add(i, tempReader.ReadNullTerminatedString()); } } } try { sysItems[CacheFactory.ScenarioClass] = items.Values.Single(i => i.ClassCode == CacheFactory.ScenarioClass && i.FullPath == cache.Header.ScenarioName); } catch { throw Exceptions.AmbiguousScenarioReference(); } }
internal void ReadItems() { if (items.Any()) { throw new InvalidOperationException(); } using (var reader = cache.CreateReader(cache.MetadataTranslator)) { reader.Seek(TagClassDataPointer.Address, SeekOrigin.Begin); Classes.AddRange(reader.ReadEnumerable <TagClass>(TagClassCount)); reader.Seek(TagDataPointer.Address, SeekOrigin.Begin); for (int i = 0; i < TagCount; i++) { var item = reader.ReadObject(new IndexItem(cache, i)); if (item.ClassIndex < 0) { continue; } items.Add(i, item); if (item.ClassCode != CacheFactory.ScenarioClass && CacheFactory.SystemClasses.Contains(item.ClassCode)) { sysItems.Add(item.ClassCode, item); } } // hack to redirect any play tag requests to the start of the zone tag when there is no play tag var play = sysItems["play"]; if (play.MetaPointer.Value == 0) { play.MetaPointer = new Pointer(sysItems["zone"].MetaPointer.Value + 28, cache.MetadataTranslator); } reader.Seek(cache.Header.FileTableIndexPointer.Address, SeekOrigin.Begin); var indices = reader.ReadEnumerable <int>(TagCount).ToArray(); reader.Seek(cache.Header.FileTablePointer.Address, SeekOrigin.Begin); var decrypted = reader.ReadAesBytes(cache.Header.FileTableSize, CacheFile.FileNamesKey); using (var ms = new MemoryStream(decrypted)) using (var tempReader = new EndianReader(ms)) { for (int i = 0; i < TagCount; i++) { if (indices[i] == -1) { Filenames.Add(i, null); continue; } tempReader.Seek(indices[i], SeekOrigin.Begin); Filenames.Add(i, tempReader.ReadNullTerminatedString()); } } } try { sysItems[CacheFactory.ScenarioClass] = items.Values.Single(i => i.ClassCode == CacheFactory.ScenarioClass && i.FullPath == cache.Header.ScenarioName); } catch { throw Exceptions.AmbiguousScenarioReference(); } }