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)); }
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); } }
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); } } }
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; } } }
internal ObjectPointer(Asset source, TypeTree typeTree) { this.TypeTree = TypeTree; this.Source = source; }
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); }