private SmartStream ReadPre530Metadata(BundleFileReader reader) { switch (Header.Type) { case BundleType.UnityRaw: { Metadata.Read(reader); return(m_stream.CreateReference()); } case BundleType.UnityWeb: { // read only last chunk. wtf? ChunkInfo chunkInfo = Header.ChunkInfos[Header.ChunkInfos.Count - 1]; using (SmartStream stream = SmartStream.CreateMemory(new byte[chunkInfo.DecompressedSize])) { SevenZipHelper.DecompressLZMASizeStream(reader.BaseStream, chunkInfo.CompressedSize, stream); using (BundleFileReader decompressReader = new BundleFileReader(stream, reader.EndianType, reader.Generation)) { Metadata.Read(decompressReader); } return(stream.CreateReference()); } } default: throw new NotSupportedException($"Bundle type {Header.Type} isn't supported before 530 generation"); } }
private void ReadPre530Metadata(EndianReader reader) { switch (Header.Type) { case BundleType.UnityRaw: { Metadata = new BundleMetadata(m_filePath); Metadata.ReadPre530(reader); } break; case BundleType.UnityWeb: case BundleType.HexFA: { // read only last chunk. wtf? ChunkInfo chunkInfo = Header.ChunkInfos[Header.ChunkInfos.Count - 1]; using (SmartStream stream = SmartStream.CreateMemory(new byte[chunkInfo.DecompressedSize])) { SevenZipHelper.DecompressLZMASizeStream(reader.BaseStream, chunkInfo.CompressedSize, stream); Metadata = new BundleMetadata(m_filePath); using (EndianReader decompressReader = new EndianReader(stream, EndianType.BigEndian)) { Metadata.ReadPre530(decompressReader); } } } break; default: throw new NotSupportedException($"Bundle type {Header.Type} isn't supported before 530 generation"); } }
private void ParseBundleFormat(EndianStream stream) { int bundleSize = stream.ReadInt32(); short unused16 = stream.ReadInt16(); int offset = stream.ReadInt16(); int unused32 = stream.ReadInt32(); int lzmaChunkCount = stream.ReadInt32(); if (lzmaChunkCount != 1) { // see original project, it support only 1 chunk throw new Exception($"Found lzma with {lzmaChunkCount} chunks"); } MemoryStream memStream = IsBundlePacked ? new MemoryStream() : null; for (int i = 0; i < lzmaChunkCount; i++) { int lzmaSize = stream.ReadInt32(); int decompressedSize = stream.ReadInt32(); stream.BaseStream.Position = offset; switch (Signature) { case BundleSignature.UnityRaw: ParseBundleFiles(stream); break; case BundleSignature.UnityWeb: case BundleSignature.HexFA: memStream.Position = 0; SevenZipHelper.DecompressLZMASizeStream(stream.BaseStream, lzmaSize, memStream); using (EndianStream decompressStream = new EndianStream(memStream, EndianType.BigEndian)) { ParseBundleFiles(decompressStream); } break; default: throw new Exception($"Unsupported bundle signature '{Signature}'"); } offset += lzmaSize; } }
private void ReadPre530Metadata(EndianStream stream, bool isClosable) { switch (Header.Type) { case BundleType.UnityRaw: { if (Header.ChunkInfos.Count > 1) { throw new NotSupportedException($"Raw data with several chunks {Header.ChunkInfos.Count} isn't supported"); } BundleMetadata metadata = new BundleMetadata(stream.BaseStream, m_filePath, isClosable); metadata.ReadPre530(stream); Metadatas = new BundleMetadata[] { metadata }; } break; case BundleType.UnityWeb: case BundleType.HexFA: { BundleMetadata[] metadatas = new BundleMetadata[Header.ChunkInfos.Count]; for (int i = 0; i < Header.ChunkInfos.Count; i++) { ChunkInfo chunkInfo = Header.ChunkInfos[i]; MemoryStream memStream = new MemoryStream(new byte[chunkInfo.DecompressedSize]); SevenZipHelper.DecompressLZMASizeStream(stream.BaseStream, chunkInfo.CompressedSize, memStream); BundleMetadata metadata = new BundleMetadata(memStream, m_filePath, true); using (EndianStream decompressStream = new EndianStream(memStream, EndianType.BigEndian)) { metadata.ReadPre530(decompressStream); } metadatas[i] = metadata; } Metadatas = metadatas; if (isClosable) { stream.Dispose(); } } break; default: throw new NotSupportedException($"Bundle type {Header.Type} isn't supported before 530 generation"); } }
private SmartStream Read530Metadata(BundleFileReader reader) { if (Header.Flags.IsMetadataAtTheEnd()) { reader.BaseStream.Position = Header.BundleSize - Header.MetadataCompressedSize; } BundleCompressType metaCompression = Header.Flags.GetCompression(); switch (metaCompression) { case BundleCompressType.None: { Metadata.Read(reader); long expectedPosition = Header.Flags.IsMetadataAtTheEnd() ? Header.BundleSize : Header.HeaderSize + Header.MetadataDecompressedSize; if (reader.BaseStream.Position != expectedPosition) { throw new Exception($"Read {reader.BaseStream.Position - Header.HeaderSize} but expected {Header.MetadataDecompressedSize}"); } } break; case BundleCompressType.LZMA: { using (MemoryStream stream = new MemoryStream(new byte[Header.MetadataDecompressedSize])) { SevenZipHelper.DecompressLZMASizeStream(reader.BaseStream, Header.MetadataCompressedSize, stream); using (BundleFileReader decompressReader = new BundleFileReader(stream, reader.EndianType, reader.Generation)) { Metadata.Read(decompressReader); } if (stream.Position != Header.MetadataDecompressedSize) { throw new Exception($"Read {stream.Position} but expected {Header.MetadataDecompressedSize}"); } } } break; case BundleCompressType.LZ4: case BundleCompressType.LZ4HZ: { using (MemoryStream stream = new MemoryStream(new byte[Header.MetadataDecompressedSize])) { using (Lz4DecodeStream decodeStream = new Lz4DecodeStream(reader.BaseStream, Header.MetadataCompressedSize)) { long read = decodeStream.Read(stream, Header.MetadataDecompressedSize); if (read != Header.MetadataDecompressedSize || decodeStream.IsDataLeft) { throw new Exception($"Read {read} but expected {Header.MetadataDecompressedSize}"); } } stream.Position = 0; using (BundleFileReader decompressReader = new BundleFileReader(stream, reader.EndianType, reader.Generation)) { Metadata.Read(decompressReader); } if (stream.Position != Header.MetadataDecompressedSize) { throw new Exception($"Read {stream.Position} but expected {Header.MetadataDecompressedSize}"); } } } break; default: throw new NotSupportedException($"Bundle compression '{metaCompression}' isn't supported"); } return(m_stream.CreateReference()); }
private void Read530Metadata(EndianStream stream, bool isClosable, long basePosition) { long dataPosition = stream.BaseStream.Position; if (Header.Flags.IsMetadataAtTheEnd()) { stream.BaseStream.Position = basePosition + Header.BundleSize - Header.MetadataCompressedSize; } else { dataPosition += Header.MetadataCompressedSize; } BlockInfo[] blockInfos; BundleMetadata metadata; BundleCompressType metaCompress = Header.Flags.GetCompression(); switch (metaCompress) { case BundleCompressType.None: { long metaPosition = stream.BaseStream.Position; // unknown 0x10 stream.BaseStream.Position += 0x10; blockInfos = stream.ReadArray <BlockInfo>(); metadata = new BundleMetadata(stream.BaseStream, m_filePath, isClosable); metadata.Read530(stream, dataPosition); if (stream.BaseStream.Position != metaPosition + Header.MetadataDecompressedSize) { throw new Exception($"Read {stream.BaseStream.Position - metaPosition} but expected {Header.MetadataDecompressedSize}"); } break; } case BundleCompressType.LZMA: { using (MemoryStream memStream = new MemoryStream(Header.MetadataDecompressedSize)) { SevenZipHelper.DecompressLZMASizeStream(stream.BaseStream, Header.MetadataCompressedSize, memStream); memStream.Position = 0; using (EndianStream metadataStream = new EndianStream(memStream, EndianType.BigEndian)) { // unknown 0x10 metadataStream.BaseStream.Position += 0x10; blockInfos = metadataStream.ReadArray <BlockInfo>(); metadata = new BundleMetadata(stream.BaseStream, m_filePath, isClosable); metadata.Read530(metadataStream, dataPosition); if (memStream.Position != memStream.Length) { throw new Exception($"Read {memStream.Position} but expected {memStream.Length}"); } } } break; } case BundleCompressType.LZ4: case BundleCompressType.LZ4HZ: { using (MemoryStream memStream = new MemoryStream(Header.MetadataDecompressedSize)) { using (Lz4Stream lzStream = new Lz4Stream(stream.BaseStream, Header.MetadataCompressedSize)) { long read = lzStream.Read(memStream, Header.MetadataDecompressedSize); memStream.Position = 0; if (read != Header.MetadataDecompressedSize) { throw new Exception($"Read {read} but expected {Header.MetadataDecompressedSize}"); } } using (EndianStream metadataStream = new EndianStream(memStream, EndianType.BigEndian)) { // unknown 0x10 metadataStream.BaseStream.Position += 0x10; blockInfos = metadataStream.ReadArray <BlockInfo>(); metadata = new BundleMetadata(stream.BaseStream, m_filePath, isClosable); metadata.Read530(metadataStream, dataPosition); if (memStream.Position != memStream.Length) { throw new Exception($"Read {memStream.Position} but expected {memStream.Length}"); } } } break; } default: throw new NotSupportedException($"Bundle compression '{metaCompress}' isn't supported"); } stream.BaseStream.Position = dataPosition; Read530Blocks(stream, isClosable, blockInfos, metadata); }
private void Read530Metadata(EndianReader reader, long basePosition) { SmartStream bundleStream = (SmartStream)reader.BaseStream; long dataPosition = bundleStream.Position; if (Header.Flags.IsMetadataAtTheEnd()) { bundleStream.Position = basePosition + Header.BundleSize - Header.MetadataCompressedSize; } else { dataPosition += Header.MetadataCompressedSize; } BlockInfo[] blockInfos; BundleCompressType metaCompression = Header.Flags.GetCompression(); switch (metaCompression) { case BundleCompressType.None: { long metaPosition = bundleStream.Position; // unknown 0x10 bundleStream.Position += 0x10; blockInfos = reader.ReadArray <BlockInfo>(); Metadata = new BundleMetadata(m_filePath); Metadata.Read530(reader, bundleStream); if (bundleStream.Position != metaPosition + Header.MetadataDecompressedSize) { throw new Exception($"Read {bundleStream.Position - metaPosition} but expected {Header.MetadataDecompressedSize}"); } break; } case BundleCompressType.LZMA: { using (MemoryStream metaStream = new MemoryStream(new byte[Header.MetadataDecompressedSize])) { SevenZipHelper.DecompressLZMASizeStream(bundleStream, Header.MetadataCompressedSize, metaStream); using (EndianReader metaReader = new EndianReader(metaStream, EndianType.BigEndian)) { // unknown 0x10 metaReader.BaseStream.Position += 0x10; blockInfos = metaReader.ReadArray <BlockInfo>(); Metadata = new BundleMetadata(m_filePath); Metadata.Read530(metaReader, bundleStream); } if (metaStream.Position != metaStream.Length) { throw new Exception($"Read {metaStream.Position} but expected {metaStream.Length}"); } } break; } case BundleCompressType.LZ4: case BundleCompressType.LZ4HZ: { using (MemoryStream metaStream = new MemoryStream(new byte[Header.MetadataDecompressedSize])) { using (Lz4Stream lzStream = new Lz4Stream(bundleStream, Header.MetadataCompressedSize)) { long read = lzStream.Read(metaStream, Header.MetadataDecompressedSize); metaStream.Position = 0; if (read != Header.MetadataDecompressedSize) { throw new Exception($"Read {read} but expected {Header.MetadataDecompressedSize}"); } } using (EndianReader metaReader = new EndianReader(metaStream, EndianType.BigEndian)) { // unknown 0x10 metaReader.BaseStream.Position += 0x10; blockInfos = metaReader.ReadArray <BlockInfo>(); Metadata = new BundleMetadata(m_filePath); Metadata.Read530(metaReader, bundleStream); } if (metaStream.Position != metaStream.Length) { throw new Exception($"Read {metaStream.Position} but expected {metaStream.Length}"); } } break; } default: throw new NotSupportedException($"Bundle compression '{metaCompression}' isn't supported"); } bundleStream.Position = dataPosition; Read530Blocks(bundleStream, blockInfos); }