private void ReadTypeTree(List <TypeTreeNode> typeTree, int level = 0)
        {
            var typeTreeNode = new TypeTreeNode();

            typeTree.Add(typeTreeNode);
            typeTreeNode.m_Level    = level;
            typeTreeNode.m_Type     = reader.ReadStringToNull();
            typeTreeNode.m_Name     = reader.ReadStringToNull();
            typeTreeNode.m_ByteSize = reader.ReadInt32();
            if (header.m_Version == 2)
            {
                var variableCount = reader.ReadInt32();
            }
            if (header.m_Version != 3)
            {
                typeTreeNode.m_Index = reader.ReadInt32();
            }
            typeTreeNode.m_IsArray = reader.ReadInt32();
            typeTreeNode.m_Version = reader.ReadInt32();
            if (header.m_Version != 3)
            {
                typeTreeNode.m_MetaFlag = reader.ReadInt32();
            }

            int childrenCount = reader.ReadInt32();

            for (int i = 0; i < childrenCount; i++)
            {
                ReadTypeTree(typeTree, level + 1);
            }
        }
Example #2
0
 private void ReadHeader(AssetReader reader)
 {
     m_Header.version                    = reader.ReadUInt32();
     m_Header.unityVersion               = reader.ReadStringToNull();
     m_Header.unityRevision              = reader.ReadStringToNull();
     m_Header.size                       = reader.ReadInt64();
     m_Header.compressedBlocksInfoSize   = reader.ReadUInt32();
     m_Header.uncompressedBlocksInfoSize = reader.ReadUInt32();
     m_Header.flags                      = reader.ReadUInt32();
 }
Example #3
0
        public BundleFile(AssetReader reader, string path)
        {
            m_Header           = new Header();
            m_Header.signature = reader.ReadStringToNull();
            switch (m_Header.signature)
            {
            case "UnityArchive":
                break;     //TODO

            case "UnityWeb":
            case "UnityRaw":
                ReadHeaderAndBlocksInfo(reader);
                using (var blocksStream = CreateBlocksStream(path))
                {
                    ReadBlocksAndDirectory(reader, blocksStream);
                    ReadFiles(blocksStream, path);
                }
                break;

            case "UnityFS":
                ReadHeader(reader);
                ReadBlocksInfoAndDirectory(reader);
                using (var blocksStream = CreateBlocksStream(path))
                {
                    ReadBlocks(reader, blocksStream);
                    ReadFiles(blocksStream, path);
                }
                break;
            }
        }
Example #4
0
        private void ReadBlocksAndDirectory(AssetReader reader, Stream blocksStream)
        {
            foreach (var blockInfo in m_BlocksInfo)
            {
                var uncompressedBytes = reader.ReadBytes((int)blockInfo.compressedSize);
                if (blockInfo.flags == 1)
                {
                    using (var memoryStream = new MemoryStream(uncompressedBytes))
                    {
                        using (var decompressStream = SevenZipHelper.StreamDecompress(memoryStream))
                        {
                            uncompressedBytes = decompressStream.ToArray();
                        }
                    }
                }
                blocksStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
            }
            blocksStream.Position = 0;
            var blocksReader = new AssetReader(blocksStream);
            var nodesCount   = blocksReader.ReadInt32();

            m_DirectoryInfo = new Node[nodesCount];
            for (int i = 0; i < nodesCount; i++)
            {
                m_DirectoryInfo[i] = new Node
                {
                    path   = blocksReader.ReadStringToNull(),
                    offset = blocksReader.ReadUInt32(),
                    size   = blocksReader.ReadUInt32()
                };
            }
        }
Example #5
0
        private void ReadHeaderAndBlocksInfo(AssetReader reader)
        {
            var isCompressed = m_Header.signature == "UnityWeb";

            m_Header.version       = reader.ReadUInt32();
            m_Header.unityVersion  = reader.ReadStringToNull();
            m_Header.unityRevision = reader.ReadStringToNull();
            if (m_Header.version >= 4)
            {
                var hash = reader.ReadBytes(16);
                var crc  = reader.ReadUInt32();
            }
            var minimumStreamedBytes = reader.ReadUInt32();
            var headerSize           = reader.ReadUInt32();
            var numberOfLevelsToDownloadBeforeStreaming = reader.ReadUInt32();
            var levelCount = reader.ReadInt32();

            m_BlocksInfo = new StorageBlock[1];
            for (int i = 0; i < levelCount; i++)
            {
                var storageBlock = new StorageBlock()
                {
                    compressedSize   = reader.ReadUInt32(),
                    uncompressedSize = reader.ReadUInt32(),
                    flags            = (ushort)(isCompressed ? 1 : 0)
                };
                if (i == levelCount - 1)
                {
                    m_BlocksInfo[0] = storageBlock;
                }
            }
            if (m_Header.version >= 2)
            {
                var completeFileSize = reader.ReadUInt32();
            }
            if (m_Header.version >= 3)
            {
                var fileInfoHeaderSize = reader.ReadUInt32();
            }
            reader.Position = headerSize;
        }
