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");
            }
        }
Exemple #2
0
        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");
            }
        }
Exemple #3
0
        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;
            }
        }
Exemple #4
0
        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());
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }