Exemplo n.º 1
0
        private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
                {
                default:                        //None
                {
                    reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
                    break;
                }

                case 1:     //LZMA
                {
                    SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case 2:     //LZ4
                case 3:     //LZ4HC
                {
                    var compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
                    using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                    {
                        lz4Stream.CopyTo(blocksStream, blockInfo.uncompressedSize);
                    }
                    break;
                }
                }
            }
            blocksStream.Position = 0;
        }
Exemplo n.º 2
0
        private void ReadBlocksAndDirectory(EndianBinaryReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
                if (blockInfo.flags == 1)
                {
                    using (var memoryStream = new MemoryStream(uncompressedBytes))
                    {
                        using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
                        {
                            uncompressedBytes = decompressStream.ToArray();
                        }
                    }
                }
                blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
            }
            blocksStream.Position = 0;
            var blocksReader = new EndianBinaryReader(blocksStream);
            var nodesCount   = blocksReader.ReadInt32();

            m_DirectoryInfo = new Node[nodesCount];
            for (int i = 0; i < nodesCount; i++)
            {
                m_DirectoryInfo[i] = new Node
                {
                    path   = blocksReader.ReadStringToNull(),
                    offset = blocksReader.ReadUInt32(),
                    size   = blocksReader.ReadUInt32()
                };
            }
        }
Exemplo n.º 3
0
        private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                var compressionType = (CompressionType)(blockInfo.flags & StorageBlockFlags.CompressionTypeMask);
                switch (compressionType)
                {
                case CompressionType.None:
                {
                    reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
                    break;
                }

                case CompressionType.Lzma:
                {
                    SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case CompressionType.Lz4:
                case CompressionType.Lz4HC:
                {
                    var compressedSize  = (int)blockInfo.compressedSize;
                    var compressedBytes = BigArrayPool <byte> .Shared.Rent(compressedSize);

                    reader.Read(compressedBytes, 0, compressedSize);
                    var uncompressedSize  = (int)blockInfo.uncompressedSize;
                    var uncompressedBytes = BigArrayPool <byte> .Shared.Rent(uncompressedSize);

                    var numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
                    if (numWrite != uncompressedSize)
                    {
                        throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
                    }
                    blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
                    BigArrayPool <byte> .Shared.Return(compressedBytes);

                    BigArrayPool <byte> .Shared.Return(uncompressedBytes);

                    break;
                }

                default:
                    throw new IOException($"Unsupported compression type {compressionType}");
                }
            }
            blocksStream.Position = 0;
        }
