예제 #1
0
        internal virtual void Load(ArchiveBinaryReader reader)
        {
            var nodeCount           = reader.ReadInt32();
            var typeTableBufferSize = reader.ReadInt32();

            var nodeBuffer = reader.ReadBytes(24 * nodeCount);

            byte[] stringTable = reader.ReadBytes(typeTableBufferSize);

            using (var nodeReader = new ArchiveBinaryReader(new MemoryStream(nodeBuffer)))
            {
                var stack = new Stack <TypeNode>();
                stack.Push(this);

                this.Version = nodeReader.ReadUInt16();
                this.Depth   = nodeReader.ReadByte();
                this.IsArray = nodeReader.ReadBoolean();

                ushort position = nodeReader.ReadUInt16();
                ushort flag     = nodeReader.ReadUInt16();
                this.TypeName = flag == 0 ? stringTable.GetString(position) : baseStringTable.GetString(position);

                position       = nodeReader.ReadUInt16();
                flag           = nodeReader.ReadUInt16();
                this.FieldName = flag == 0 ? stringTable.GetString(position) : baseStringTable.GetString(position);

                this.Size  = nodeReader.ReadInt32();
                this.Index = nodeReader.ReadInt32();
                this.Flags = nodeReader.ReadInt32();

                for (var i = 1; i < nodeCount; i++)
                {
                    var current = new TypeNode(this);
                    current.Version = nodeReader.ReadUInt16();
                    current.Depth   = nodeReader.ReadByte();
                    current.IsArray = nodeReader.ReadBoolean();

                    position         = nodeReader.ReadUInt16();
                    flag             = nodeReader.ReadUInt16();
                    current.TypeName = flag == 0 ? stringTable.GetString(position) : baseStringTable.GetString(position);

                    position          = nodeReader.ReadUInt16();
                    flag              = nodeReader.ReadUInt16();
                    current.FieldName = flag == 0 ? stringTable.GetString(position) : baseStringTable.GetString(position);

                    current.Size  = nodeReader.ReadInt32();
                    current.Index = nodeReader.ReadInt32();
                    current.Flags = nodeReader.ReadInt32();

                    while (stack.Count > current.Depth)
                    {
                        stack.Pop();
                    }

                    stack.Peek().Children.Add(current);
                    stack.Push(current);
                }
            }
        }
예제 #2
0
        protected virtual void ReadArrayNode(TypeNode typeNode, int size, ArchiveBinaryReader reader, ObjectArchive archive, Stream output, FeatureInfo data)
        {
            if (size <= 0)
            {
                return;
            }

            Stream src = reader.BaseStream;

            switch (typeNode.TypeFlag)
            {
            case "bool":
            case "SInt8":
            case "char":
            case "UInt8":
            case "short":
            case "SInt16":
            case "unsigned short":
            case "UInt16":
            case "int":
            case "SInt32":
            case "unsigned int":
            case "UInt32":
            case "Type*":
            case "long long":
            case "SInt64":
            case "unsigned long long":
            case "UInt64":
            case "float":
            case "double":
            case "Quaternionf":
            case "float4":
            case "Vector4f":
            case "float3":
            case "Vector3f":
            case "float2":
            case "Vector2f":
            case "ColorRGBA":
            case "Matrix4x4f":
            case "Hash128":
            {
                this.CopyTo(src, output, typeNode.Size * size);
                break;
            }

            default:
            {
                for (int i = 0; i < size; i++)
                {
                    this.ReadNode(typeNode, reader, archive, output, data);
                }
                break;
            }
            }
        }
예제 #3
0
        public ObjectArchive(AssetBundleArchive bundle, string name, long fileStreamOffset, long fileStreamSize, ArchiveType type) : base(bundle, name, fileStreamOffset, fileStreamSize, type)
        {
            this.archiveRefs.Add(new ArchiveRef(0, this.Name, 0, new Hash128(new byte[16]), this.Name));
            this.extractor = new FeatureExtractor();

            using (Stream stream = this.GetDataStream())
            {
                using (ArchiveBinaryReader reader = new ArchiveBinaryReader(stream))
                {
                    this.Load(reader);
                }
            }
        }
