Ejemplo n.º 1
0
        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(); }
        }
Ejemplo n.º 2
0
        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(); }
        }
Ejemplo n.º 3
0
        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(); }
        }