Ejemplo n.º 1
0
        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);
                }

                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))
                        {
                            Read530Blocks(dataStream);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        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");
            }
        }
Ejemplo n.º 3
0
        public void Read(BundleFileReader reader)
        {
            if (IsReadBlockInfo(reader.Generation))
            {
                // unknown 0x10
                reader.BaseStream.Position += 0x10;
                BlockInfos = reader.ReadBundleArray <BlockInfo>();
            }

            int count = reader.ReadInt32();
            Dictionary <string, BundleFileEntry> entries = new Dictionary <string, BundleFileEntry>(count);

            for (int i = 0; i < count; i++)
            {
                BundleFileEntry entry = reader.ReadBundle <BundleFileEntry>();
                entries.Add(entry.Name, entry);
            }
            Entries = entries;
        }
Ejemplo n.º 4
0
        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());
        }