private void ProcessChunkFile(PackageChildEntry childEntry, IEnumerable <IPackageProcessor> matchingPackageProcessors)
        {
            foreach (IPackageProcessor packageFileProcessor in matchingPackageProcessors)
            {
                cachedSubStream.Initialize(reader.BaseStream, childEntry.FileOffset, childEntry.FileSize);

                Stream workStream = cachedSubStream;

                if (packageFileProcessor.Crypto != null)
                {
                    byte[] buffer = new byte[workStream.Length];

                    workStream.Read(buffer);

                    var blowfish = new MHWCrypto.Blowfish(packageFileProcessor.Crypto.Key);
                    blowfish.Decrypt(buffer);

                    workStream = new MemoryStream(buffer);
                }

                try
                {
                    packageFileProcessor.ProcessChunkFile(workStream, childEntry.ChunkFullFilename);
                }
                catch (SkipException ex)
                {
                    logger.LogInformation($"Skipped '{(reader.BaseStream is FileStream fs ? fs.Name : "<unknown>")}' => '{childEntry.ChunkFullFilename}' [{ex.Message}] ");
                }
            }
        }
        private void RunMatchingPackageProcessors(PackageChildEntry childEntry, IEnumerable <IPackageProcessor> matchingPackageProcessors)
        {
            PreChunkFileProcess(matchingPackageProcessors, childEntry.ChunkFullFilename);

            long savedPosition = reader.BaseStream.Position;

            try
            {
                ProcessChunkFile(childEntry, matchingPackageProcessors);
            }
            finally
            {
                reader.BaseStream.Seek(savedPosition, SeekOrigin.Begin);
            }

            PostChunkFileProcess(matchingPackageProcessors, childEntry.ChunkFullFilename);
        }
        private void ProcessChildEntry()
        {
            var childEntry = PackageChildEntry.Read(reader);

            if (childEntry.EntryType == 1) // Folder
            {
                return;
            }

            if (childEntry.EntryType != 0 && childEntry.EntryType != 2)
            {
                logger?.LogError($"Found file in chunk but unexpected entry type (expected 0, actual is {childEntry.EntryType})");
                return;
            }

            IEnumerable <IPackageProcessor> matchingPackageProcessors = packageProcessors
                                                                        .Where(x => x.IsChunkFileMatching(childEntry.ChunkFullFilename))
                                                                        .ToList(); // <-- Need to freeze the state here, since iterated many times.

            RunMatchingPackageProcessors(childEntry, matchingPackageProcessors);
        }