예제 #4
0
        public FeatureInfo Extract(ObjectInfo info, ArchiveBinaryReader reader)
        {
            FeatureInfo data = new FeatureInfo();

            using (MemoryStream output = new MemoryStream())
            {
                this.ReadNode(info.TypeTree, reader, info.Archive, output, data);
                output.Seek(0, SeekOrigin.Begin);
                var hash = ArchiveUtil.Hash(output);
                data.PropertyHash = hash;
            }
            return(data);
        }
예제 #5
0
        public virtual object Create(ObjectInfo info)
        {
            if (info == null)
            {
                return(null);
            }

            lock (info)
            {
                using (var reader = new ArchiveBinaryReader(new MemoryStream(info.Data)))
                {
                    var typeTree = info.TypeTree;
                    var value    = Parse(typeTree, reader);
                    if (value is UnityDynamicObject)
                    {
                        UnityDynamicObject uo = value as UnityDynamicObject;
                        uo.ID         = info.ID;
                        uo.Size       = info.Size;
                        uo.ObjectInfo = info;
                    }
                    return(value);
                }
            }
        }
예제 #6
0
        public static AssetBundleArchive Load(Stream stream)
        {
            using (var reader = new ArchiveBinaryReader(stream))
            {
                var signature     = reader.ReadCString();
                var formatVersion = reader.ReadInt32(true);
                var mainVersion   = reader.ReadCString();
                var buildVersion  = reader.ReadCString();

                if (signature != SIGNATURE_FS && signature != SIGNATURE_WEB)
                {
                    throw new NotSupportedException("Not supported signature : " + signature);
                }

                if (formatVersion != 6)
                {
                    throw new NotSupportedException("Not supported format version : " + formatVersion);
                }

                AssetBundleArchive bundle = new AssetBundleArchive(formatVersion, mainVersion, buildVersion);
                bundle.FileSize = reader.ReadInt64(true);

                var compressedBlockSize   = reader.ReadInt32(true);
                var uncompressedBlockSize = reader.ReadInt32(true);
                var flags = reader.ReadInt32(true);

                var compressionType = (CompressionType)(flags & 0x3f);

                byte[] buffer = null;
                if ((flags & 0x80) > 0)
                {
                    var currentPos = reader.BaseStream.Position;
                    reader.BaseStream.Seek(-compressedBlockSize, SeekOrigin.End);
                    buffer = reader.ReadBytes(compressedBlockSize);
                    reader.BaseStream.Seek(currentPos, SeekOrigin.Begin);
                }
                else
                {
                    buffer = reader.ReadBytes(compressedBlockSize);
                }

                switch (compressionType)
                {
                case CompressionType.NONE:
                    break;

                case CompressionType.LZ4:
                case CompressionType.LZ4HC:
                    buffer = LZ4.LZ4Codec.Decode(buffer, 0, compressedBlockSize, uncompressedBlockSize);
                    break;

                default:
                    throw new NotSupportedException("Not supported compression type : " + compressionType);
                }

                List <BlockInfo> blocks = new List <BlockInfo>();
                List <AssetInfo> assets = new List <AssetInfo>();
                using (var metaReader = new ArchiveBinaryReader(new MemoryStream(buffer)))
                {
                    bundle.GUID = metaReader.ReadHash128();

                    int blockCount = metaReader.ReadInt32(true);
                    for (int i = 0; i < blockCount; i++)
                    {
                        BlockInfo block;
                        block.uncompressedSize = metaReader.ReadUInt32(true);
                        block.compressedSize   = metaReader.ReadUInt32(true);
                        block.flag             = metaReader.ReadInt16(true);
                        blocks.Add(block);
                    }

                    var assetCount = metaReader.ReadInt32(true);
                    for (int i = 0; i < assetCount; i++)
                    {
                        AssetInfo asset;
                        asset.offset = metaReader.ReadInt64(true);
                        asset.size   = metaReader.ReadInt64(true);
                        asset.flag   = metaReader.ReadInt32(true);
                        var name = metaReader.ReadCString();
                        name       = string.IsNullOrEmpty(name) ? "" : name.ToLower();
                        asset.name = name;
                        assets.Add(asset);
                    }
                }

                var totalDataSize = blocks.Sum(b => b.uncompressedSize);

                var      dataFilename = string.Format("{0}/{1}", ArchiveUtil.GetTemporaryCachePath(), Guid.NewGuid().ToString());
                FileInfo file         = new FileInfo(dataFilename);
                if (!file.Directory.Exists)
                {
                    file.Directory.Create();
                }
                bundle.dataFilename = file.FullName;

                using (Stream dataStream = new FileStream(file.FullName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 8192))
                {
                    foreach (var block in blocks)
                    {
                        switch (block.CompressionType)
                        {
                        case CompressionType.NONE:
                        {
                            buffer = reader.ReadBytes((int)block.compressedSize);
                            dataStream.Write(buffer, 0, buffer.Length);
                            break;
                        }

                        case CompressionType.LZMA:
                        {
                            var properties = reader.ReadBytes(5);
                            var decoder    = new SevenZip.Compression.LZMA.Decoder();
                            decoder.SetDecoderProperties(properties);
                            decoder.Code(reader.BaseStream, dataStream, block.compressedSize - 5, block.uncompressedSize, null);
                            break;
                        }

                        case CompressionType.LZ4:
                        case CompressionType.LZ4HC:
                        {
                            buffer = reader.ReadBytes((int)block.compressedSize);
                            var data = LZ4.LZ4Codec.Decode(buffer, 0, (int)block.compressedSize, (int)block.uncompressedSize);
                            dataStream.Write(data, 0, data.Length);
                            break;
                        }

                        default:
                            throw new NotSupportedException("Not supported compression type : " + block.CompressionType);
                        }
                    }
                }
                foreach (var assetInfo in assets)
                {
                    switch (assetInfo.flag)
                    {
                    case 4:
                    {
                        ObjectArchive asset = new ObjectArchive(bundle, assetInfo.name, assetInfo.offset, assetInfo.size, assetInfo.Type);
                        bundle.AddAssetArchive(asset);
                        break;
                    }

                    default:
                    {
                        ResourceArchive asset = new ResourceArchive(bundle, assetInfo.name, assetInfo.offset, assetInfo.size, assetInfo.Type);
                        bundle.AddAssetArchive(asset);
                        break;
                    }
                    }

                    //switch (assetInfo.Type)
                    //{
                    //    case ArchiveType.CAB:
                    //    case ArchiveType.BUILD_PLAYER:
                    //    case ArchiveType.SHARED_DATA:
                    //        {
                    //            ObjectArchive asset = new ObjectArchive(bundle, assetInfo.name, assetInfo.offset, assetInfo.size, assetInfo.Type);
                    //            bundle.AddAssetArchive(asset);
                    //            break;
                    //        }
                    //    default:
                    //        {
                    //            ResourceArchive asset = new ResourceArchive(bundle, assetInfo.name, assetInfo.offset, assetInfo.size, assetInfo.Type);
                    //            bundle.AddAssetArchive(asset);
                    //            break;
                    //        }
                    //}
                }
                return(bundle);
            }
        }
