The result of some sort of operation. A result is either successful or not, but if it is successful then there may be a set of warnings/messages associated with it. These warnings describe the performed error recovery operations.
        private static bool EmitFailWarning(fsResult result) {
            if (fiSettings.EmitWarnings && result.RawMessages.Any()) {
                Debug.LogWarning(result.FormattedMessages);
            }

            return result.Failed;
        }
Beispiel #2
0
        // Token: 0x06000527 RID: 1319 RVA: 0x0001F2D4 File Offset: 0x0001D4D4
        public sealed override fsResult TrySerialize(object instance, out fsData serialized, Type storageType)
        {
            Dictionary <string, fsData> dictionary = new Dictionary <string, fsData>();
            fsResult result = this.DoSerialize((TModel)((object)instance), dictionary);

            serialized = new fsData(dictionary);
            return(result);
        }
Beispiel #3
0
        private fsResult RunParse(out fsData data)
        {
            SkipSpace();

            if (HasValue() == false)
            {
                data = default;
                return(MakeFailure("Unexpected end of input"));
            }

            switch (Character())
            {
            case 'I':     // Infinity
            case 'N':     // NaN
            case '.':
            case '+':
            case '-':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9': return(TryParseNumber(out data));

            case '"':
            {
                string   str;
                fsResult fail = TryParseString(out str);
                if (fail.Failed)
                {
                    data = null;
                    return(fail);
                }

                data = new fsData(str);
                return(fsResult.Success);
            }

            case '[': return(TryParseArray(out data));

            case '{': return(TryParseObject(out data));

            case 't': return(TryParseTrue(out data));

            case 'f': return(TryParseFalse(out data));

            case 'n': return(TryParseNull(out data));

            default:
                data = null;
                return(MakeFailure("unable to parse; invalid token \"" + Character() + "\""));
            }
        }
Beispiel #4
0
        private fsResult InternalDeserialize_2_Version(Type overrideConverterType, fsData data, Type storageType,
                                                       ref object result, out List <fsObjectProcessor> processors)
        {
            if (IsVersioned(data))
            {
                // data is versioned, but we might not need to do a migration
                string version = data.AsDictionary[Key_Version].AsString;

                fsOption <fsVersionedType> versionedType = fsVersionManager.GetVersionedType(storageType);
                if (versionedType.HasValue &&
                    versionedType.Value.VersionString != version)
                {
                    // we have to do a migration
                    fsResult deserializeResult = fsResult.Success;

                    List <fsVersionedType> path;
                    deserializeResult += fsVersionManager.GetVersionImportPath(version, versionedType.Value, out path);
                    if (deserializeResult.Failed)
                    {
                        processors = GetProcessors(storageType);
                        return(deserializeResult);
                    }

                    // deserialize as the original type
                    deserializeResult += InternalDeserialize_3_Inheritance(overrideConverterType, data,
                                                                           path[0].ModelType, ref result, out processors);
                    if (deserializeResult.Failed)
                    {
                        return(deserializeResult);
                    }

                    // TODO: we probably should be invoking object processors all
                    //       along this pipeline
                    for (int i = 1; i < path.Count; ++i)
                    {
                        result = path[i].Migrate(result);
                    }

                    // Our data contained an object definition ($id) that was
                    // added to _references in step 4. However, in case we are
                    // doing versioning, it will contain the old version. To make
                    // sure future references to this object end up referencing
                    // the migrated version, we must update the reference.
                    if (IsObjectDefinition(data))
                    {
                        int sourceId = int.Parse(data.AsDictionary[Key_ObjectDefinition].AsString);
                        _references.AddReferenceWithId(sourceId, result);
                    }

                    processors = GetProcessors(deserializeResult.GetType());
                    return(deserializeResult);
                }
            }

            return(InternalDeserialize_3_Inheritance(overrideConverterType, data, storageType, ref result,
                                                     out processors));
        }
