Пример #1
0
        internal EngineObject CreateEngineObject(TypeTree typeTree, Dictionary <string, object> dict)
        {
            foreach (var creator in this.engineObjectCreators)
            {
                var obj = creator.CreateEngineObject(typeTree, dict);
                if (obj != null)
                {
                    return(obj);
                }
            }

            return(new EngineObject(typeTree, dict));
        }
Пример #2
0
        public EngineObject CreateEngineObject(TypeTree typeTree, Dictionary <string, object> dict)
        {
            switch (typeTree.Type)
            {
            case "TextAsset":
                return(new TextAsset(typeTree, dict));

            case "GameObject":
                return(new GameObject(typeTree, dict));

            case "Transform":
                return(new Transform(typeTree, dict));

            default:
                return(null);
            }
        }
Пример #3
0
        private void LoadBlob(BinaryReader reader)
        {
            var bigendian = this.TypeMetadata.Asset.bigendian;
            var numNodes = reader.ReadInt32(bigendian);
            var bufferBytes = reader.ReadInt32(bigendian);
            var nodeData = reader.ReadBytes(24 * (int)numNodes);
            this.data = reader.ReadBytes(bufferBytes);

            var parents = new Stack<TypeTree>();
            parents.Push(this);
            using (var nodeReader = new BinaryReader(new MemoryStream(nodeData)))
            {
                for (var i = 0; i < numNodes; i++)
                {
                    var version = nodeReader.ReadInt16(bigendian);
                    var depth = nodeReader.ReadByte();
                    TypeTree current;

                    if (depth == 0)
                    {
                        current = this;
                    }
                    else
                    {
                        while (parents.Count > depth)
                        {
                            parents.Pop();
                        }

                        current = new TypeTree(this.TypeMetadata);
                        parents.Peek().children.Add(current);
                        parents.Push(current);
                    }

                    current.Version = version;
                    current.IsArray = nodeReader.ReadByte() != 0;
                    current.Type = GetString(nodeReader.ReadInt32(bigendian));
                    current.Name = GetString(nodeReader.ReadInt32(bigendian));
                    current.Size = nodeReader.ReadInt32(bigendian);
                    current.Index = nodeReader.ReadInt32(bigendian);
                    current.Flags = nodeReader.ReadInt32(bigendian);
                }
            }
        }
Пример #4
0
        internal void Load(BinaryReader reader)
        {
            var bigendian = this.Asset.bigendian;
            var format    = this.Asset.Format;

            this.GeneratorVersion = reader.ReadCString();
            this.TargetPlatform   = reader.ReadUInt32(bigendian);


            if (format >= 13)
            {
                var hasTypeTree = reader.ReadBoolean();
                var numTypes    = reader.ReadInt32(bigendian);
                this.classIds = new List <int>(numTypes);
                this.hashDict = new Dictionary <int, byte[]>(numTypes);
                if (hasTypeTree)
                {
                    this.typeTreeDict = new Dictionary <int, TypeTree>(numTypes);
                }

                for (var i = 0; i < numTypes; i++)
                {
                    var classId = reader.ReadInt32(bigendian);
                    if (format >= 17)
                    {
                        reader.ReadByte();  // unknown
                        var scriptId = reader.ReadInt16(bigendian);

                        if (classId == 114)
                        {
                            if (scriptId >= 0)
                            {
                                classId = -1 - scriptId;
                            }
                            else
                            {
                                classId = -1;
                            }
                        }
                    }

                    this.classIds.Add(classId);
                    byte[] hash;
                    if (classId < 0)
                    {
                        hash = reader.ReadBytes(0x20);
                    }
                    else
                    {
                        hash = reader.ReadBytes(0x10);
                    }
                    this.hashDict[classId] = hash;

                    if (hasTypeTree)
                    {
                        var tree = new TypeTree(this);
                        tree.Load(reader);
                        this.typeTreeDict[classId] = tree;
                    }
                }
            }
            else
            {
                this.typeTreeDict = new Dictionary <int, TypeTree>();
                var numFields = reader.ReadInt32(bigendian);
                for (var i = 0; i < numFields; i++)
                {
                    var classId = reader.ReadInt32(bigendian);
                    var tree    = new TypeTree(this);
                    tree.Load(reader);
                    this.typeTreeDict[classId] = tree;
                }
            }
        }
Пример #5
0
 internal ObjectPointer(Asset source, TypeTree typeTree)
 {
     this.TypeTree = TypeTree;
     this.Source   = source;
 }
Пример #6
0
        private object ReadValue(TypeTree typeTree, BinaryReader reader)
        {
            var    beforePos = reader.BaseStream.Position;
            object result    = null;
            var    needAlign = false;
            var    typeName  = typeTree.Type;
            var    bigendian = this.Asset.bigendian;

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

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

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

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

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

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

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

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

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

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

            case "string":
            {
                var size = reader.ReadInt32(bigendian);
                result    = reader.ReadBytes(size);
                needAlign = typeTree.Children[0].PostAlign;
            }
            break;

            default:
            {
                var firstChild = typeTree.IsArray ? typeTree : typeTree.Children[0];

                if (typeName.StartsWith("PPtr<"))
                {
                    var ptr = new ObjectPointer(this.Asset, typeTree);
                    ptr.Load(reader);
                    result = ptr;
                }
                else if (firstChild != null && firstChild.IsArray)
                {
                    needAlign = firstChild.IsArray;
                    var size      = Math.Max(reader.ReadInt32(bigendian), 0);
                    var arrayType = firstChild.Children[1];
                    if (arrayType.Type == "char" || arrayType.Type == "UInt8")
                    {
                        result = reader.ReadBytes(size).OfType <object>().ToArray();
                    }
                    else
                    {
                        var array = new object[size];
                        for (var i = 0; i < size; i++)
                        {
                            array[i] = ReadValue(arrayType, reader);
                        }
                        result = array;
                    }
                }
                else if (typeName == "pair")
                {
                    var first  = ReadValue(typeTree.Children[0], reader);
                    var second = ReadValue(typeTree.Children[1], reader);
                    result = new KeyValuePair <object, object>(first, second);
                }
                else
                {
                    var dict = new Dictionary <string, object>(typeTree.Children.Count);
                    foreach (var child in typeTree.Children)
                    {
                        dict[child.Name] = ReadValue(child, reader);
                    }

                    result = this.Asset.Bundle.Environment.CreateEngineObject(typeTree, dict);
                }
            }
            break;
            }

            var afterPos   = reader.BaseStream.Position;
            var actualSize = afterPos - beforePos;

            if (typeTree.Size > 0 && actualSize < typeTree.Size)
            {
                throw new NotSupportedException(string.Format("Expected ReadValue {0}, Actual {1}", typeTree.Size, actualSize));
            }

            if (needAlign || typeTree.PostAlign)
            {
                reader.Align(4);
            }

            return(result);
        }