Exemple #1
0
        /// <summary>
        /// Calls a component on the Newgrounds.io server.
        /// Note: This is an abstract method and you are better served using the callWith() method of any object in the io.newgrounds.components namespace.
        /// </summary>
        /// <param name="component">The component name to call, ie Gateway.ping</param>
        /// <param name="parameters">An object containing any properties you need to send to the component.</param>
        /// <param name="callback">An optional callback action that will run when the server has executed this component call.</param>
        public void callComponent(string component, object parameters = null, Action <ResultModel> callback = null)
        {
            SimpleJSONImportableList single_call = new SimpleJSONImportableList(typeof(objects.call));

            single_call.Add(_createCall(component, parameters, callback));
            StartCoroutine(_executeCallList(single_call));
        }
Exemple #2
0
        /// <summary>
        ///  Extracts keys from a SimpleJSON.JSONNode matching public properties in this model object.
        /// </summary>
        /// <param name="json">A SimpleJSON.JObject that has been processed from a JSON string.</param>
        /// <param name="core">The core instance to attach to this object.</param>
        internal void setPropertiesFromSimpleJSON(JObject json, core core = null)
        {
            if (core != null)
            {
                this.ngio_core = core;
            }
            else
            {
                core = this.ngio_core;
            }

            Type rType = this.GetType();

            PropertyInfo[] rProps = rType.GetProperties();

            Dictionary <string, JObject> jdict = json.ObjectValue;

            SimpleJSONImportable pval;
            Type ptype;

            foreach (PropertyInfo property in rProps)
            {
                if (!jdict.ContainsKey(property.Name))
                {
                    continue;
                }

                bool    is_model = property.PropertyType.IsSubclassOf(typeof(SimpleJSONImportable));
                JObject jprop    = jdict[property.Name];

                // subclasses can override this method to handle special case properties
                if (setSpecialPropertyFromJSON(property.Name, jprop, core))
                {
                    continue;
                }

                if (jprop.Kind == JObjectKind.Null)
                {
                    property.SetValue(this, null, null);
                }
                else if (is_model)
                {
                    pval = (SimpleJSONImportable)property.GetValue(this, null);
                    pval.setPropertiesFromSimpleJSON(jprop, core);
                }
                else if (isMultiTypeProperty(property.Name) && multi_property_map[property.Name][MultiValueFlat].GetType().IsSubclassOf(typeof(SimpleJSONImportable)))
                {
                    switch (jprop.Kind)
                    {
                    case JObjectKind.Array:
                        SimpleJSONImportableList plist = new SimpleJSONImportableList();
                        ptype      = multi_property_map[property.Name][MultiValueFlat].GetType();
                        plist.type = ptype;
                        foreach (JObject jrow in jprop.ArrayValue)
                        {
                            pval = (SimpleJSONImportable)Activator.CreateInstance(ptype);
                            pval.setPropertiesFromSimpleJSON(jrow, core);
                            plist.Add(pval);
                        }
                        property.SetValue(this, plist, null);
                        break;

                    case JObjectKind.Object:
                        pval = (SimpleJSONImportable)property.GetValue(this, null);
                        pval.setPropertiesFromSimpleJSON(jprop, core);
                        break;

                    default:
                        Debug.LogWarning("Unexpected property value for " + property.Name + ". Setting to null.");
                        property.SetValue(this, null, null);
                        break;
                    }
                }
                else
                {
                    JObjectKind jk  = jprop.Kind;
                    string      ppt = property.PropertyType.ToString();

                    // some bools and numbers may get passed in as strings, this should catch them.
                    if (jk == JObjectKind.String && ppt != "System.String")
                    {
                        switch (ppt)
                        {
                        case "System.Boolean":
                            jk = JObjectKind.Boolean;
                            break;

                        default:
                            jk = JObjectKind.Number;
                            break;
                        }
                    }
                    // and some bools may be set as 0/1 integers too
                    else if (jk == JObjectKind.Number && ppt == "System.Boolean")
                    {
                        jk = JObjectKind.Boolean;
                    }

                    switch (jk)
                    {
                    case JObjectKind.Null:
                        property.SetValue(this, null, null);
                        break;

                    case JObjectKind.Boolean:
                        property.SetValue(this, jprop.BooleanValue, null);
                        break;

                    case JObjectKind.String:
                        property.SetValue(this, jprop.StringValue, null);
                        break;

                    case JObjectKind.Number:

                        // now to figure out what number type to use...
                        if (ppt.StartsWith("System.Int"))
                        {
                            property.SetValue(this, jprop.IntValue, null);
                        }
                        else
                        {
                            property.SetValue(this, jprop.DoubleValue, null);
                        }
                        break;

                    default:
                        Debug.LogWarning("Unexpected property value for " + property.Name + " (Kind=" + jk.ToString() + "). Setting to null.");
                        property.SetValue(this, null, null);
                        break;
                    }
                }
            }
        }