Beispiel #5
0
        private fsResult InternalSerialize_1_ProcessCycles(Type storageType, Type overrideConverterType,
                                                           object instance, out fsData data)
        {
            // We have an object definition to serialize.
            try
            {
                // Note that we enter the reference group at the beginning of serialization so that we support
                // references that are at equal serialization levels, not just nested serialization levels, within
                // the given subobject. A prime example is serialization a list of references.
                _references.Enter();

                // This type does not need cycle support.
                fsBaseConverter converter = GetConverter(instance.GetType(), overrideConverterType);
                if (converter.RequestCycleSupport(instance.GetType()) == false)
                {
                    return(InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data));
                }

                // We've already serialized this object instance (or it is pending higher up on the call stack).
                // Just serialize a reference to it to escape the cycle.
                //
                // note: We serialize the int as a string to so that we don't lose any information
                //       in a conversion to/from double.
                if (_references.IsReference(instance))
                {
                    data = fsData.CreateDictionary();
                    _lazyReferenceWriter.WriteReference(_references.GetReferenceId(instance), data.AsDictionary);
                    return(fsResult.Success);
                }

                // Mark inside the object graph that we've serialized the instance. We do this *before*
                // serialization so that if we get back into this function recursively, it'll already
                // be marked and we can handle the cycle properly without going into an infinite loop.
                _references.MarkSerialized(instance);

                // We've created the cycle metadata, so we can now serialize the actual object.
                // InternalSerialize will handle inheritance correctly for us.
                fsResult result =
                    InternalSerialize_2_Inheritance(storageType, overrideConverterType, instance, out data);
                if (result.Failed)
                {
                    return(result);
                }

                _lazyReferenceWriter.WriteDefinition(_references.GetReferenceId(instance), data);

                return(result);
            }
            finally
            {
                if (_references.Exit())
                {
                    _lazyReferenceWriter.Clear();
                }
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Parses an array
        /// </summary>
        private fsResult TryParseArray(out fsData arr)
        {
            if (Character() != '[')
            {
                arr = null;
                return(MakeFailure("Expected initial [ when parsing an array"));
            }

            // skip '['
            if (TryMoveNext() == false)
            {
                arr = null;
                return(MakeFailure("Unexpected end of input when parsing an array"));
            }

            SkipSpace();

            List <fsData> result = new List <fsData>();

            while (HasValue() && Character() != ']')
            {
                // parse the element
                fsData   element;
                fsResult fail = RunParse(out element);
                if (fail.Failed)
                {
                    arr = null;
                    return(fail);
                }

                result.Add(element);

                // parse the comma
                SkipSpace();
                if (HasValue() && Character() == ',')
                {
                    if (TryMoveNext() == false)
                    {
                        break;
                    }

                    SkipSpace();
                }
            }

            // skip the final ]
            if (HasValue() == false || Character() != ']' || TryMoveNext() == false)
            {
                arr = null;
                return(MakeFailure("No closing ] for array"));
            }

            arr = new fsData(result);
            return(fsResult.Success);
        }
Beispiel #7
0
        /// <summary>
        ///     Parses a string
        /// </summary>
        private fsResult TryParseString(out string str)
        {
            _cachedStringBuilder.Length = 0;

            // skip the first "
            if (Character() != '"' || TryMoveNext() == false)
            {
                str = string.Empty;
                return(MakeFailure("Expected initial \" when parsing a string"));
            }

            // read until the next "
            while (HasValue() && Character() != '\"')
            {
                char c = Character();

                // escape if necessary
                if (c == '\\')
                {
                    char     unescaped;
                    fsResult fail = TryUnescapeChar(out unescaped);
                    if (fail.Failed)
                    {
                        str = string.Empty;
                        return(fail);
                    }

                    _cachedStringBuilder.Append(unescaped);
                }

                // no escaping necessary
                else
                {
                    _cachedStringBuilder.Append(c);

                    // get the next character
                    if (TryMoveNext() == false)
                    {
                        str = string.Empty;
                        return(MakeFailure("Unexpected end of input when reading a string"));
                    }
                }
            }

            // skip the first "
            if (HasValue() == false || Character() != '"' || TryMoveNext() == false)
            {
                str = string.Empty;
                return(MakeFailure("No closing \" when parsing a string"));
            }

            str = _cachedStringBuilder.ToString();
            return(fsResult.Success);
        }
Beispiel #8
0
        protected fsResult SerializeMember <T>(Dictionary <string, fsData> data, Type overrideConverterType, string name, T value)
        {
            fsData   memberData;
            fsResult result = Serializer.TrySerialize(typeof(T), overrideConverterType, value, out memberData);

            if (result.Succeeded)
            {
                data[name] = memberData;
            }
            return(result);
        }
Beispiel #9
0
        /// <summary>
        /// Adds only the messages from the other result into this result,
        /// ignoring the success/failure status of the other result.
        /// </summary>
        public void AddMessages(fsResult result) {
            if (result._messages == null) {
                return;
            }

            if (_messages == null) {
                _messages = new List<string>();
            }

            _messages.AddRange(result._messages);
        }
Beispiel #10
0
        /// <summary>
        /// Adds only the messages from the other result into this result, ignoring
        /// the success/failure status of the other result.
        /// </summary>
        public void AddMessages(fsResult result) {
            if (result._messages == null) {
                return;
            }

            if (_messages == null) {
                _messages = new List<string>();
            }

            _messages.AddRange(result._messages);
        }
        /// <summary>
        ///     Generic wrapper around TryDeserialize that simply forwards the call.
        /// </summary>
        public fsResult TryDeserialize <T>(fsData data, ref T instance)
        {
            object   boxed = instance;
            fsResult fail  = TryDeserialize(data, typeof(T), ref boxed);

            if (fail.Succeeded)
            {
                instance = (T)boxed;
            }
            return(fail);
        }
Beispiel #12
0
        /// <summary>
        /// Merges the other result into this one. If the other result failed,
        /// then this one too will have failed.
        /// </summary>
        /// <remarks>
        /// Note that you can use += instead of this method so that you don't
        /// bury the actual method call that is generating the other fsResult.
        /// </remarks>
        public fsResult Merge(fsResult other) {
            // Copy success over
            _success = _success && other._success;

            // Copy messages over
            if (other._messages != null) {
                if (_messages == null) _messages = new List<string>(other._messages);
                else _messages.AddRange(other._messages);
            }

            return this;
        }
Beispiel #13
0
        /// <summary>
        /// Merges the other result into this one. If the other result failed, then
        /// this one too will have failed.
        /// </summary>
        /// <remarks>
        /// Note that you can use += instead of this method so that you don't bury
        /// the actual method call that is generating the other fsResult.
        /// </remarks>
        public fsResult Merge(fsResult other) {
            // Copy success over
            _success = _success && other._success;

            // Copy messages over
            if (other._messages != null) {
                if (_messages == null) _messages = new List<string>(other._messages);
                else _messages.AddRange(other._messages);
            }

            return this;
        }
Beispiel #14
0
        private fsResult TryParseNull(out fsData data)
        {
            fsResult fail = TryParseExact("null");

            if (fail.Succeeded)
            {
                data = new fsData();
                return(fsResult.Success);
            }

            data = null;
            return(fail);
        }
Beispiel #15
0
        private fsResult TryParseFalse(out fsData data)
        {
            fsResult fail = TryParseExact("false");

            if (fail.Succeeded)
            {
                data = new fsData(false);
                return(fsResult.Success);
            }

            data = null;
            return(fail);
        }
Beispiel #16
0
        // Token: 0x06000528 RID: 1320 RVA: 0x0001F300 File Offset: 0x0001D500
        public sealed override fsResult TryDeserialize(fsData data, ref object instance, Type storageType)
        {
            fsResult fsResult = fsResult.Success;
            fsResult fsResult2;

            fsResult = (fsResult2 = fsResult + base.CheckType(data, fsDataType.Object));
            if (fsResult2.Failed)
            {
                return(fsResult);
            }
            TModel tModel = (TModel)((object)instance);

            fsResult += this.DoDeserialize(data.AsDictionary, ref tModel);
            instance  = tModel;
            return(fsResult);
        }
Beispiel #17
0
        protected fsResult DeserializeMember <T>(Dictionary <string, fsData> data, Type overrideConverterType, string name, out T value)
        {
            fsData memberData;

            if (data.TryGetValue(name, out memberData) == false)
            {
                value = default(T);
                return(fsResult.Fail("Unable to find member \"" + name + "\""));
            }

            object   storage = null;
            fsResult result  = Serializer.TryDeserialize(memberData, typeof(T), overrideConverterType, ref storage);

            value = (T)storage;
            return(result);
        }
Beispiel #18
0
        /// <summary>
        /// Serializes the object into json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="prettyJson"></param>
        /// <returns></returns>
        public static string Serialize <T>(T value, bool prettyJson = false)
        {
            fsData   data;
            fsResult r = Internal.TrySerialize <T>(value, out data);

            if (r.Failed)
            {
                throw r.AsException;
            }

            if (!prettyJson)
            {
                return(fsJsonPrinter.CompressedJson(data));
            }

            return(fsJsonPrinter.PrettyJson(data));
        }
        /// <summary>
        ///     Serialize the given value.
        /// </summary>
        /// <param name="storageType">
        ///     The type of field/property that stores the object instance. This is
        ///     important particularly for inheritance, as a field storing an IInterface instance
        ///     should have type information included.
        /// </param>
        /// <param name="overrideConverterType">
        ///     An fsBaseConverter derived type that will be used to serialize
        ///     the object instead of the converter found via the normal discovery mechanisms.
        /// </param>
        /// <param name="instance">The actual object instance to serialize.</param>
        /// <param name="data">The serialized state of the object.</param>
        /// <returns>If serialization was successful.</returns>
        public fsResult TrySerialize(Type storageType, Type overrideConverterType, object instance, out fsData data)
        {
            List <fsObjectProcessor> processors = GetProcessors(instance == null ? storageType : instance.GetType());

            Invoke_OnBeforeSerialize(processors, storageType, instance);

            // We always serialize null directly as null
            if (ReferenceEquals(instance, null))
            {
                data = new fsData();
                Invoke_OnAfterSerialize(processors, storageType, instance, ref data);
                return(fsResult.Success);
            }

            fsResult result = InternalSerialize_1_ProcessCycles(storageType, overrideConverterType, instance, out data);

            Invoke_OnAfterSerialize(processors, storageType, instance, ref data);
            return(result);
        }
Beispiel #20
0
        /// <summary>
        /// Serializes the object into json
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="prettyJson"></param>
        /// <returns></returns>
        public static string Serialize <T>(T value, bool prettyJson = false)
        {
            fsData   data;
            fsResult r = Internal.TrySerialize <T>(value, out data);

            if (r.Failed)
            {
                throw r.AsException;
            }

            if (data.IsDictionary && data.AsDictionary.ContainsKey("$content"))
            {
                data = data.AsDictionary["$content"];
            }

            if (!prettyJson)
            {
                return(fsJsonPrinter.CompressedJson(data));
            }

            return(fsJsonPrinter.PrettyJson(data));
        }
Beispiel #21
0
        /// <summary>
        ///     Attempts to deserialize a value from a serialized state.
        /// </summary>
        public fsResult TryDeserialize(fsData data, Type storageType, Type overrideConverterType, ref object result)
        {
            if (data.IsNull)
            {
                result = null;
                List <fsObjectProcessor> processors = GetProcessors(storageType);
                Invoke_OnBeforeDeserialize(processors, storageType, ref data);
                Invoke_OnAfterDeserialize(processors, storageType, null);
                return(fsResult.Success);
            }

            // Convert legacy data into modern style data
            ConvertLegacyData(ref data);

            try
            {
                // We wrap the entire deserialize call in a reference group so
                // that we can properly deserialize a "parallel" set of
                // references, ie, a list of objects that are cyclic w.r.t. the
                // list
                _references.Enter();

                List <fsObjectProcessor> processors;
                fsResult r = InternalDeserialize_1_CycleReference(overrideConverterType, data, storageType, ref result,
                                                                  out processors);
                if (r.Succeeded)
                {
                    Invoke_OnAfterDeserialize(processors, storageType, result);
                }

                return(r);
            }
            finally
            {
                _references.Exit();
            }
        }
Beispiel #22
0
        private fsResult InternalSerialize_3_ProcessVersioning(Type overrideConverterType, object instance,
                                                               out fsData data)
        {
            // note: We do not have to take a Type parameter here, since at this
            //       point in the serialization algorithm inheritance has
            // *always* been handled. If we took a type parameter, it will
            // *always* be equal to instance.GetType(), so why bother taking the
            //  parameter?

            // Check to see if there is versioning information for this type. If
            // so, then we need to serialize it.
            fsOption <fsVersionedType> optionalVersionedType = fsVersionManager.GetVersionedType(instance.GetType());

            if (optionalVersionedType.HasValue)
            {
                fsVersionedType versionedType = optionalVersionedType.Value;

                // Serialize the actual object content; we'll just wrap it with
                // versioning metadata here.
                fsResult result = InternalSerialize_4_Converter(overrideConverterType, instance, out data);
                if (result.Failed)
                {
                    return(result);
                }

                // Add the versioning information
                EnsureDictionary(data);
                data.AsDictionary[Key_Version] = new fsData(versionedType.VersionString);

                return(result);
            }

            // This type has no versioning information -- directly serialize it
            // using the selected converter.
            return(InternalSerialize_4_Converter(overrideConverterType, instance, out data));
        }
        private fsResult InternalDeserialize_3_Inheritance(Type overrideConverterType, fsData data, Type storageType, ref object result,
                                                           out List <fsObjectProcessor> processors)
        {
            fsResult deserializeResult = fsResult.Success;

            Type objectType = storageType;

            // If the serialized state contains type information, then we need to make sure to update our
            // objectType and data to the proper values so that when we construct an object instance later
            // and run deserialization we run it on the proper type.
            if (IsTypeSpecified(data))
            {
                fsData typeNameData = data.AsDictionary[Key_InstanceType];

                // we wrap everything in a do while false loop so we can break out it
                do
                {
                    if (typeNameData.IsString == false)
                    {
                        deserializeResult.AddMessage(Key_InstanceType + " value must be a string (in " + data + ")");
                        break;
                    }

                    string typeName = typeNameData.AsString;
                    Type   type     = fsTypeCache.GetType(typeName);
                    if (type == null)
                    {
                        deserializeResult += fsResult.Fail("Unable to locate specified type \"" + typeName + "\"");
                        break;
                    }

                    if (storageType.IsAssignableFrom(type) == false)
                    {
                        deserializeResult.AddMessage("Ignoring type specifier; a field/property of type " + storageType + " cannot hold an instance of " + type);
                        break;
                    }

                    objectType = type;
                }while (false);
            }

            // We wait until here to actually Invoke_OnBeforeDeserialize because we do not
            // have the correct set of processors to invoke until *after* we have resolved
            // the proper type to use for deserialization.
            processors = GetProcessors(objectType);

            if (deserializeResult.Failed)
            {
                return(deserializeResult);
            }

            Invoke_OnBeforeDeserialize(processors, storageType, ref data);

            // Construct an object instance if we don't have one already. We also need to construct
            // an instance if the result type is of the wrong type, which may be the case when we
            // have a versioned import graph.
            if (ReferenceEquals(result, null) || result.GetType() != objectType)
            {
                result = GetConverter(objectType, overrideConverterType).CreateInstance(data, objectType);
            }

            // We call OnBeforeDeserializeAfterInstanceCreation here because we still want to invoke the
            // method even if the user passed in an existing instance.
            Invoke_OnBeforeDeserializeAfterInstanceCreation(processors, storageType, result, ref data);

            // NOTE: It is critically important that we pass the actual objectType down instead of
            //       using result.GetType() because it is not guaranteed that result.GetType()
            //       will equal objectType, especially because some converters are known to
            //       return dummy values for CreateInstance() (for example, the default behavior
            //       for structs is to just return the type of the struct).

            return(deserializeResult += InternalDeserialize_4_Cycles(overrideConverterType, data, objectType, ref result));
        }
    public void LoadLevel(string levelParams)
    {
        _player.Reset();

        FullSerializer.fsData   jsData = null;
        FullSerializer.fsResult res    = FullSerializer.fsJsonParser.Parse(levelParams, out jsData);
        DebugLogger.WriteInfo("GameLevel.LoadLevel res.Failed = {0}", res.Failed.ToInt());
        if (res.Failed)
        {
            DebugLogger.WriteError("GameLevel.LoadLevel error = {0}", res.FormattedMessages);
            return;
        }
        DebugLogger.WriteInfo("GameLevel.LoadLevel data.IsDictionary = {0}", jsData.IsDictionary.ToInt());
        if (!jsData.IsDictionary)
        {
            DebugLogger.WriteError("GameLevel.LoadLevel json data is incorrect format");
            return;
        }

        var isDict = jsData.IsDictionary;

        if (!isDict)
        {
            DebugLogger.WriteError("GameLevel.LoadLevel json data must be have node 'level'");
            return;
        }
        jsData = jsData.AsDictionary["level"];
        DebugLogger.WriteInfo("GameLevel.LoadLevel data.AsDictionary = {0}", jsData.IsDictionary.ToInt());
        if (!jsData.IsDictionary)
        {
            DebugLogger.WriteError("GameLevel.LoadLevel level data is not dictionary");
            return;
        }

        var jsLevelParams = jsData.AsDictionary;
        var jsTerrain     = jsLevelParams["terrain"];

        if (!jsTerrain.IsDictionary)
        {
            DebugLogger.WriteError("GameLevel.LoadLevel terrain data is not dictionary");
            return;
        }

        _levelAllSprites = new GameObject("GameLevel");

        var jsIslands    = jsTerrain.AsDictionary["islands"];
        var jsIslandList = jsIslands.AsList;

        var islandList = new List <Island>();

        foreach (var jsIsland in jsIslandList)
        {
            var island = new Island(this, _levelAllSprites.transform);
            island.Load(jsIsland);
            islandList.Add(island);
        }

        if (islandList.Count == 1)
        {
            var island = islandList[0];
            Field = new Rect(new Vector2(island.Pos.x - 0.5f * island.Size.x, island.Pos.y - 0.5f * island.Size.y),
                             new Vector2(island.Size.x, island.Size.y));
        }
        else
        {
            var minPosX = float.MaxValue;
            var maxPosX = float.MinValue;
            var minPosY = float.MaxValue;
            var maxPosY = float.MinValue;
            foreach (var island in islandList)
            {
                if (minPosX > island.Pos.x - 0.5f * island.Size.x)
                {
                    minPosX = island.Pos.x - 0.5f * island.Size.x;
                }
                if (maxPosX < island.Pos.x + 0.5f * island.Size.x)
                {
                    maxPosX = island.Pos.x + 0.5f * island.Size.x;
                }
                if (minPosY > island.Pos.y - 0.5f * island.Size.y)
                {
                    minPosY = island.Pos.y - 0.5f * island.Size.y;
                }
                if (maxPosY < island.Pos.y + 0.5f * island.Size.y)
                {
                    maxPosY = island.Pos.y + 0.5f * island.Size.y;
                }
            }
            Field = new Rect(new Vector2(minPosX, minPosY), new Vector2(maxPosX - minPosX, maxPosY - minPosX));
        }

        if (jsTerrain.AsDictionary.ContainsKey("bridges"))
        {
            var jsBrigdeList = jsTerrain.AsDictionary["bridges"].AsList;
            foreach (var jsBrigde in jsBrigdeList)
            {
                var bridge = new Bridge(this, _levelAllSprites.transform, islandList);
                if (!bridge.Load(jsBrigde))
                {
                    DebugLogger.WriteError("GameLevel.LoadLevel load bridge is failed");
                }
            }
        }

        foreach (var island in islandList)
        {
            island.CreateBorders();
        }

        if (jsLevelParams.ContainsKey("enemy"))
        {
            var jsEnemy = jsLevelParams["enemy"];
            if (jsEnemy.AsDictionary.ContainsKey("portals"))
            {
                var jsPortalList = jsEnemy.AsDictionary["portals"].AsList;
                foreach (var jsPortal in jsPortalList)
                {
                    var jsPortalData = jsPortal.AsDictionary;
                    int portalLevel  = jsPortalData.ContainsKey("level") ? (int)jsPortalData["level"].AsInt64 : 0;

                    var portalPos = GameLevelJsonLoader.GetPos(jsPortalData["pos"]);
                    int islandId  = jsPortalData.ContainsKey("islandId") ? (int)jsPortalData["islandId"].AsInt64 : -1;
                    var portal    = EGHelpers.CreateObjectByPrefab <Portal>((islandId == -1 ? portalPos :
                                                                             (portalPos + islandList.Find(it => it.Id == islandId).Pos)), prefabPortal, _levelAllSprites.transform);
                    portal.Level = portalLevel;
                    portal.AddObserver(_DiedObject);
                    _enemyManager.AddEnemy(portal);
                }
            }
        }

        var jsBonus     = jsLevelParams["bonus"];
        var jsBonusData = jsBonus.AsDictionary;
        var jsGoodBonus = jsBonusData["player"].AsDictionary;

        PlayerUpgrade.SleepTime          = (float)jsGoodBonus["sleepTime"].AsDouble;
        PlayerUpgrade.SpeedTime          = (float)jsGoodBonus["speedTime"].AsDouble;
        PlayerUpgrade.ShieldTime         = (float)jsGoodBonus["shieldTime"].AsDouble;
        PlayerUpgrade.ChildrenShieldTime = (float)jsGoodBonus["childrenShieldTime"].AsDouble;
        PlayerUpgrade.Health             = (float)jsGoodBonus["health"].AsDouble;
        var jsEnemyBonus = jsBonusData["enemy"].AsDictionary;

        EnemyUpgrade.SleepTime  = (float)jsEnemyBonus["sleepTime"].AsDouble;
        EnemyUpgrade.SpeedTime  = (float)jsEnemyBonus["speedTime"].AsDouble;
        EnemyUpgrade.ShieldTime = (float)jsEnemyBonus["shieldTime"].AsDouble;
        EnemyUpgrade.Health     = (float)jsEnemyBonus["health(%)"].AsDouble;
        _enemyCountText.text    = String.Format("E: {0}", _enemyManager.Count.ToString());
    }