Exemplo n.º 4
0
        private void ReadBlocks(EndianBinaryReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                switch (blockInfo.flags & 0x3F) //kStorageBlockCompressionTypeMask
                {
                default:                        //None
                {
                    reader.BaseStream.CopyTo(blocksStream, blockInfo.compressedSize);
                    break;
                }

                case 1:     //LZMA
                {
                    SevenZipHelper.StreamDecompress(reader.BaseStream, blocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case 2:     //LZ4
                case 3:     //LZ4HC
                {
                    var compressedSize  = (int)blockInfo.compressedSize;
                    var compressedBytes = BigArrayPool <byte> .Shared.Rent(compressedSize);

                    reader.Read(compressedBytes, 0, compressedSize);
                    var uncompressedSize  = (int)blockInfo.uncompressedSize;
                    var uncompressedBytes = BigArrayPool <byte> .Shared.Rent(uncompressedSize);

                    var numWrite = LZ4Codec.Decode(compressedBytes, 0, compressedSize, uncompressedBytes, 0, uncompressedSize);
                    if (numWrite != uncompressedSize)
                    {
                        throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
                    }
                    blocksStream.Write(uncompressedBytes, 0, uncompressedSize);
                    BigArrayPool <byte> .Shared.Return(compressedBytes);

                    BigArrayPool <byte> .Shared.Return(uncompressedBytes);

                    break;
                }
                }
            }
            blocksStream.Position = 0;
        }
Exemplo n.º 5
0
        public BundleFile(EndianBinaryReader bundleReader, string path)
        {
            this.path = path;
            var signature = bundleReader.ReadStringToNull();

            switch (signature)
            {
            case "UnityWeb":
            case "UnityRaw":
            case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
            {
                var format = bundleReader.ReadInt32();
                versionPlayer = bundleReader.ReadStringToNull();
                versionEngine = bundleReader.ReadStringToNull();
                if (format < 6)
                {
                    int bundleSize = bundleReader.ReadInt32();
                }
                else if (format == 6)
                {
                    ReadFormat6(bundleReader, true);
                    return;
                }
                short dummy2     = bundleReader.ReadInt16();
                int   offset     = bundleReader.ReadInt16();
                int   dummy3     = bundleReader.ReadInt32();
                int   lzmaChunks = bundleReader.ReadInt32();

                int  lzmaSize   = 0;
                long streamSize = 0;

                for (int i = 0; i < lzmaChunks; i++)
                {
                    lzmaSize   = bundleReader.ReadInt32();
                    streamSize = bundleReader.ReadInt32();
                }

                bundleReader.Position = offset;
                switch (signature)
                {
                case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":             //.bytes
                case "UnityWeb":
                {
                    var lzmaBuffer = bundleReader.ReadBytes(lzmaSize);
                    using (var lzmaStream = new EndianBinaryReader(SevenZipHelper.StreamDecompress(new MemoryStream(lzmaBuffer))))
                    {
                        GetAssetsFiles(lzmaStream, 0);
                    }
                    break;
                }

                case "UnityRaw":
                {
                    GetAssetsFiles(bundleReader, offset);
                    break;
                }
                }
                break;
            }

            case "UnityFS":
            {
                var format = bundleReader.ReadInt32();
                versionPlayer = bundleReader.ReadStringToNull();
                versionEngine = bundleReader.ReadStringToNull();
                if (format == 6)
                {
                    ReadFormat6(bundleReader);
                }
                break;
            }
            }
        }
Exemplo n.º 6
0
        private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false)
        {
            var bundleSize       = bundleReader.ReadInt64();
            int compressedSize   = bundleReader.ReadInt32();
            int uncompressedSize = bundleReader.ReadInt32();
            int flag             = bundleReader.ReadInt32();

            if (padding)
            {
                bundleReader.ReadByte();
            }
            byte[] blocksInfoBytes;
            if ((flag & 0x80) != 0)//at end of file
            {
                var position = bundleReader.Position;
                bundleReader.Position = bundleReader.BaseStream.Length - compressedSize;
                blocksInfoBytes       = bundleReader.ReadBytes(compressedSize);
                bundleReader.Position = position;
            }
            else
            {
                blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoDecompressedStream;

            switch (flag & 0x3F)
            {
            default:    //None
            {
                blocksInfoDecompressedStream = blocksInfoCompressedStream;
                break;
            }

            case 1:    //LZMA
            {
                blocksInfoDecompressedStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
                blocksInfoCompressedStream.Close();
                break;
            }

            case 2:    //LZ4
            case 3:    //LZ4HC
            {
                byte[] uncompressedBytes = new byte[uncompressedSize];
                using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedSize);
                }
                blocksInfoDecompressedStream = new MemoryStream(uncompressedBytes);
                break;
            }
                //case 4:LZHAM?
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoDecompressedStream))
            {
                blocksInfoReader.Position = 0x10;
                int blockcount = blocksInfoReader.ReadInt32();
                var blockInfos = new BlockInfo[blockcount];
                for (int i = 0; i < blockcount; i++)
                {
                    blockInfos[i] = new BlockInfo
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flag             = blocksInfoReader.ReadInt16()
                    };
                }
                Stream dataStream;
                var    uncompressedSizeSum = blockInfos.Sum(x => x.uncompressedSize);
                if (uncompressedSizeSum > int.MaxValue)
                {
                    /*var memoryMappedFile = MemoryMappedFile.CreateNew(Path.GetFileName(path), uncompressedSizeSum);
                     * assetsDataStream = memoryMappedFile.CreateViewStream();*/
                    dataStream = new FileStream(path + ".temp", FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose);
                }
                else
                {
                    dataStream = new MemoryStream((int)uncompressedSizeSum);
                }
                foreach (var blockInfo in blockInfos)
                {
                    switch (blockInfo.flag & 0x3F)
                    {
                    default:    //None
                    {
                        bundleReader.BaseStream.CopyTo(dataStream, blockInfo.compressedSize);
                        break;
                    }

                    case 1:    //LZMA
                    {
                        SevenZipHelper.StreamDecompress(bundleReader.BaseStream, dataStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                        break;
                    }

                    case 2:    //LZ4
                    case 3:    //LZ4HC
                    {
                        var lz4Stream = new Lz4DecoderStream(bundleReader.BaseStream, blockInfo.compressedSize);
                        lz4Stream.CopyTo(dataStream, blockInfo.uncompressedSize);
                        break;
                    }
                        //case 4:LZHAM?
                    }
                }
                dataStream.Position = 0;
                using (dataStream)
                {
                    var entryinfo_count = blocksInfoReader.ReadInt32();
                    for (int i = 0; i < entryinfo_count; i++)
                    {
                        var file             = new StreamFile();
                        var entryinfo_offset = blocksInfoReader.ReadInt64();
                        var entryinfo_size   = blocksInfoReader.ReadInt64();
                        flag          = blocksInfoReader.ReadInt32();
                        file.fileName = Path.GetFileName(blocksInfoReader.ReadStringToNull());
                        if (entryinfo_size > int.MaxValue)
                        {
                            /*var memoryMappedFile = MemoryMappedFile.CreateNew(file.fileName, entryinfo_size);
                             * file.stream = memoryMappedFile.CreateViewStream();*/
                            var extractPath = path + "_unpacked\\";
                            Directory.CreateDirectory(extractPath);
                            file.stream = File.Create(extractPath + file.fileName);
                        }
                        else
                        {
                            file.stream = new MemoryStream((int)entryinfo_size);
                        }
                        dataStream.Position = entryinfo_offset;
                        dataStream.CopyTo(file.stream, entryinfo_size);
                        file.stream.Position = 0;
                        fileList.Add(file);
                    }
                }
            }
        }