예제 #7
0
        public object Parse(TypeNode typeNode, ArchiveBinaryReader reader)
        {
            object result = null;

            switch (typeNode.TypeFlag)
            {
            case "bool":
                result = reader.ReadBoolean();
                break;

            case "SInt8":
                result = reader.ReadSByte();
                break;

            case "char":
            case "UInt8":
                result = reader.ReadByte();
                break;

            case "short":
            case "SInt16":
                result = reader.ReadInt16();
                break;

            case "unsigned short":
            case "UInt16":
                result = reader.ReadUInt16();
                break;

            case "int":
            case "SInt32":
                result = reader.ReadInt32();
                break;

            case "unsigned int":
            case "UInt32":
            case "Type*":
                result = reader.ReadUInt32();
                break;

            case "long long":
            case "SInt64":
                result = reader.ReadInt64();
                break;

            case "unsigned long long":
            case "UInt64":
                result = reader.ReadUInt64();
                break;

            case "float":
                result = reader.ReadSingle();
                break;

            case "double":
                result = reader.ReadDouble();
                break;

            case "Quaternionf":
            {
                result = reader.ReadQuaternion();
                break;
            }

            case "float4":
            case "Vector4f":
            {
                result = reader.ReadVector4();
                break;
            }

            case "float3":
            case "Vector3f":
            {
                result = reader.ReadVector3();
                break;
            }

            case "float2":
            case "Vector2f":
            {
                result = reader.ReadVector2();
                break;
            }

            case "ColorRGBA":
            {
                if (typeNode.Version == 2)
                {
                    result = reader.ReadColor32();
                }
                else
                {
                    result = reader.ReadColor();
                }
                break;
            }

            case "Matrix4x4f":
            {
                result = reader.ReadMatrix4x4();
                break;
            }

            case "Hash128":
            {
                result = reader.ReadHash128();
                break;
            }

            case "string":
            {
                result = reader.ReadString();
                break;
            }

            case "vector":
            case "staticvector":
            case "set":
            {
                var valueTypeNode = typeNode.Children[0];
                result = this.Parse(valueTypeNode, reader);
                break;
            }

            case "map":
            {
                var pairTypeNode  = typeNode.Children[0].Children[1];
                var keyTypeNode   = pairTypeNode.Children[0];
                var valueTypeNode = pairTypeNode.Children[1];

                var size = reader.ReadInt32();
                Map map  = new Map(typeNode);
                for (int i = 0; i < size; i++)
                {
                    var key   = this.Parse(keyTypeNode, reader);
                    var value = this.Parse(valueTypeNode, reader);
                    map.Add(key, value);
                }
                result = map;
                break;
            }

            case "Array":
            {
                var valueTypeNode = typeNode.Children[1];
                var size          = reader.ReadInt32();
                result = this.ParseArray(valueTypeNode, size, reader);
                break;
            }

            case "PPtr":
            {
                var fileID = reader.ReadInt32();
                var pathID = reader.ReadInt64();
                result = new PPtr(fileID, pathID, typeNode.TypeName);
                break;
            }

            case "TypelessData":
            {
                var size = reader.ReadInt32();
                result = new TypelessData(reader.ReadBytes(size));
                break;
            }

            case "StreamedResource":
            {
                var source           = reader.ReadString();
                var offset           = reader.ReadUInt64();
                var size             = reader.ReadUInt64();
                var streamedResource = new StreamedResource(source, offset, size);
                result = streamedResource;
                break;
            }

            case "AssetBundle":
            {
                AssetBundle bundle = new AssetBundle(((TypeTree)typeNode).Archive);
                bundle.FullName = reader.ReadString();

                var         size         = reader.ReadInt32();
                List <PPtr> preloadTable = new List <PPtr>(size);
                for (int i = 0; i < size; i++)
                {
                    PPtr pptr = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>");
                    preloadTable.Add(pptr);
                }

                bundle.Preloads.AddRange(preloadTable);

                size = reader.ReadInt32();
                List <AssetPair> container = new List <AssetPair>(size);
                for (int i = 0; i < size; i++)
                {
                    var first        = reader.ReadString();
                    var preloadIndex = reader.ReadInt32();
                    var preloadSize  = reader.ReadInt32();
                    var pptr         = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>");
                    var pair         = new AssetPair(first, new Objects.AssetInfo(preloadIndex, preloadSize, pptr));
                    container.Add(pair);
                }
                bundle.Container.AddRange(container);

                bundle.MainAsset = new Objects.AssetInfo(reader.ReadInt32(), reader.ReadInt32(), new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>"));

                bundle.RuntimeCompatibility = reader.ReadUInt32();
                bundle.Name = reader.ReadString();

                size = reader.ReadInt32();
                List <string> dependencies = new List <string>(size);
                for (int i = 0; i < size; i++)
                {
                    dependencies.Add(reader.ReadString());
                }
                bundle.Dependencies.AddRange(dependencies);

                bundle.IsStreamed = reader.ReadBoolean();
                result            = bundle;
                break;
            }

            case "PreloadData":
            {
                PreloadData preloadData = new PreloadData(((TypeTree)typeNode).Archive);

                preloadData.Name = reader.ReadString();

                var         size         = reader.ReadInt32();
                List <PPtr> preloadTable = new List <PPtr>(size);
                for (int i = 0; i < size; i++)
                {
                    PPtr pptr = new PPtr(reader.ReadInt32(), reader.ReadInt64(), "PPtr<Object>");
                    preloadTable.Add(pptr);
                }

                preloadData.Preloads.AddRange(preloadTable);

                size = reader.ReadInt32();
                List <string> dependencies = new List <string>(size);
                for (int i = 0; i < size; i++)
                {
                    dependencies.Add(reader.ReadString());
                }
                preloadData.Dependencies.AddRange(dependencies);
                result = preloadData;
                break;
            }

            case "AssetBundleManifest":
            {
                Objects.AssetBundleManifest obj = new Objects.AssetBundleManifest((TypeTree)typeNode);
                foreach (TypeNode childNode in typeNode.Children)
                {
                    var key        = childNode.FieldName;
                    var childValue = this.Parse(childNode, reader);
                    obj[key] = childValue;
                }
                result = obj;
                break;
            }

            default:
            {
                DynamicObject obj = typeNode is TypeTree ? new UnityDynamicObject((TypeTree)typeNode) : new DynamicObject(typeNode);
                foreach (TypeNode childNode in typeNode.Children)
                {
                    var key        = childNode.FieldName;
                    var childValue = this.Parse(childNode, reader);
                    obj[key] = childValue;
                }
                result = obj;
                break;
            }
            }

            if (typeNode.IsAlign)
            {
                reader.Align(4);
            }

            return(result);
        }
예제 #8
0
        protected virtual IList ParseArray(TypeNode typeNode, int size, ArchiveBinaryReader reader)
        {
            switch (typeNode.TypeFlag)
            {
            case "bool":
            {
                bool[] result = new bool[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadBoolean();
                    if (typeNode.IsAlign)
                    {
                        reader.Align(4);
                    }
                }
                return(result);
            }

            case "SInt8":
            {
                sbyte[] result = new sbyte[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadSByte();
                }
                return(result);
            }

            case "char":
            case "UInt8":
            {
                if (size <= 0)
                {
                    return(new byte[0]);
                }

                return(reader.ReadBytes(size));
            }

            case "short":
            case "SInt16":
            {
                short[] result = new short[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadInt16();
                }
                return(result);
            }

            case "unsigned short":
            case "UInt16":
            {
                ushort[] result = new ushort[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadUInt16();
                }
                return(result);
            }

            case "int":
            case "SInt32":
            {
                int[] result = new int[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadInt32();
                }
                return(result);
            }

            case "unsigned int":
            case "UInt32":
            case "Type*":
            {
                uint[] result = new uint[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadUInt32();
                }
                return(result);
            }

            case "long long":
            case "SInt64":
            {
                long[] result = new long[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadInt64();
                }
                return(result);
            }

            case "unsigned long long":
            case "UInt64":
            {
                ulong[] result = new ulong[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadUInt64();
                }
                return(result);
            }

            case "float":
            {
                float[] result = new float[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadSingle();
                }
                return(result);
            }

            case "double":
            {
                double[] result = new double[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadDouble();
                }
                return(result);
            }

            case "Quaternionf":
            {
                Quaternion[] result = new Quaternion[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadQuaternion();
                }
                return(result);
            }

            case "float4":
            case "Vector4f":
            {
                Vector4[] result = new Vector4[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadVector4();
                }
                return(result);
            }

            case "float3":
            case "Vector3f":
            {
                Vector3[] result = new Vector3[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadVector3();
                }
                return(result);
            }

            case "float2":
            case "Vector2f":
            {
                Vector2[] result = new Vector2[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadVector2();
                }
                return(result);
            }

            case "ColorRGBA":
            {
                Color[] result = new Color[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadColor();
                }
                return(result);
            }

            case "Matrix4x4f":
            {
                Matrix4x4[] result = new Matrix4x4[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadMatrix4x4();
                }
                return(result);
            }

            case "Hash128":
            {
                Hash128[] result = new Hash128[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadHash128();
                }
                return(result);
            }

            case "string":
            {
                string[] result = new string[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = reader.ReadString();
                }
                return(result);
            }

            default:
            {
                object[] result = new object[size];
                for (int i = 0; i < size; i++)
                {
                    result[i] = this.Parse(typeNode, reader);
                }
                return(result);
            }
            }
        }
예제 #9
0
        protected virtual void Load(ArchiveBinaryReader reader)
        {
            try
            {
                long startPos   = reader.BaseStream.Position;
                int  headerSize = reader.ReadInt32(true);
                var  fileSize   = reader.ReadInt32(true);
                this.Format          = reader.ReadInt32(true);
                this.assetDataOffset = reader.ReadUInt32(true);

                if (this.Format < 17)
                {
                    throw new NotSupportedException(string.Format("The AssetBundle's format not supported,format:{0}", this.Format));
                }

                bool bigEndian = reader.ReadBoolean();
                reader.IsBigEndian = bigEndian;
                reader.ReadBytes(3);
                this.Version        = reader.ReadCString();
                this.TargetPlatform = reader.ReadUInt32();

                //读取类型树
                var hasTypeTree = reader.ReadBoolean();
                if (!hasTypeTree)
                {
                    throw new NotSupportedException("Missing type tree, not supported");
                }

                Hash128 zero          = new Hash128(new byte[16]);
                var     typeTreeCount = reader.ReadInt32();
                for (var i = 0; i < typeTreeCount; i++)
                {
                    var typeId = reader.ReadInt32();
                    reader.ReadByte();
                    var scriptIndex    = reader.ReadInt16();
                    var hash           = reader.ReadHash128();
                    var propertiesHash = typeId == 114 ? reader.ReadHash128() : zero;
                    var tree           = new TypeTree(this, i, Enum.IsDefined(typeof(TypeID), typeId) ? (TypeID)typeId : TypeID.UnknownType, scriptIndex, hash, propertiesHash);
                    tree.Load(reader);
                    this.trees.Add(tree);
                }

                //读取对象信息
                var objectCount = reader.ReadInt32();
                List <ObjectItem> objectItems = new List <ObjectItem>();
                for (var i = 0; i < objectCount; i++)
                {
                    reader.Align(4);
                    var id       = reader.ReadInt64();
                    var offset   = reader.ReadInt32();
                    var size     = reader.ReadInt32();
                    var index    = reader.ReadInt32();
                    var typeTree = trees[index];
                    var item     = new ObjectItem(id, offset, size, typeTree);
                    objectItems.Add(item);
                }

                //自定义脚本预载表
                var scriptCount = reader.ReadInt32();
                for (int i = 0; i < scriptCount; i++)
                {
                    var fileID = reader.ReadInt32();
                    var pathID = reader.ReadInt64();
                    var pptr   = new PPtr(fileID, pathID, "PPtr<MonoScript>");
                    this.preloadScripts.Add(pptr);
                }

                //读取共享对象
                int refCount = reader.ReadInt32();
                for (int i = 1; i <= refCount; i++)
                {
                    var name     = reader.ReadCString();
                    var guid     = reader.ReadHash128();
                    var type     = reader.ReadInt32();
                    var fileName = reader.ReadCString();
                    fileName = string.IsNullOrEmpty(fileName) ? "" : fileName.ToLower();
                    var assetRef = new ArchiveRef(i, name, type, guid, fileName);
                    this.archiveRefs.Add(assetRef);
                }

                foreach (var item in objectItems)
                {
                    TypeID typeId = item.TypeTree.TypeID;
                    if (typeId != TypeID.AssetBundle && typeId != TypeID.PreloadData)
                    {
                        continue;
                    }

                    ObjectInfo info = new ObjectInfo(this, item.ID, item.TypeTree, item.Offset, item.Size, false);
                    if (info.TypeID == TypeID.AssetBundle)
                    {
                        AssetBundle assetBundle = info.GetObject <AssetBundle>();
                        this.AssetBundle   = assetBundle;
                        Bundle.AssetBundle = assetBundle;
                    }
                    else if (info.TypeID == TypeID.PreloadData)
                    {
                        PreloadData preloadData = info.GetObject <PreloadData>();
                        this.PreloadData = preloadData;
                    }
                }

                foreach (var item in objectItems)
                {
                    TypeID typeId = item.TypeTree.TypeID;
                    if (typeId == TypeID.AssetBundle || typeId == TypeID.PreloadData)
                    {
                        continue;
                    }

                    bool       isPublic = !this.Bundle.IsStreamed && this.AssetBundle != null && this.AssetBundle.IsPublic(item.ID);
                    ObjectInfo info     = new ObjectInfo(this, item.ID, item.TypeTree, item.Offset, item.Size, isPublic);
                    this.objects.Add(info.ID, info);

                    if (info.IsPotentialRedundancy)
                    {
                        reader.BaseStream.Seek(this.assetDataOffset + item.Offset, SeekOrigin.Begin);
                        FeatureInfo featureInfo = this.extractor.Extract(info, reader);
                        info.Fingerprint = new PropertiesFingerprint(info, featureInfo.References, featureInfo.PropertyHash);
                        info.Name        = featureInfo.Name;
                        info.Resources   = featureInfo.Resources;
                    }
                    else
                    {
                        info.Fingerprint = new IdentifierFingerprint(info.ID, this.Name);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogErrorFormat("{0}", e);
            }
        }
예제 #10
0
        protected virtual void ReadNode(TypeNode typeNode, ArchiveBinaryReader reader, ObjectArchive archive, Stream output, FeatureInfo data)
        {
            Stream src = reader.BaseStream;

            switch (typeNode.TypeFlag)
            {
            case "bool":
            case "SInt8":
            case "char":
            case "UInt8":
            case "short":
            case "SInt16":
            case "unsigned short":
            case "UInt16":
            case "int":
            case "SInt32":
            case "unsigned int":
            case "UInt32":
            case "Type*":
            case "long long":
            case "SInt64":
            case "unsigned long long":
            case "UInt64":
            case "float":
            case "double":
            case "Quaternionf":
            case "float4":
            case "Vector4f":
            case "float3":
            case "Vector3f":
            case "float2":
            case "Vector2f":
            case "ColorRGBA":
            case "Matrix4x4f":
            case "Hash128":
            {
                this.CopyTo(src, output, typeNode.Size);
                break;
            }

            case "string":
            {
                if ((typeNode.Depth == 1 || (typeNode.Depth == 2 && typeNode.Root.TypeID == TypeID.Shader)) && typeNode.FieldName.Equals("m_Name"))
                {
                    var position = reader.BaseStream.Position;
                    data.Name = reader.ReadString();
                    reader.BaseStream.Position = position;
                }

                int size = reader.ReadInt32();
                if (size > 0)
                {
                    this.CopyTo(src, output, size);
                }
                reader.Align(4);
                break;
            }

            case "Array":
            {
                var valueTypeNode = typeNode.Children[1];
                var size          = reader.ReadInt32();
                if (size <= 0)
                {
                    break;
                }

                this.ReadArrayNode(valueTypeNode, size, reader, archive, output, data);
                break;
            }

            case "TypelessData":
            {
                var size = reader.ReadInt32();
                if (size > 0)
                {
                    this.CopyTo(src, output, size);
                }
                break;
            }

            case "PPtr":
            {
                var fileID = reader.ReadInt32();
                var pathID = reader.ReadInt64();
                var pptr   = new PPtr(fileID, pathID, typeNode.TypeName);
                data.Add(pptr);
                break;
            }

            case "StreamedResource":
            {
                var source           = reader.ReadString();
                var offset           = reader.ReadUInt64();
                var size             = reader.ReadUInt64();
                var streamedResource = new StreamedResource(source, offset, size);
                data.Resources = streamedResource;

                if (size <= 0)
                {
                    break;
                }

                using (Stream dataStream = archive.GetResourceStream(streamedResource))
                {
                    if (dataStream == null)
                    {
                        break;
                    }

                    byte[] buffer = ArchiveUtil.HashBytes(dataStream);
                    output.Write(buffer, 0, buffer.Length);
                }
                break;
            }

            default:
            {
                foreach (TypeNode childNode in typeNode.Children)
                {
                    ReadNode(childNode, reader, archive, output, data);
                }
                break;
            }
            }

            if (typeNode.IsAlign)
            {
                reader.Align(4);
            }
        }