예제 #1
0
        public List <IObjectInfo> GetReferences()
        {
            if (references != null)
            {
                return(references);
            }

            lock (_lock)
            {
                if (references != null)
                {
                    return(this.references);
                }

                this.references = new List <IObjectInfo>();

                ObjectArchive archive = (ObjectArchive)this.info.Archive;

                foreach (PPtr pptr in pptrs)
                {
                    this.references.Add(archive.GetObjectInfo(pptr));
                }
                return(references);
            }
        }
예제 #2
0
        public virtual IObjectInfo GetObjectInfo(PPtr pptr)
        {
            if (pptr.FileID == 0 && pptr.PathID == 0)
            {
                return(new NullObjectInfo(pptr.TypeID));
            }

            if (pptr.FileID == 0)
            {
                ObjectInfo info = null;
                if (objects.TryGetValue(pptr.PathID, out info))
                {
                    return(info);
                }

                return(new MissingObjectInfo(this, pptr.PathID, pptr.TypeID));
            }

            ArchiveRef    assetRef = this.archiveRefs[pptr.FileID];
            ObjectArchive asset    = this.Bundle.GetAssetArchive(assetRef.FileName) as ObjectArchive;

            if (asset != null)
            {
                return(asset.GetObjectInfo(pptr.PathID));
            }

            var container = this.Bundle.ArchiveContainer;

            if (container == null)
            {
                return(new MissingObjectInfo(null, pptr.PathID, pptr.TypeID));
            }

            return(container.GetObjectInfo(assetRef.FileName, pptr.PathID));
        }
예제 #3
0
 public TypeTree(ObjectArchive archive, int id, TypeID typeId, short scriptIndex, Hash128 hash, Hash128 propertiesHash) : base(null)
 {
     this.Root           = this;
     this.Archive        = archive;
     this.ID             = id;
     this.TypeID         = typeId;
     this.ScriptIndex    = scriptIndex;
     this.Hash           = hash;
     this.PropertiesHash = propertiesHash;
 }
예제 #4
0
        public ObjectInfo(ObjectArchive archive, long id, TypeTree tree, long offset, int size, bool isPublic) : base(archive)
        {
            this.ID       = id;
            this.IsPublic = isPublic;
            this.TypeTree = tree;

            this.dataSize   = size;
            this.dataOffset = offset;

            this.TypeID = this.TypeTree.TypeID;
            this.IsPotentialRedundancy = PotentialRedundancy();
        }
예제 #5
0
        public virtual IObjectInfo GetObjectInfo(string assetName, long pathId)
        {
            lock (_lock)
            {
                foreach (var builtinAsset in builtinArchives)
                {
                    if (!builtinAsset.Name.Equals(assetName))
                    {
                        continue;
                    }

                    return(builtinAsset.GetObjectInfo(pathId));
                }

                ObjectArchive asset = GetAssetArchive(assetName) as ObjectArchive;
                if (asset != null)
                {
                    return(asset.GetObjectInfo(pathId));
                }

                UnityEngine.Debug.LogWarningFormat("Object not found,AssetName:{0} ID:{1}", assetName, pathId);
                return(new MissingObjectInfo(null, pathId, TypeID.UnknownType));
            }
        }
예제 #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
        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);
            }
        }
예제 #8
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;
            }
            }
        }