Exemplo n.º 7
0
        private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
        {
            byte[] blocksInfoBytes;
            if (m_Header.version >= 7)
            {
                reader.AlignStream(16);
            }
            if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
            {
                var position = reader.Position;
                reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
                reader.Position = position;
            }
            else //0x40 kArchiveBlocksAndDirectoryInfoCombined
            {
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoUncompresseddStream;

            switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
            {
            default:                       //None
            {
                blocksInfoUncompresseddStream = blocksInfoCompressedStream;
                break;
            }

            case 1:     //LZMA
            {
                blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
                blocksInfoCompressedStream.Close();
                break;
            }

            case 2:     //LZ4
            case 3:     //LZ4HC
            {
                var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
                using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
                }
                blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
                break;
            }
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
            {
                var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
                var blocksInfoCount      = blocksInfoReader.ReadInt32();
                m_BlocksInfo = new StorageBlock[blocksInfoCount];
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    m_BlocksInfo[i] = new StorageBlock
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flags            = blocksInfoReader.ReadUInt16()
                    };
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                m_DirectoryInfo = new Node[nodesCount];
                for (int i = 0; i < nodesCount; i++)
                {
                    m_DirectoryInfo[i] = new Node
                    {
                        offset = blocksInfoReader.ReadInt64(),
                        size   = blocksInfoReader.ReadInt64(),
                        flags  = blocksInfoReader.ReadUInt32(),
                        path   = blocksInfoReader.ReadStringToNull(),
                    };
                }
            }
        }
