public bool Pack(AssetsFileReader reader, AssetsFileWriter writer, AssetBundleCompressionType compType, bool blockDirAtEnd = true) { reader.Position = 0; writer.Position = 0; if (Read(reader, false)) { AssetBundleHeader06 newHeader = new AssetBundleHeader06() { signature = bundleHeader6.signature, fileVersion = bundleHeader6.fileVersion, minPlayerVersion = bundleHeader6.minPlayerVersion, fileEngineVersion = bundleHeader6.fileEngineVersion, totalFileSize = 0, compressedSize = 0, decompressedSize = 0, flags = (uint)(0x43 | (blockDirAtEnd ? 0x80 : 0x00)) }; AssetBundleBlockAndDirectoryList06 newBlockAndDirList = new AssetBundleBlockAndDirectoryList06() { checksumLow = 0, checksumHigh = 0, blockCount = 0, blockInf = null, directoryCount = bundleInf6.directoryCount, dirInf = bundleInf6.dirInf }; //write header now and overwrite it later long startPos = writer.Position; newHeader.Write(writer); if (newHeader.fileVersion >= 7) { writer.Align16(); } int headerSize = (int)(writer.Position - startPos); long totalCompressedSize = 0; List <AssetBundleBlockInfo06> newBlocks = new List <AssetBundleBlockInfo06>(); List <Stream> newStreams = new List <Stream>(); //used if blockDirAtEnd == false long fileDataOffset = bundleHeader6.GetFileDataOffset(); int fileDataLength = (int)(bundleHeader6.totalFileSize - fileDataOffset); SegmentStream bundleDataStream = new SegmentStream(reader.BaseStream, fileDataOffset, fileDataLength); switch (compType) { case AssetBundleCompressionType.LZMA: { Stream writeStream; if (blockDirAtEnd) { writeStream = writer.BaseStream; } else { writeStream = GetTempFileStream(); } long writeStreamStart = writeStream.Position; SevenZipHelper.Compress(bundleDataStream, writeStream); uint writeStreamLength = (uint)(writeStream.Position - writeStreamStart); AssetBundleBlockInfo06 blockInfo = new AssetBundleBlockInfo06() { compressedSize = writeStreamLength, decompressedSize = (uint)fileDataLength, flags = 0x41 }; totalCompressedSize += blockInfo.compressedSize; newBlocks.Add(blockInfo); if (!blockDirAtEnd) { newStreams.Add(writeStream); } break; } case AssetBundleCompressionType.LZ4: { //compress into 0x20000 blocks BinaryReader bundleDataReader = new BinaryReader(bundleDataStream); byte[] uncompressedBlock = bundleDataReader.ReadBytes(0x20000); while (uncompressedBlock.Length != 0) { Stream writeStream; if (blockDirAtEnd) { writeStream = writer.BaseStream; } else { writeStream = GetTempFileStream(); } byte[] compressedBlock = LZ4Codec.Encode32HC(uncompressedBlock, 0, uncompressedBlock.Length); if (compressedBlock.Length > uncompressedBlock.Length) { writeStream.Write(uncompressedBlock, 0, uncompressedBlock.Length); AssetBundleBlockInfo06 blockInfo = new AssetBundleBlockInfo06() { compressedSize = (uint)uncompressedBlock.Length, decompressedSize = (uint)uncompressedBlock.Length, flags = 0x0 }; totalCompressedSize += blockInfo.compressedSize; newBlocks.Add(blockInfo); } else { writeStream.Write(compressedBlock, 0, compressedBlock.Length); AssetBundleBlockInfo06 blockInfo = new AssetBundleBlockInfo06() { compressedSize = (uint)compressedBlock.Length, decompressedSize = (uint)uncompressedBlock.Length, flags = 0x3 }; totalCompressedSize += blockInfo.compressedSize; newBlocks.Add(blockInfo); } if (!blockDirAtEnd) { newStreams.Add(writeStream); } uncompressedBlock = bundleDataReader.ReadBytes(0x20000); } break; } case AssetBundleCompressionType.NONE: { AssetBundleBlockInfo06 blockInfo = new AssetBundleBlockInfo06() { compressedSize = (uint)fileDataLength, decompressedSize = (uint)fileDataLength, flags = 0x00 }; totalCompressedSize += blockInfo.compressedSize; newBlocks.Add(blockInfo); if (blockDirAtEnd) { bundleDataStream.CopyToCompat(writer.BaseStream); } else { newStreams.Add(bundleDataStream); } break; } } newBlockAndDirList.blockInf = newBlocks.ToArray(); byte[] bundleInfoBytes; using (MemoryStream memStream = new MemoryStream()) { AssetsFileWriter infoWriter = new AssetsFileWriter(memStream); newBlockAndDirList.Write(infoWriter); bundleInfoBytes = memStream.ToArray(); } //listing is usually lz4 even if the data blocks are lzma byte[] bundleInfoBytesCom = LZ4Codec.Encode32HC(bundleInfoBytes, 0, bundleInfoBytes.Length); long totalFileSize = headerSize + bundleInfoBytesCom.Length + totalCompressedSize; newHeader.totalFileSize = totalFileSize; newHeader.decompressedSize = (uint)bundleInfoBytes.Length; newHeader.compressedSize = (uint)bundleInfoBytesCom.Length; if (!blockDirAtEnd) { writer.Write(bundleInfoBytesCom); foreach (Stream newStream in newStreams) { newStream.Position = 0; newStream.CopyToCompat(writer.BaseStream); newStream.Close(); } } else { writer.Write(bundleInfoBytesCom); } writer.Position = 0; newHeader.Write(writer); if (newHeader.fileVersion >= 7) { writer.Align16(); } return(true); } return(false); }