private void ReadScheme() { using (PartialStream stream = new PartialStream(m_stream, m_offset, m_size)) { using (EndianReader reader = new EndianReader(stream, EndianType.BigEndian)) { Header.Read(reader); } long headerSize = stream.Position; using (BundleFileReader reader = new BundleFileReader(stream, EndianType.BigEndian, Header.Generation)) { if (reader.Generation < BundleGeneration.BF_530_x) { using (SmartStream dataStream = ReadPre530Metadata(reader)) { ReadPre530Blocks(dataStream); } } else { using (SmartStream dataStream = Read530Metadata(reader, headerSize)) { Read530Blocks(dataStream, headerSize); } } } } }
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"); } }
public void Read(BundleFileReader reader) { if (IsReadBlobIndex(reader.Generation)) { Offset = reader.ReadInt64(); Size = reader.ReadInt64(); BlobIndex = reader.ReadInt32(); NameOrigin = reader.ReadStringZeroTerm(); } else { NameOrigin = reader.ReadStringZeroTerm(); Offset = reader.ReadInt32(); Size = reader.ReadInt32(); } Name = FilenameUtils.FixFileIdentifier(NameOrigin); }
public void Read(BundleFileReader reader) { DecompressedSize = reader.ReadUInt32(); CompressedSize = reader.ReadUInt32(); Flags = (BundleFlag)reader.ReadUInt16(); }
private SmartStream Read530Metadata(BundleFileReader reader, long headerSize) { 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 : headerSize + Header.MetadataDecompressedSize; if (reader.BaseStream.Position != expectedPosition) { throw new Exception($"Read {reader.BaseStream.Position - 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) { throw new Exception($"Read {read} but expected {Header.MetadataDecompressedSize}"); } if (decodeStream.IsDataLeft) { throw new Exception($"LZ4 stream still has some data"); } } 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()); }