Exemplo n.º 8
0
        private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
        {
            byte[] blocksInfoBytes;
            if (m_Header.version >= 7)
            {
                reader.AlignStream(16);
            }
            if ((m_Header.flags & ArchiveFlags.BlocksInfoAtTheEnd) != 0)
            {
                var position = reader.Position;
                reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
                reader.Position = position;
            }
            else //0x40 BlocksAndDirectoryInfoCombined
            {
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
            }
            MemoryStream blocksInfoUncompresseddStream;
            var          uncompressedSize = m_Header.uncompressedBlocksInfoSize;
            var          compressionType  = (CompressionType)(m_Header.flags & ArchiveFlags.CompressionTypeMask);

            switch (compressionType)
            {
            case CompressionType.None:
            {
                blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
                break;
            }

            case CompressionType.Lzma:
            {
                blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
                using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
                {
                    SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
                }
                blocksInfoUncompresseddStream.Position = 0;
                break;
            }

            case CompressionType.Lz4:
            case CompressionType.Lz4HC:
            {
                var uncompressedBytes = new byte[uncompressedSize];
                var numWrite          = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
                if (numWrite != uncompressedSize)
                {
                    throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
                }
                blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
                break;
            }

            default:
                throw new IOException($"Unsupported compression type {compressionType}");
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
            {
                var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
                var blocksInfoCount      = blocksInfoReader.ReadInt32();
                m_BlocksInfo = new StorageBlock[blocksInfoCount];
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    m_BlocksInfo[i] = new StorageBlock
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flags            = (StorageBlockFlags)blocksInfoReader.ReadUInt16()
                    };
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                m_DirectoryInfo = new Node[nodesCount];
                for (int i = 0; i < nodesCount; i++)
                {
                    m_DirectoryInfo[i] = new Node
                    {
                        offset = blocksInfoReader.ReadInt64(),
                        size   = blocksInfoReader.ReadInt64(),
                        flags  = blocksInfoReader.ReadUInt32(),
                        path   = blocksInfoReader.ReadStringToNull(),
                    };
                }
            }
            if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
            {
                reader.AlignStream(16);
            }
        }
Exemplo n.º 9
0
        private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
        {
            byte[] blocksInfoBytes;
            if (m_Header.version >= 7)
            {
                reader.AlignStream(16);
            }
            if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
            {
                var position = reader.Position;
                reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
                reader.Position = position;
            }
            else //0x40 kArchiveBlocksAndDirectoryInfoCombined
            {
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
            }
            MemoryStream blocksInfoUncompresseddStream;
            var          uncompressedSize = m_Header.uncompressedBlocksInfoSize;

            switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
            {
            default:                       //None
            {
                blocksInfoUncompresseddStream = new MemoryStream(blocksInfoBytes);
                break;
            }

            case 1:     //LZMA
            {
                blocksInfoUncompresseddStream = new MemoryStream((int)(uncompressedSize));
                using (var blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes))
                {
                    SevenZipHelper.StreamDecompress(blocksInfoCompressedStream, blocksInfoUncompresseddStream, m_Header.compressedBlocksInfoSize, m_Header.uncompressedBlocksInfoSize);
                }
                blocksInfoUncompresseddStream.Position = 0;
                break;
            }

            case 2:     //LZ4
            case 3:     //LZ4HC
            {
                var uncompressedBytes = new byte[uncompressedSize];
                var numWrite          = LZ4Codec.Decode(blocksInfoBytes, uncompressedBytes);
                if (numWrite != uncompressedSize)
                {
                    throw new IOException($"Lz4 decompression error, write {numWrite} bytes but expected {uncompressedSize} bytes");
                }
                blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
                break;
            }
            }
            using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
            {
                var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
                var blocksInfoCount      = blocksInfoReader.ReadInt32();
                m_BlocksInfo = new StorageBlock[blocksInfoCount];
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    m_BlocksInfo[i] = new StorageBlock
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flags            = blocksInfoReader.ReadUInt16()
                    };
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                m_DirectoryInfo = new Node[nodesCount];
                for (int i = 0; i < nodesCount; i++)
                {
                    m_DirectoryInfo[i] = new Node
                    {
                        offset = blocksInfoReader.ReadInt64(),
                        size   = blocksInfoReader.ReadInt64(),
                        flags  = blocksInfoReader.ReadUInt32(),
                        path   = blocksInfoReader.ReadStringToNull(),
                    };
                }
            }
        }
