Пример #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;
        }
        private void ReadBlocks(EndianBinaryReader varReader, Stream varBlocksStream)
        {
            foreach (var blockInfo in BlocksInfo)
            {
                switch (blockInfo.GetCompressionType())
                {
                default:     //None
                {
                    varReader.BaseStream.CopyTo(varBlocksStream, blockInfo.compressedSize);
                    break;
                }

                case Compression.CompressionType.kCompressionLzma:     //LZMA
                {
                    SevenZipHelper.StreamDecompress(varReader.BaseStream, varBlocksStream, blockInfo.compressedSize, blockInfo.uncompressedSize);
                    break;
                }

                case Compression.CompressionType.kCompressionLz4:     //LZ4
                case Compression.CompressionType.kCompressionLz4HC:   //LZ4HC
                {
                    var compressedStream = new MemoryStream(varReader.ReadBytes((int)blockInfo.compressedSize));
                    using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                    {
                        lz4Stream.CopyTo(varBlocksStream, blockInfo.uncompressedSize);
                    }
                    break;
                }
                }
            }
            varBlocksStream.Position = 0;
        }
Пример #3
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);
                    }
                }
            }
        }
Пример #4
0
        public Stream OpenAsset(string assetName)
        {
            MemoryStream fileStream = null;
            var          fileNode   = Array.Find(m_DirectoryInfo, node => node.path == assetName);

            if (fileNode != null)
            {
                long skipUncompressed = 0;
                foreach (var blockInfo in m_BlocksInfo)
                {
                    if (fileStream == null)
                    {
                        if (skipUncompressed + blockInfo.uncompressedSize >= fileNode.offset)
                        {
                            fileStream = new MemoryStream();
                        }
                        else
                        {
                            skipUncompressed += blockInfo.uncompressedSize;
                        }
                    }

                    if (fileStream != null)
                    {
                        reader.Position = blockInfo.offset;
                        var    compressedStream = new MemoryStream(reader.ReadBytes((int)blockInfo.compressedSize));
                        byte[] buffer           = new byte[blockInfo.uncompressedSize];

                        using (MemoryStream unCompressStream = new MemoryStream())
                        {
                            using (var lz4Stream = new Lz4DecoderStream(compressedStream))
                            {
                                lz4Stream.CopyTo(unCompressStream);
                            }
                            long begin = 0;
                            if (fileStream.Length == 0)
                            {
                                begin = fileNode.offset - skipUncompressed;
                                if (begin < 0)
                                {
                                    begin = 0;
                                }
                            }
                            unCompressStream.Seek(0, 0);

                            int end = (int)(blockInfo.uncompressedSize - (fileNode.size - fileStream.Position));
                            if (end < 0)
                            {
                                end = 0;
                            }

                            int size  = (int)(blockInfo.uncompressedSize - begin - end);
                            int count = unCompressStream.Read(buffer, (int)begin, size);
                            fileStream.Write(buffer, 0, count);
                            if (fileStream.Length >= fileNode.size)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            fileStream?.Seek(0, 0);
            return(fileStream);
        }