Exemplo n.º 1
0
        public bool process(HttpListenerRequest request, HttpListenerResponse response)
        {
            if (!request.RawUrl.StartsWith(PAGE_PREFIX))
            {
                return(false);
            }

            // Work out how big this request was
            long byteCount = request.RawUrl.Length + request.ContentLength64;

            // Don't count headers + request.Headers.AllKeys.Sum(x => x.Length + request.Headers[x].Length + 1);
            dataRates.RecieveDataFromClient(Convert.ToInt32(byteCount));

            IDictionary <string, object> apiRequests;

            if (request.HttpMethod.ToUpper() == "POST" && request.HasEntityBody)
            {
                System.IO.StreamReader streamReader = new System.IO.StreamReader(request.InputStream);
                apiRequests = parseJSONBody(streamReader.ReadToEnd());
            }
            else
            {
                apiRequests = splitArguments(request.Url.Query);
            }

            var results  = new Dictionary <string, object>();
            var unknowns = new List <string>();
            var errors   = new Dictionary <string, string>();

            foreach (var name in apiRequests.Keys)
            {
                try {
                    results[name] = kspAPI.ProcessAPIString(apiRequests[name].ToString());
                } catch (IKSPAPI.UnknownAPIException)
                {
                    unknowns.Add(apiRequests[name].ToString());
                } catch (Exception ex)
                {
                    errors[apiRequests[name].ToString()] = ex.ToString();
                }
            }
            // If we had any unrecognised API keys, let the user know
            if (unknowns.Count > 0)
            {
                results["unknown"] = unknowns;
            }
            if (errors.Count > 0)
            {
                results["errors"] = errors;
            }

            // Now, serialize the dictionary and write to the response
            var returnData = Encoding.UTF8.GetBytes(SimpleJson.SimpleJson.SerializeObject(results));

            response.ContentEncoding = Encoding.UTF8;
            response.ContentType     = "application/json";
            response.WriteContent(returnData);
            dataRates.SendDataToClient(returnData.Length);
            return(true);
        }
Exemplo n.º 2
0
        }     // OnMessage

        /// Read all variables and send back the responses for just this client
        public void SendDataUpdate()
        {
            // Don't do anything if we are e.g. still awaiting data to be fully set
            if (!readyToSend)
            {
                return;
            }
            lastUpdate = UnityEngine.Time.time;

            // Grab all of the variables at once
            string[] allVariables;
            lock (dataLock)
            {
                allVariables = subscriptions.Union(oneShotRuns).Union(binarySubscriptions).ToArray();
                oneShotRuns.Clear();
            }

            var vessel = api.getVessel();

            // Now, process them all into a data dictionary
            var apiResults = new Dictionary <string, object>();
            var unknowns   = new List <string>();
            var errors     = new Dictionary <string, string>();

            foreach (var apiString in allVariables)
            {
                try
                {
                    apiResults[apiString] = api.ProcessAPIString(apiString);
                }
                catch (IKSPAPI.UnknownAPIException)
                {
                    // IF we get this message, we know it was because no variable was found
                    unknowns.Add(apiString);
                } catch (IKSPAPI.VariableNotEvaluable)
                {
                    // We can't evaluate this at the moment. Just ignore until we can.
                } catch (Exception ex)
                {
                    errors[apiString] = ex.ToString();
                }
            }
            if (unknowns.Count > 0)
            {
                apiResults["unknown"] = unknowns;
            }
            if (errors.Count > 0)
            {
                apiResults["errors"] = errors;
            }

            // Handle sending a binary packet if requested
            if (binarySubscriptions.Length > 0)
            {
                var variableValues = new List <float>();
                // Read every binary value
                foreach (var name in binarySubscriptions)
                {
                    try {
                        variableValues.Add(Convert.ToSingle(apiResults[name]));
                    } catch (Exception ex)
                    {
                        variableValues.Add(0);
                        if (apiResults.ContainsKey(name))
                        {
                            errors[name] = "Error streaming to binary " + name + "='" + apiResults[name] + "'; " + ex.ToString();
                        }
                        else
                        {
                            errors[name] = "Error streaming to binary: value for " + name + " not found; " + ex.ToString();
                        }
                    }
                }
                // Which byte translation?
                Func <float, IEnumerable <byte> > reverser = x => BitConverter.GetBytes(x).Reverse();
                var byteTranslation = BitConverter.IsLittleEndian ? reverser : BitConverter.GetBytes;

                // Now translate these to binary bytes
                var byteData = new List <byte>();
                byteData.Add(1);
                byteData.AddRange(variableValues.SelectMany(x => byteTranslation(x)));
                SendAsync(byteData.ToArray(), x => { });
            }

            //if (allVariables.Contains("binaryNavigation"))
            //{
            //    allVariables = allVariables.Where(x => x != "binaryNavigation").ToArray();
            //    // Build and dispatch the binary information, here and quickly....
            //    var pitch = Convert.ToSingle(api.ProcessAPIString("n.pitch"));
            //    var roll = Convert.ToSingle(api.ProcessAPIString("n.roll"));
            //    var heading = Convert.ToSingle(api.ProcessAPIString("n.heading"));
            //    var deltaV = Convert.ToSingle(api.ProcessAPIString("v.verticalSpeed"));
            //    var parts = new List<byte[]>();
            //    parts.Add(new byte[] { 1 });
            //    parts.Add(BitConverter.GetBytes(heading));
            //    parts.Add(BitConverter.GetBytes(pitch));
            //    parts.Add(BitConverter.GetBytes(roll));
            //    parts.Add(BitConverter.GetBytes(deltaV));
            //    if (BitConverter.IsLittleEndian) parts = parts.Select(x => x.Reverse().ToArray()).ToList();
            //    var byteData = parts.SelectMany(x => x).ToArray();
            //    SendAsync(byteData, x => { });
            //    PluginLogger.print(string.Format("Send byte data for {0}, {1}, {2}, {3}", heading, pitch, roll, deltaV));
            //}

            var data = SimpleJson.SimpleJson.SerializeObject(apiResults);

            // Now, if we have data send a message, otherwise send a null message
            readyToSend = false;
            try
            {
                SendAsync(data, (b) => readyToSend = true);
                dataRates.SendDataToClient(data.Length);
            }
            catch (Exception ex)
            {
                PluginLogger.print("Caught " + ex.ToString());
            }
            finally
            {
                readyToSend = true;
            }
        }