Exemplo n.º 10
0
        private void ReadFormat6(EndianBinaryReader bundleReader, bool padding = false)
        {
            var bundleSize       = bundleReader.ReadInt64();
            int compressedSize   = bundleReader.ReadInt32();
            int uncompressedSize = bundleReader.ReadInt32();
            int flag             = bundleReader.ReadInt32();

            if (padding)
            {
                bundleReader.ReadByte();
            }
            byte[] blocksInfoBytes;
            if ((flag & 0x80) != 0)//at end of file
            {
                var position = bundleReader.Position;
                bundleReader.Position = bundleReader.BaseStream.Length - compressedSize;
                blocksInfoBytes       = bundleReader.ReadBytes(compressedSize);
                bundleReader.Position = position;
            }
            else
            {
                blocksInfoBytes = bundleReader.ReadBytes(compressedSize);
            }
            MemoryStream blocksInfoStream;

            switch (flag & 0x3F)
            {
            default:    //None
            {
                blocksInfoStream = new MemoryStream(blocksInfoBytes);
                break;
            }

            case 1:    //LZMA
            {
                blocksInfoStream = SevenZipHelper.StreamDecompress(new MemoryStream(blocksInfoBytes));
                break;
            }

            case 2:    //LZ4
            case 3:    //LZ4HC
            {
                byte[] uncompressedBytes = new byte[uncompressedSize];
                using (var decoder = new Lz4DecoderStream(new MemoryStream(blocksInfoBytes)))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedSize);
                }
                blocksInfoStream = new MemoryStream(uncompressedBytes);
                break;
            }
                //case 4:LZHAM?
            }
            using (var blocksInfo = new EndianBinaryReader(blocksInfoStream))
            {
                blocksInfo.Position = 0x10;
                int blockcount       = blocksInfo.ReadInt32();
                var assetsDataStream = new MemoryStream();
                for (int i = 0; i < blockcount; i++)
                {
                    uncompressedSize = blocksInfo.ReadInt32();
                    compressedSize   = blocksInfo.ReadInt32();
                    flag             = blocksInfo.ReadInt16();
                    var compressedBytes = bundleReader.ReadBytes(compressedSize);
                    switch (flag & 0x3F)
                    {
                    default:    //None
                    {
                        assetsDataStream.Write(compressedBytes, 0, compressedSize);
                        break;
                    }

                    case 1:    //LZMA
                    {
                        var uncompressedBytes = new byte[uncompressedSize];
                        using (var mstream = new MemoryStream(compressedBytes))
                        {
                            var decoder = SevenZipHelper.StreamDecompress(mstream, uncompressedSize);
                            decoder.Read(uncompressedBytes, 0, uncompressedSize);
                            decoder.Dispose();
                        }
                        assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                        break;
                    }

                    case 2:    //LZ4
                    case 3:    //LZ4HC
                    {
                        var uncompressedBytes = new byte[uncompressedSize];
                        using (var decoder = new Lz4DecoderStream(new MemoryStream(compressedBytes)))
                        {
                            decoder.Read(uncompressedBytes, 0, uncompressedSize);
                        }
                        assetsDataStream.Write(uncompressedBytes, 0, uncompressedSize);
                        break;
                    }
                        //case 4:LZHAM?
                    }
                }
                using (var assetsDataReader = new EndianBinaryReader(assetsDataStream))
                {
                    var entryinfo_count = blocksInfo.ReadInt32();
                    for (int i = 0; i < entryinfo_count; i++)
                    {
                        var file             = new MemoryFile();
                        var entryinfo_offset = blocksInfo.ReadInt64();
                        var entryinfo_size   = blocksInfo.ReadInt64();
                        flag                      = blocksInfo.ReadInt32();
                        file.fileName             = Path.GetFileName(blocksInfo.ReadStringToNull());
                        assetsDataReader.Position = entryinfo_offset;
                        var buffer = assetsDataReader.ReadBytes((int)entryinfo_size);
                        file.stream = new MemoryStream(buffer);
                        fileList.Add(file);
                    }
                }
            }
        }