public static (byte[] info, int infoLen, byte[] data) BuildFormat6(UnityAssetsBundlePayload bundlePayload) { if (bundlePayload.Files.Length != bundlePayload.Blocks.Length) { throw new Exception($"Expected equal count of blocks(get {bundlePayload.Blocks.Length}) and files(get {bundlePayload.Files.Length})."); } if (bundlePayload.ReadAtEnd) { throw new NotImplementedException("Not support bundles with ReadAtEnd flag"); } //build compressed data (Payload.Blocks) int infoLen; byte[] compressedInfoBytes; //byte[] entriesInfosBytes; byte[] compressedDataBytes; //var blocksInfos = new UnityAssetsBundleReader.BlockInfo[bundlePayload.Files.Length]; using (var compressedDataStream = new MemoryStream()) { var blocksInfosStream = new MemoryStream(); var blocksInfosWriter = new EndianBinaryWriter(blocksInfosStream); var entriesStream = new MemoryStream(); var entriesWriter = new EndianBinaryWriter(entriesStream); blocksInfosWriter.Write(bundlePayload.UnknownBytes); blocksInfosWriter.Write(bundlePayload.Blocks.Length); entriesWriter.Write(bundlePayload.Files.Length); var entryOffset = (long)0; for (int i = 0; i < bundlePayload.Files.Length; i++) { var file = bundlePayload.Files[i]; entriesWriter.Write(entryOffset); entriesWriter.Write((long)file.DataBytes.Length); entriesWriter.Write(file.Flags); entriesWriter.Write(file.Name); entryOffset += file.DataBytes.Length; var compressedEntry = Compress(file.DataBytes, bundlePayload.Blocks[i].CompressionType); compressedDataStream.Write(compressedEntry); blocksInfosWriter.Write((uint)file.DataBytes.LongLength); blocksInfosWriter.Write((uint)compressedEntry.LongLength); blocksInfosWriter.Write(bundlePayload.Blocks[i].Flags); } blocksInfosStream.Write(entriesStream.ToArray()); infoLen = (int)blocksInfosStream.Length; compressedInfoBytes = Compress(blocksInfosStream.ToArray(), bundlePayload.PayloadCompressionType); //entriesInfosBytes = entriesStream.ToArray(); compressedDataBytes = compressedDataStream.ToArray(); } return(compressedInfoBytes, infoLen, compressedDataBytes); }
private static UnityAssetsBundlePayload ReadFormat6(EndianBinaryReader bundleReader, bool padding = false) { var payload = new UnityAssetsBundlePayload(); var payloadBundleSize = bundleReader.ReadInt64(); var payloadCompressedSize = bundleReader.ReadInt32(); var payloadDecompressedSize = bundleReader.ReadInt32(); payload.Flags = bundleReader.ReadInt32(); // if (padding) { bundleReader.ReadByte(); } byte[] compressedBlocksInfoBytes; if (payload.ReadAtEnd)//at end of file { var position = bundleReader.Position; bundleReader.Position = bundleReader.BaseStream.Length - payloadCompressedSize; compressedBlocksInfoBytes = bundleReader.ReadBytes(payloadCompressedSize); bundleReader.Position = position; } else { compressedBlocksInfoBytes = bundleReader.ReadBytes(payloadCompressedSize); } //info var blocksInfoStream = DecompressToMemoryStream(compressedBlocksInfoBytes, payload.PayloadCompressionType, payloadDecompressedSize); using var blocksInfoReader = new EndianBinaryReader(blocksInfoStream); payload.UnknownBytes = blocksInfoReader.ReadBytes(16); var payloadBlocksCount = blocksInfoReader.ReadInt32(); payload.Blocks = new UnityAssetsBundlePayloadBlock[payloadBlocksCount]; var blockInfos = new BlockInfo[payloadBlocksCount]; for (var i = 0; i < payloadBlocksCount; i++) { blockInfos[i] = new BlockInfo() { DecompressedSize = blocksInfoReader.ReadUInt32(), CompressedSize = blocksInfoReader.ReadUInt32(), Flags = blocksInfoReader.ReadInt16() }; payload.Blocks[i] = new UnityAssetsBundlePayloadBlock() { Flags = blockInfos[i].Flags }; } //create stream with decompressed blocks var dataStream = new MemoryStream(); foreach (var blockInfo in blockInfos) { var compressedBytes = bundleReader.ReadBytes((int)blockInfo.CompressedSize); var decompressedMemStream = DecompressToMemoryStream( compressedBytes, blockInfo.CompressionType, (int)blockInfo.DecompressedSize); decompressedMemStream.Position = 0; decompressedMemStream.CopyTo(dataStream, blockInfo.DecompressedSize); } dataStream.Position = 0; //reset using (dataStream) { var entryInfoCount = blocksInfoReader.ReadInt32(); payload.Files = new UnityAssetsBundleStreamFile[entryInfoCount]; for (var i = 0; i < payload.Files.Length; i++) { var offset = blocksInfoReader.ReadInt64(); var size = blocksInfoReader.ReadInt64(); var file = new UnityAssetsBundleStreamFile { Flags = blocksInfoReader.ReadInt32(), Name = blocksInfoReader.ReadStringToNull(), DataBytes = new byte[size] }; dataStream.Position = offset; dataStream.Read(file.DataBytes, 0, (int)size); payload.Files[i] = file; } } return(payload); }