Exemple #3
0
        /// This handles the actual transactions with the Newgrounds.io server. This runs as a Coroutine in Unity.
        private IEnumerator _executeCallList(SimpleJSONImportableList call_list)
        {
            objects.input input = new objects.input();
            input.app_id = app_id;

            if (!string.IsNullOrEmpty(session_id))
            {
                input.session_id = session_id;
            }

            SimpleJSONImportableList calls = new SimpleJSONImportableList(typeof(objects.call));

            objects.call vc;
            CallModel    cm;
            ResultModel  vr;

            for (int c = 0; c < call_list.Count; c++)
            {
                vc = (objects.call)call_list[c];
                cm = CallModel.getByComponentName(vc.component);

                if (cm.require_session && string.IsNullOrEmpty(session_id))
                {
                    vr = (ResultModel)ResultModel.getByComponentName(vc.component);

                    vr.setIsLocal(true);
                    vr.setCall(vc);
                    vr.component     = vc.component;
                    vr.success       = false;
                    vr.error.message = vc.component + " requires a valid user session.";
                    vr.ngio_core     = this;

                    debug_log("Call failed local validation:\n" + vc.toJSON());
                    debug_log("Local Response:\n" + vr.toJSON());

                    if (vc.callback != null)
                    {
                        vc.callback(vr);
                    }

                    vr.dispatchMe(vc.component);
                    continue;
                }
                else
                {
                    calls.Add(vc);
                }
            }

            if (calls.Count > 0)
            {
                input.call = calls;
                string json = input.toJSON();
                debug_log("Sent to Server:\n" + json);

                WWWForm webform = new WWWForm();
                webform.AddField("input", json);

                WWW json_results = new WWW(GATEWAY_URI, webform);

                yield return(json_results);

                debug_log("Server Response:\n" + json_results.text);

                // hopefully, our results will populate to this
                objects.output _output = new objects.output();

                string default_error = "There was a problem connecting to the server at '" + GATEWAY_URI + "'.";

                // we'll try decoding what the server sent back.  If it's valid JSON there should be no problems
                try
                {
                    // decode the overall response
                    JObject jobject = JSONDecoder.Decode(json_results.text);

                    // populate the basic info our output model will need to proceed
                    if (jobject.Kind == JObjectKind.Object)
                    {
                        _output.setPropertiesFromSimpleJSON(jobject);
                    }
                }
                // catch any exceptions and update the generic error message we'll spit back.
                catch (Exception e)
                {
                    Debug.LogWarning("Caught an exception decoding the data:\n" + e.Message);
                    default_error = e.Message;
                }

                _output.ngio_core = this;

                // We'll typically only get here if the was a server or connection error.
                if (_output.success != true && _output.error == null)
                {
                    _output.error         = new objects.error();
                    _output.error.message = default_error;
                }

                // cheap way to fill debug info even with debug mode being off
                _output.debug.input = input;

                ResultModel    _rm;
                objects.result _result;
                objects.call   call;

                for (int i = 0; i < calls.Count; i++)
                {
                    call = (objects.call)calls[i];

                    if (_output.success != true)
                    {
                        _rm       = new ResultModel();
                        _rm.error = _output.error;
                    }
                    else if (_output.result.GetType() == typeof(SimpleJSONImportableList) && ((SimpleJSONImportableList)_output.result).ElementAtOrDefault <object>(i) != null)
                    {
                        _result           = (objects.result)((SimpleJSONImportableList)_output.result)[i];
                        _result.ngio_core = this;

                        if (_result.component != call.component)
                        {
                            _rm               = new ResultModel();
                            _rm.success       = false;
                            _rm.error.message = "Unexpected index mismatch in API response!";
                        }
                        else
                        {
                            _rm = (ResultModel)_result.data;
                        }
                    }
                    else
                    {
                        _rm               = new ResultModel();
                        _rm.success       = false;
                        _rm.error.message = "Unexpected index mismatch in API response!";
                    }

                    _rm.ngio_core = this;
                    _rm.setCall(call);

                    if (call.callback != null)
                    {
                        call.callback(_rm);
                    }

                    _rm.dispatchMe(call.component);
                }
            }
        }