Example #6
0
        private static FileType CheckFileType(AssetReader reader)
        {
            reader.Position = 0;
            var signature = reader.ReadStringToNull(20);

            reader.Position = 0;
            switch (signature)
            {
            case "UnityWeb":
            case "UnityRaw":
            case "UnityArchive":
            case "UnityFS":
                return(FileType.BundleFile);

            case "UnityWebData1.0":
                return(FileType.WebFile);

            default:
            {
                var magic = reader.ReadBytes(2);
                reader.Position = 0;
                if (WebFile.gzipMagic.SequenceEqual(magic))
                {
                    return(FileType.WebFile);
                }
                reader.Position = 0x20;
                magic           = reader.ReadBytes(6);
                reader.Position = 0;
                if (WebFile.brotliMagic.SequenceEqual(magic))
                {
                    return(FileType.WebFile);
                }
                if (SerializedFile.IsSerializedFile(reader))
                {
                    return(FileType.AssetsFile);
                }
                else
                {
                    return(FileType.ResourceFile);
                }
            }
            }
        }
Example #7
0
        private void ReadBlocksInfoAndDirectory(AssetReader reader)
        {
            byte[] blocksInfoBytes;
            if ((m_Header.flags & 0x80) != 0) //kArchiveBlocksInfoAtTheEnd
            {
                var position = reader.Position;
                reader.Position = reader.BaseStream.Length - m_Header.compressedBlocksInfoSize;
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
                reader.Position = position;
            }
            else //0x40 kArchiveBlocksAndDirectoryInfoCombined
            {
                if (m_Header.version >= 7)
                {
                    reader.AlignStream(16);
                }
                blocksInfoBytes = reader.ReadBytes((int)m_Header.compressedBlocksInfoSize);
            }
            var          blocksInfoCompressedStream = new MemoryStream(blocksInfoBytes);
            MemoryStream blocksInfoUncompresseddStream;

            switch (m_Header.flags & 0x3F) //kArchiveCompressionTypeMask
            {
            default:                       //None
            {
                blocksInfoUncompresseddStream = blocksInfoCompressedStream;
                break;
            }

            case 1:     //LZMA
            {
                blocksInfoUncompresseddStream = SevenZipHelper.StreamDecompress(blocksInfoCompressedStream);
                blocksInfoCompressedStream.Close();
                break;
            }

            case 2:     //LZ4
            case 3:     //LZ4HC
            {
                var uncompressedBytes = new byte[m_Header.uncompressedBlocksInfoSize];
                using (var decoder = new Lz4DecoderStream(blocksInfoCompressedStream))
                {
                    decoder.Read(uncompressedBytes, 0, uncompressedBytes.Length);
                }
                blocksInfoUncompresseddStream = new MemoryStream(uncompressedBytes);
                break;
            }
            }
            using (var blocksInfoReader = new AssetReader(blocksInfoUncompresseddStream))
            {
                var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
                var blocksInfoCount      = blocksInfoReader.ReadInt32();
                m_BlocksInfo = new StorageBlock[blocksInfoCount];
                for (int i = 0; i < blocksInfoCount; i++)
                {
                    m_BlocksInfo[i] = new StorageBlock
                    {
                        uncompressedSize = blocksInfoReader.ReadUInt32(),
                        compressedSize   = blocksInfoReader.ReadUInt32(),
                        flags            = blocksInfoReader.ReadUInt16()
                    };
                }

                var nodesCount = blocksInfoReader.ReadInt32();
                m_DirectoryInfo = new Node[nodesCount];
                for (int i = 0; i < nodesCount; i++)
                {
                    m_DirectoryInfo[i] = new Node
                    {
                        offset = blocksInfoReader.ReadInt64(),
                        size   = blocksInfoReader.ReadInt64(),
                        flags  = blocksInfoReader.ReadUInt32(),
                        path   = blocksInfoReader.ReadStringToNull(),
                    };
                }
            }
        }
        public SerializedFile(AssetsManager assetsManager, string fullName, AssetReader reader)
        {
            this.assetsManager = assetsManager;
            this.reader        = reader;
            this.fullName      = fullName;
            fileName           = Path.GetFileName(fullName);

            //ReadHeader
            header = new SerializedFileHeader();
            header.m_MetadataSize = reader.ReadUInt32();
            header.m_FileSize     = reader.ReadUInt32();
            header.m_Version      = reader.ReadUInt32();
            header.m_DataOffset   = reader.ReadUInt32();

            if (header.m_Version >= 9)
            {
                header.m_Endianess = reader.ReadByte();
                header.m_Reserved  = reader.ReadBytes(3);
                m_FileEndianess    = (EndianType)header.m_Endianess;
            }
            else
            {
                reader.Position = header.m_FileSize - header.m_MetadataSize;
                m_FileEndianess = (EndianType)reader.ReadByte();
            }

            if (header.m_Version >= 22)
            {
                header.m_MetadataSize = reader.ReadUInt32();
                header.m_FileSize     = reader.ReadInt64();
                header.m_DataOffset   = reader.ReadInt64();
                reader.ReadInt64(); // unknown
            }

            //ReadMetadata
            if (m_FileEndianess == EndianType.LittleEndian)
            {
                reader.endian = EndianType.LittleEndian;
            }
            if (header.m_Version >= 7)
            {
                unityVersion = reader.ReadStringToNull();
                SetVersion(unityVersion);
            }
            if (header.m_Version >= 8)
            {
                m_TargetPlatform = (BuildTarget)reader.ReadInt32();
                if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
                {
                    m_TargetPlatform = BuildTarget.UnknownPlatform;
                }
            }
            if (header.m_Version >= 13)
            {
                m_EnableTypeTree = reader.ReadBoolean();
            }

            //ReadTypes
            int typeCount = reader.ReadInt32();

            m_Types = new List <SerializedType>(typeCount);
            for (int i = 0; i < typeCount; i++)
            {
                m_Types.Add(ReadSerializedType());
            }

            var bigIDEnabled = 0;

            if (header.m_Version >= 7 && header.m_Version < 14)
            {
                bigIDEnabled = reader.ReadInt32();
            }

            //ReadObjects
            int objectCount = reader.ReadInt32();

            m_Objects  = new List <ObjectInfo>(objectCount);
            Objects    = new List <Object>(objectCount);
            ObjectsDic = new Dictionary <long, Object>(objectCount);
            for (int i = 0; i < objectCount; i++)
            {
                var objectInfo = new ObjectInfo();
                if (bigIDEnabled != 0)
                {
                    objectInfo.m_PathID = reader.ReadInt64();
                }
                else if (header.m_Version < 14)
                {
                    objectInfo.m_PathID = reader.ReadInt32();
                }
                else
                {
                    reader.AlignStream();
                    objectInfo.m_PathID = reader.ReadInt64();
                }

                if (header.m_Version >= 22)
                {
                    objectInfo.byteStart = reader.ReadInt64();
                }
                else
                {
                    objectInfo.byteStart = reader.ReadUInt32();
                }

                objectInfo.byteStart += header.m_DataOffset;
                objectInfo.byteSize   = reader.ReadUInt32();
                objectInfo.typeID     = reader.ReadInt32();
                if (header.m_Version < 16)
                {
                    objectInfo.classID        = reader.ReadUInt16();
                    objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
                }
                else
                {
                    var type = m_Types[objectInfo.typeID];
                    objectInfo.serializedType = type;
                    objectInfo.classID        = type.classID;
                }
                if (header.m_Version < 11)
                {
                    var isDestroyed = reader.ReadUInt16();
                }
                if (header.m_Version >= 11 && header.m_Version < 17)
                {
                    var m_ScriptTypeIndex = reader.ReadInt16();
                    if (objectInfo.serializedType != null)
                    {
                        objectInfo.serializedType.m_ScriptTypeIndex = m_ScriptTypeIndex;
                    }
                }
                if (header.m_Version == 15 || header.m_Version == 16)
                {
                    var stripped = reader.ReadByte();
                }
                m_Objects.Add(objectInfo);
            }

            if (header.m_Version >= 11)
            {
                int scriptCount = reader.ReadInt32();
                m_ScriptTypes = new List <LocalSerializedObjectIdentifier>(scriptCount);
                for (int i = 0; i < scriptCount; i++)
                {
                    var m_ScriptType = new LocalSerializedObjectIdentifier();
                    m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
                    if (header.m_Version < 14)
                    {
                        m_ScriptType.localIdentifierInFile = reader.ReadInt32();
                    }
                    else
                    {
                        reader.AlignStream();
                        m_ScriptType.localIdentifierInFile = reader.ReadInt64();
                    }
                    m_ScriptTypes.Add(m_ScriptType);
                }
            }

            int externalsCount = reader.ReadInt32();

            m_Externals = new List <FileIdentifier>(externalsCount);
            for (int i = 0; i < externalsCount; i++)
            {
                var m_External = new FileIdentifier();
                if (header.m_Version >= 6)
                {
                    var tempEmpty = reader.ReadStringToNull();
                }
                if (header.m_Version >= 5)
                {
                    m_External.guid = new Guid(reader.ReadBytes(16));
                    m_External.type = reader.ReadInt32();
                }
                m_External.pathName = reader.ReadStringToNull();
                m_External.fileName = Path.GetFileName(m_External.pathName);
                m_Externals.Add(m_External);
            }

            if (header.m_Version >= 20)
            {
                int refTypesCount = reader.ReadInt32();
                m_RefTypes = new List <SerializedType>(refTypesCount);
                for (int i = 0; i < refTypesCount; i++)
                {
                    m_RefTypes.Add(ReadSerializedType());
                }
            }

            if (header.m_Version >= 5)
            {
                var userInformation = reader.ReadStringToNull();
            }

            //reader.AlignStream(16);
        }