private object ReadObject() { if (_reader.NodeType != JsonNodeType.Object) { throw new SerializationException("Failed to deserialize due to malformed json."); } _reader.Read(); if (_reader.NodeType != JsonNodeType.String || _reader.Name != ID_TYPE) { throw new SerializationException("Failed to deserialize due to malformed json: objects must contain a @type property."); } var tp = Type.GetType(_reader.Value as string); if (tp == null) { tp = TypeUtil.FindType(_reader.Value as string, true); } if (tp == null) { throw new SerializationException("Failed to deserialize due to malformed json: objects must contain a @type property."); } object result; ISerializationSurrogate surrogate; ISurrogateSelector selector; if (this.SurrogateSelector != null && (surrogate = this.SurrogateSelector.GetSurrogate(tp, this.Context, out selector)) != null) { var si = this.ReadAsSerializationInfo(tp); try { var obj = FormatterServices.GetUninitializedObject(tp); if (tp.FullName == "Serialization.PersistentObject") { // TODO: Remove this hack. Use tokens instead of trying to directly serialize PersistentObject--the descedant of MonoBehavior obj = PersistenceController.GetPrecreatedPersistentObject(new PersistentUid(si.GetString("uid"))); if (obj == null) { string linkedPrefabUid = si.GetString("linkedPrefabUid"); if (linkedPrefabUid != "") { PersistentObject prefab = PersistenceController.GetRegisteredPrefab(linkedPrefabUid); obj = GameObject.Instantiate(prefab); } } } result = surrogate.SetObjectData(obj, si, this.Context, selector); } catch (System.Exception ex) { throw new SerializationException("Failed to deserialize.", ex); } } else if (typeof(ISerializable).IsAssignableFrom(tp)) { var si = this.ReadAsSerializationInfo(tp); var constructor = GetSerializationConstructor(tp); if (constructor == null) { throw new SerializationException("Failed to deserialize due to ISerializable type '" + tp.FullName + "' not implementing the appropriate constructor."); } try { result = constructor.Invoke(new object[] { si, this.Context }); } catch (System.Exception ex) { throw new SerializationException("Failed to deserialize.", ex); } } else { var members = FormatterServices.GetSerializableMembers(tp, Context); var data = new object[members.Length]; while (_reader.Read()) { var weqw = _reader.NodeType; switch (_reader.NodeType) { case JsonNodeType.None: case JsonNodeType.EndArray: throw new SerializationException("Failed to deserialize due to malformed json."); case JsonNodeType.Object: { var nm = _reader.Name; int i = GetIndexOfMemberName(members, nm); if (i < 0) { this.ReadPastObject(); } else { data[i] = this.ReadObject(); } } break; case JsonNodeType.Array: { var nm = _reader.Name; int i = GetIndexOfMemberName(members, nm); if (i < 0) { this.ReadPastArray(); } else { _reader.Read(); if (_reader.NodeType != JsonNodeType.String) { throw new SerializationException("Failed to deserialize due to malformed json: array must begin with a @type string. (" + nm + ")"); } System.Type arrayType = null; try { var stp = _reader.Value as string; //bool isArray = (stp != null && stp.EndsWith("[]")); //if (isArray) stp = stp.Substring(0, stp.Length - 2); //arrayType = Type.GetType(stp); //if (arrayType == null) arrayType = TypeUtil.FindType(stp, true); //if (arrayType != null && isArray) arrayType = arrayType.MakeArrayType(); if (string.IsNullOrEmpty(stp)) { arrayType = null; } else if (stp.EndsWith("[]")) { stp = stp.Substring(0, stp.Length - 2); arrayType = Type.GetType(stp); if (arrayType == null) { arrayType = TypeUtil.FindType(stp, true); } if (arrayType != null) { arrayType = arrayType.MakeArrayType(); } } else if (stp.EndsWith("<>")) { stp = stp.Substring(0, stp.Length - 2); arrayType = Type.GetType(stp); if (arrayType == null) { arrayType = TypeUtil.FindType(stp, true); } if (arrayType != null) { arrayType = typeof(List <>).MakeGenericType(arrayType); } } } catch (System.Exception) { throw new SerializationException("Failed to deserialize due to malformed json: array must begin with a @type string. (" + nm + ")"); } if (arrayType == null) { throw new SerializationException("Failed to deserialize due to malformed json: array must begin with a @type string. (" + nm + ")"); } var innerType = arrayType.IsArray ? arrayType.GetElementType() : arrayType.GetGenericArguments()[0]; data[i] = this.ReadArray(nm, innerType, !arrayType.IsArray); } } break; case JsonNodeType.String: case JsonNodeType.Number: case JsonNodeType.Boolean: case JsonNodeType.Null: { int i = GetIndexOfMemberName(members, _reader.Name); if (i < 0) { this.ReadPastObject(); } else { data[i] = ConvertJsonValueToType(_reader.Value, (members[i] as System.Reflection.FieldInfo).FieldType); } } break; case JsonNodeType.EndObject: goto Result; } } Result: result = FormatterServices.GetUninitializedObject(tp); FormatterServices.PopulateObjectMembers(result, members, data); } if (result is IDeserializationCallback) { (result as IDeserializationCallback).OnDeserialization(this); } return(result); }