示例#1
0
        public static List <MicroResourceAmount> ReadMicroResources(string key, IDictionary <string, object> data, string categoryEdName = null)
        {
            var result = new List <MicroResourceAmount>();

            if (data.TryGetValue(key, out object val))
            {
                if (val is List <object> listVal)
                {
                    foreach (IDictionary <string, object> microResourceVal in listVal)
                    {
                        var edname       = JsonParsing.getString(microResourceVal, "Name");
                        var fallbackName = JsonParsing.getString(microResourceVal, "Name_Localised");
                        categoryEdName = JsonParsing.getString(microResourceVal, "Type") ?? categoryEdName ?? MicroResourceCategory.Unknown.edname;
                        var resource = MicroResource.FromEDName(edname, fallbackName, categoryEdName);

                        var ownerId   = JsonParsing.getOptionalInt(microResourceVal, "OwnerID");
                        var missionId = JsonParsing.getOptionalDecimal(microResourceVal, "MissionID");
                        var amount    = JsonParsing.getInt(microResourceVal, "Count");

                        result.Add(new MicroResourceAmount(resource, ownerId, missionId, amount));
                    }
                }
            }
            return(result);
        }
示例#2
0
        private void GetLocationData(IDictionary <string, object> data)
        {
            try
            {
                systemName = JsonParsing.getString(data, "StarSystem") ?? systemName;

                // Some events are bugged and return a SystemAddress of 1, regardles of the system we are in.
                // We need to ignore data that matches this pattern.
                long?SystemAddress = JsonParsing.getOptionalLong(data, "SystemAddress");
                systemAddress = (SystemAddress > 1 ? SystemAddress : systemAddress);

                data.TryGetValue("StarPos", out object starpos);
                if (starpos != null)
                {
                    List <object> starPos = (List <object>)starpos;
                    systemX = Math.Round(JsonParsing.getDecimal("X", starPos[0]) * 32M) / 32M;
                    systemY = Math.Round(JsonParsing.getDecimal("Y", starPos[1]) * 32M) / 32M;
                    systemZ = Math.Round(JsonParsing.getDecimal("Z", starPos[2]) * 32M) / 32M;
                }

                marketId    = JsonParsing.getOptionalLong(data, "MarketID") ?? marketId;
                stationName = JsonParsing.getString(data, "StationName") ?? stationName;
            }
            catch (Exception ex)
            {
                data.Add("exception", ex.Message);
                data.Add("stacktrace", ex.StackTrace);
                Logging.Error("Failed to parse EDDN location data", data);
            }
        }
示例#3
0
        private void CheckLocationData(IDictionary <string, object> data)
        {
            // Can only send journal data if we know our current location data is correct
            // If any location data is null, data shall not be sent to EDDN.
            if (LocationIsSet())
            {
                // The `Docked` event doesn't provide system coordinates, and the `Scan`event doesn't provide any system location data.
                // The EDDN journal schema requires that we enrich the journal event data with coordinates and system name (and system address if possible).
                if (data.ContainsKey("BodyName") && !data.ContainsKey("SystemName"))
                {
                    // Apply heuristics to weed out mismatched systems and bodies
                    ConfirmScan(JsonParsing.getString(data, "BodyName"));
                }
                if (!data.ContainsKey("SystemAddress") || !data.ContainsKey("StarPos"))
                {
                    // Out of an overabundance of caution, we do not use data from our saved star systems to enrich the data we send to EDDN,
                    // but we do use it as an independent check to make sure our system address and coordinates are accurate
                    ConfirmAddressAndCoordinates(systemName);
                }

                if (LocationIsSet())
                {
                    invalidState = false;
                }
                else if (!invalidState)
                {
                    invalidState = true;
#if DEBUG
#else
                    Logging.Warn("The EDDN responder is in an invalid state and is unable to send messages.", JsonConvert.SerializeObject(this) + " Event: " + JsonConvert.SerializeObject(data));
                    SpeechService.Instance.Say(null, EddiEddnResponder.Properties.EddnResources.errPosition);
#endif
                }
            }
        }
示例#4
0
    public void LoadSuccessTest()
    {
        JsonParsing JsonParser     = new JsonParsing();
        int         expectedAnswer = JsonParser.PathJsonTest("questions.json");

        Assert.AreEqual(1, expectedAnswer);
    }
示例#5
0
 public MicroResourceInfo FromData(IDictionary <string, object> data)
 {
     timestamp   = JsonParsing.getDateTime("timestamp", data);
     Components  = ReadMicroResources("Components", data, "Component");
     Consumables = ReadMicroResources("Consumables", data, "Consumable");
     Data        = ReadMicroResources("Data", data, "Data");
     Items       = ReadMicroResources("Items", data, "Item");
     return(this);
 }
示例#6
0
        private void handleRawEvent(Event theEvent)
        {
            IDictionary <string, object> data = Deserializtion.DeserializeData(theEvent.raw);
            string edType = JsonParsing.getString(data, "event");

            if (edType == "FSDTarget" || edType == "StartJump")
            {
                // FSDTarget events describing the system we are targetting rather than the system we are in.
                // Scan events can register after StartJump and before we actually leave the originating system.
                // These must be ignored.
                return;
            }
            else if (edType == "Location" || edType == "FSDJump")
            {
                // We always start fresh from Location and FSDJump events
                invalidState = false;
                ClearLocation();
            }

            // Except as noted above, always attempt to obtain available location data from the active event
            GetLocationData(data);

            // Confirm the data in memory is as accurate as possible
            if (edType == "Docked" || edType == "Scan")
            {
                CheckLocationData(data);
            }

            if (LocationIsSet())
            {
                if (edType == "Docked" && systemName != null && stationName != null && marketId != null)
                {
                    // Send station data from the CAPI servers
                    sendCommodityInformation();
                    sendOutfittingInformation();
                    sendShipyardInformation();
                }

                if (edType == "Location" || edType == "FSDJump" || edType == "Docked" || edType == "Scan")
                {
                    data = StripPersonalData(data);
                    data = EnrichLocationData(edType, data);

                    if (data != null)
                    {
                        SendToEDDN(data);
                    }
                }
            }
        }
示例#7
0
        private void handleRawEvent(Event theEvent)
        {
            IDictionary <string, object> data = Deserializtion.DeserializeData(theEvent.raw);
            string edType = JsonParsing.getString(data, "event");

            // Ignore any events that we've blacklisted for contaminating our location data
            if (ignoredEvents.Contains(edType))
            {
                return;
            }

            // We always start location data fresh when handling events containing complete location data
            if (fullLocationEvents.Contains(edType))
            {
                invalidState = false;
                ClearLocation();
            }

            // Except as noted above, always attempt to obtain available game version data from the active event
            GetGameVersionData(edType, data);

            // Except as noted above, always attempt to obtain available location data from the active event
            GetLocationData(data);

            // Confirm the location data in memory is as accurate as possible when handling an event with partial location data
            if (partialLocationEvents.Contains(edType))
            {
                CheckLocationData(data);
            }

            if (LocationIsSet())
            {
                if (fullLocationEvents.Contains(edType) || partialLocationEvents.Contains(edType))
                {
                    if (CheckSanity(edType, data))
                    {
                        data = StripPersonalData(data);
                        data = EnrichLocationData(edType, data);
                        data = AddGameVersionData(data);

                        if (data != null)
                        {
                            SendToEDDN("https://eddn.edcd.io/schemas/journal/1", data);
                        }
                    }
                }
            }
        }
示例#8
0
        public StarSystem ParseSystem(object response)
        {
            try
            {
                Logging.Debug($"Response from Elite BGS eddbRestClient endpoint {systemEndpoint} is: ", response);

                IDictionary <string, object> systemJson = Deserializtion.DeserializeData(response.ToString());
                StarSystem system = new StarSystem
                {
                    systemname    = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(JsonParsing.getString(systemJson, "name")), // This is lower case by default from the API
                    systemAddress = long.Parse(JsonParsing.getString(systemJson, "ed_system_address")),                                  // Stored in this API as a string
                    EDSMID        = JsonParsing.getOptionalLong(systemJson, "edsm_id"),
                    updatedat     = Dates.fromDateTimeToSeconds(JsonParsing.getDateTime("updated_at", systemJson))
                };

                // Get powerplay data
                // Note: EDDB does not report the following powerplay state ednames:
                // `HomeSystem`, `InPrepareRadius`, `Prepared`, `Turmoil`
                // We can identify `HomeSystem` from static data, but  `InPrepareRadius`, `Prepared`, and `Turmoil`
                // are only available from the `Jumped` and `Location` events:
                // When in conflict, EDDB does not report the names of the conflicting powers.
                string power      = JsonParsing.getString(systemJson, "power");
                string powerstate = JsonParsing.getString(systemJson, "power_state");
                if (!string.IsNullOrEmpty(power))
                {
                    system.Power = Power.FromName(power) ?? Power.None;
                }
                if (!string.IsNullOrEmpty(powerstate))
                {
                    system.powerState = system.systemname == system.Power?.headquarters
                        ? PowerplayState.HomeSystem
                        : PowerplayState.FromName(powerstate) ?? PowerplayState.None;
                }

                return(system);
            }
            catch (Exception ex)
            {
                Dictionary <string, object> data = new Dictionary <string, object>()
                {
                    { "input", response },
                    { "exception", ex }
                };
                Logging.Error("Failed to parse BGS EDDB data.", data);
                return(null);
            }
        }
示例#9
0
    void Start()
    {
        jsonP     = Camera.main.GetComponent <JsonParsing>();
        path      = Path.Combine(Application.streamingAssetsPath, folder);
        snap      = GetComponentInParent <SnapScrolling>();
        answerInt = question.answer;
        answer[0].SetActive(false);
        answer[1].SetActive(false);
        answer[2].SetActive(false);
        answer[3].SetActive(false);
        offsetText       *= snap.kh;
        offsetBetweenText = snap.kh;
        if (question.url != "001")
        {
            StartCoroutine(LoadSprite(question.url));
            Question.GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.text.Length / numToTransfer) * offsetText);
        }
        else
        {
            Destroy(QuestionImage.gameObject);
            Question.GetComponent <RectTransform>().offsetMax = new Vector2(0, 180 * snap.kh);
            Question.GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.text.Length / numToTransfer) * offsetText + (180 * snap.kh));
        }
        Question.text     = question.text;
        Question.fontSize = Mathf.RoundToInt((float)Question.fontSize * snap.kw);

        for (int i = 0; i < question.opt.Length; i++)
        {
            answer[i].SetActive(true);
            if (i == 0)
            {
                answer[i].GetComponent <RectTransform>().offsetMax = new Vector2(0, Question.GetComponent <RectTransform>().offsetMin.y);
                answer[i].GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.opt[i].Length / numToTransfer) * offsetText + Question.GetComponent <RectTransform>().offsetMin.y);
            }
            if (i != 0)
            {
                answer[i].GetComponent <RectTransform>().offsetMax = new Vector2(0, (answer[i - 1].GetComponent <RectTransform>().offsetMin.y) - offsetBetweenText);
                answer[i].GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.opt[i].Length / numToTransfer) * offsetText + (answer[i - 1].GetComponent <RectTransform>().offsetMin.y) - offsetBetweenText);
            }
            answer[i].GetComponentInChildren <Text>().text     = question.opt[i];
            answer[i].GetComponentInChildren <Text>().fontSize = Mathf.RoundToInt((float)answer[i].GetComponentInChildren <Text>().fontSize *snap.kw);
            int t = i + 1;
            answer[i].GetComponent <Button>().onClick.AddListener(() => OnClick(t));
        }
    }
示例#10
0
 private static void PreserveSystemProperties(StarSystem updatedSystem, IDictionary <string, object> oldStarSystem)
 {
     // Carry over StarSystem properties that we want to preserve
     updatedSystem.totalbodies = JsonParsing.getOptionalInt(oldStarSystem, "discoverableBodies") ?? 0;
     if (oldStarSystem.TryGetValue("visitLog", out object visitLogObj))
     {
         // Visits should sync from EDSM, but in case there is a problem with the connection we will also seed back in our old star system visit data
         if (visitLogObj is List <object> oldVisitLog)
         {
             foreach (DateTime visit in oldVisitLog)
             {
                 // The SortedSet<T> class does not accept duplicate elements so we can safely add timestamps which may be duplicates of visits already reported from EDSM.
                 // If an item is already in the set, processing continues and no exception is thrown.
                 updatedSystem.visitLog.Add(visit);
             }
         }
     }
 }
示例#11
0
        private bool CheckSanity(string edType, IDictionary <string, object> data)
        {
            // We've already vetted location data via the CheckLocationData method.
            // Perform any additional quality checks we think we need here.
            var passed = true;

            switch (edType)
            {
            case "Docked":
                // Identify and catch a possible FDev bug that can allow incomplete `Docked` messages
                // missing a MarketID and many other properties.
                if (!data.ContainsKey("MarketID"))
                {
                    passed = false;
                }

                // Don't allow messages with a missing StationName.
                if (data.ContainsKey("StationName") && string.IsNullOrEmpty(JsonParsing.getString(data, "StationName")))
                {
                    passed = false;
                }

                break;

            case "SAASignalsFound":
                if (!data.ContainsKey("Signals"))
                {
                    passed = false;
                }
                break;

            case "Scan":
                if (!data.ContainsKey("ScanType"))
                {
                    passed = false;
                }
                break;
            }
            return(passed);
        }
示例#12
0
        private void GetGameVersionData(string eventType, IDictionary <string, object> data)
        {
            try
            {
                if (string.Equals("FileHeader", eventType, StringComparison.InvariantCultureIgnoreCase))
                {
                    gameVersion = JsonParsing.getString(data, "gameversion") ?? gameVersion;
                    gameBuild   = JsonParsing.getString(data, "build") ?? gameBuild;
                }

                if (string.Equals("LoadGame", eventType, StringComparison.InvariantCultureIgnoreCase) ||
                    string.Equals("Outfitting", eventType, StringComparison.InvariantCultureIgnoreCase) ||
                    string.Equals("Shipyard", eventType, StringComparison.InvariantCultureIgnoreCase))
                {
                    inHorizons = JsonParsing.getOptionalBool(data, "Horizons") ?? false;
                    inOdyssey  = JsonParsing.getOptionalBool(data, "Odyssey") ?? false;
                }
            }
            catch (Exception ex)
            {
                Logging.Error("Failed to parse Elite Dangerous version data for EDDN", ex);
            }
        }
示例#13
0
        private Station ParseStarMapStation(JObject station, string system)
        {
            try
            {
                Station Station = new Station
                {
                    systemname       = system,
                    name             = (string)station["name"],
                    marketId         = (long?)station["marketId"],
                    EDSMID           = (long?)station["id"],
                    Model            = StationModel.FromName((string)station["type"]) ?? StationModel.None,
                    distancefromstar = (decimal?)station["distanceToArrival"], // Light seconds
                };

                var faction = station["controllingFaction"]?.ToObject <Dictionary <string, object> >();
                Station.Faction = new Faction()
                {
                    name       = (string)faction?["name"] ?? string.Empty,
                    EDSMID     = (long?)faction?["id"],
                    Allegiance = Superpower.FromName((string)station["allegiance"]) ?? Superpower.None,
                    Government = Government.FromName((string)station["government"]) ?? Government.None,
                };

                List <EconomyShare> economyShares = new List <EconomyShare>()
                {
                    { new EconomyShare(Economy.FromName((string)station["economy"]) ?? Economy.None, 0) },
                    { new EconomyShare(Economy.FromName((string)station["secondEconomy"]) ?? Economy.None, 0) }
                };
                Station.economyShares = economyShares;

                List <StationService> stationServices = new List <StationService>();
                if ((bool?)station["haveMarket"] is true)
                {
                    stationServices.Add(StationService.FromEDName("Commodities"));
                }
                ;
                if ((bool?)station["haveShipyard"] is true)
                {
                    stationServices.Add(StationService.FromEDName("Shipyard"));
                }
                ;
                if ((bool?)station["haveOutfitting"] is true)
                {
                    stationServices.Add(StationService.FromEDName("Outfitting"));
                }
                ;
                var services = station["otherServices"].ToObject <List <string> >();
                foreach (string service in services)
                {
                    stationServices.Add(StationService.FromName(service));
                }
                ;
                // Add always available services for dockable stations
                stationServices.Add(StationService.FromEDName("Dock"));
                stationServices.Add(StationService.FromEDName("AutoDock"));
                stationServices.Add(StationService.FromEDName("Exploration"));
                stationServices.Add(StationService.FromEDName("Workshop"));
                stationServices.Add(StationService.FromEDName("FlightController"));
                stationServices.Add(StationService.FromEDName("StationOperations"));
                stationServices.Add(StationService.FromEDName("Powerplay"));
                Station.stationServices = stationServices;

                var    updateTimes = station["updateTime"].ToObject <Dictionary <string, object> >();
                string datetime;
                datetime = JsonParsing.getString(updateTimes, "information");
                long?infoLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);
                datetime = JsonParsing.getString(updateTimes, "market");
                long?marketLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);
                datetime = JsonParsing.getString(updateTimes, "shipyard");
                long?shipyardLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);
                datetime = JsonParsing.getString(updateTimes, "outfitting");
                long?        outfittingLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);
                List <long?> updatedAt             = new List <long?>()
                {
                    infoLastUpdated, marketLastUpdated, shipyardLastUpdated, outfittingLastUpdated
                };
                Station.updatedat            = updatedAt.Max();
                Station.outfittingupdatedat  = outfittingLastUpdated;
                Station.commoditiesupdatedat = marketLastUpdated;
                Station.shipyardupdatedat    = shipyardLastUpdated;

                return(Station);
            }
            catch (Exception ex)
            {
                Dictionary <string, object> data = new Dictionary <string, object>
                {
                    { "station", JsonConvert.SerializeObject(station) },
                    { "exception", ex.Message },
                    { "stacktrace", ex.StackTrace }
                };
                Logging.Error("Error parsing EDSM station result.", data);
            }
            return(null);
        }
示例#14
0
        private static Faction ParseStarMapFaction(JObject faction)
        {
            Faction Faction = new Faction
            {
                name         = (string)faction["name"],
                EDSMID       = (long?)faction["id"],
                Allegiance   = Superpower.FromName((string)faction["allegiance"]) ?? Superpower.None,
                Government   = Government.FromName((string)faction["government"]) ?? Government.None,
                isplayer     = (bool)faction["isPlayer"],
                influence    = (decimal?)faction["influence"] * 100, // Convert from a 0-1 range to a percentage
                FactionState = FactionState.FromName((string)faction["state"]) ?? FactionState.None,
                updatedAt    = (DateTime)Dates.fromTimestamp((long?)faction["lastUpdate"])
            };

            IDictionary <string, object> factionDetail = faction.ToObject <IDictionary <string, object> >();

            // Active states
            Faction.ActiveStates = new List <FactionState>();
            factionDetail.TryGetValue("ActiveStates", out object activeStatesVal);
            if (activeStatesVal != null)
            {
                var activeStatesList = (List <object>)activeStatesVal;
                foreach (IDictionary <string, object> activeState in activeStatesList)
                {
                    Faction.ActiveStates.Add(FactionState.FromEDName(JsonParsing.getString(activeState, "State") ?? "None"));
                }
            }

            // Pending states
            Faction.PendingStates = new List <FactionTrendingState>();
            factionDetail.TryGetValue("PendingStates", out object pendingStatesVal);
            if (pendingStatesVal != null)
            {
                var pendingStatesList = (List <object>)pendingStatesVal;
                foreach (IDictionary <string, object> pendingState in pendingStatesList)
                {
                    FactionTrendingState pTrendingState = new FactionTrendingState(
                        FactionState.FromEDName(JsonParsing.getString(pendingState, "State") ?? "None"),
                        JsonParsing.getInt(pendingState, "Trend")
                        );
                    Faction.PendingStates.Add(pTrendingState);
                }
            }

            // Recovering states
            Faction.RecoveringStates = new List <FactionTrendingState>();
            factionDetail.TryGetValue("RecoveringStates", out object recoveringStatesVal);
            if (recoveringStatesVal != null)
            {
                var recoveringStatesList = (List <object>)recoveringStatesVal;
                foreach (IDictionary <string, object> recoveringState in recoveringStatesList)
                {
                    FactionTrendingState rTrendingState = new FactionTrendingState(
                        FactionState.FromEDName(JsonParsing.getString(recoveringState, "State") ?? "None"),
                        JsonParsing.getInt(recoveringState, "Trend")
                        );
                    Faction.RecoveringStates.Add(rTrendingState);
                }
            }

            return(Faction);
        }
示例#15
0
        private void SendEventBatch(List <IDictionary <string, object> > eventData, StarMapConfiguration starMapConfiguration)
        {
            if (!EdsmCredentialsSet())
            {
                return;
            }

            // Filter any stale data
            eventData = eventData
                        .Where(e => JsonParsing.getDateTime("timestamp", e) > starMapConfiguration.lastJournalSync)
                        .ToList();
            if (eventData.Count == 0)
            {
                return;
            }

            // The EDSM responder has a `gameIsBeta` flag that it checks prior to sending data via this method.
            var request = new RestRequest("api-journal-v1", Method.POST);

            request.AddParameter("commanderName", commanderName);
            request.AddParameter("apiKey", apiKey);
            request.AddParameter("fromSoftware", Constants.EDDI_NAME);
            request.AddParameter("fromSoftwareVersion", Constants.EDDI_VERSION);
            request.AddParameter("message", JsonConvert.SerializeObject(eventData).Normalize());
            request.Timeout = JournalTimeoutMilliseconds;

            try
            {
                Logging.Debug("Sending message to EDSM: " + restClient.BuildUri(request).AbsoluteUri);
                var clientResponse          = restClient.Execute <StarMapLogResponse>(request);
                StarMapLogResponse response = clientResponse.Data;

                if (response is null)
                {
                    Logging.Warn(clientResponse.ErrorMessage);
                    ReEnqueueEvents(eventData);
                }
                else if (response.msgnum >= 100 && response.msgnum <= 103)
                {
                    // 100 -  Everything went fine!
                    // 101 -  The journal message was already processed in our database.
                    // 102 -  The journal message was already in a newer version in our database.
                    // 103 -  Duplicate event request (already reported from another software client).
                    starMapConfiguration.lastJournalSync = eventData
                                                           .Select(e => JsonParsing.getDateTime("timestamp", e))
                                                           .Max();
                    starMapConfiguration.ToFile();
                }
                if (response?.msgnum != 100)
                {
                    if (!string.IsNullOrEmpty(response?.msg))
                    {
                        Logging.Warn("EDSM responded with: " + response.msg);
                    }
                    else
                    {
                        Logging.Warn("EDSM responded with: " + JsonConvert.SerializeObject(response));
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Warn("Failed to send event to EDSM", ex);
            }
        }
示例#16
0
        public Faction ParseFaction(object response)
        {
            try
            {
                IDictionary <string, object> factionJson = Deserializtion.DeserializeData(response.ToString());
                Faction faction = new Faction
                {
                    EDDBID     = (long)factionJson["eddb_id"],
                    name       = (string)factionJson["name"],
                    updatedAt  = (DateTime)factionJson["updated_at"],
                    Government = Government.FromName((string)factionJson["government"]),
                    Allegiance = Superpower.FromName((string)factionJson["allegiance"]),
                };

                foreach (object presence in (List <object>)factionJson["faction_presence"])
                {
                    IDictionary <string, object> presenceJson = (IDictionary <string, object>)presence;
                    FactionPresence factionPresence           = new FactionPresence()
                    {
                        systemName   = JsonParsing.getString(presenceJson, "system_name"),
                        influence    = (JsonParsing.getOptionalDecimal(presenceJson, "influence") ?? 0) * 100, // Convert from a 0-1 range to a percentage
                        FactionState = FactionState.FromEDName(JsonParsing.getString(presenceJson, "state")) ?? FactionState.None,
                    };

                    // These properties may not be present in the json, so we pass them after initializing our FactionPresence object.
                    factionPresence.Happiness = Happiness.FromEDName(JsonParsing.getString(presenceJson, "happiness")) ?? Happiness.None;
                    presenceJson.TryGetValue("updated_at", out object updatedVal);
                    factionPresence.updatedAt = (DateTime?)updatedVal ?? DateTime.MinValue;

                    // Active states
                    presenceJson.TryGetValue("active_states", out object activeStatesVal);
                    if (activeStatesVal != null)
                    {
                        var activeStatesList = (List <object>)activeStatesVal;
                        foreach (IDictionary <string, object> activeState in activeStatesList)
                        {
                            factionPresence.ActiveStates.Add(FactionState.FromEDName(JsonParsing.getString(activeState, "state")) ?? FactionState.None);
                        }
                    }

                    // Pending states
                    presenceJson.TryGetValue("pending_states", out object pendingStatesVal);
                    if (pendingStatesVal != null)
                    {
                        var pendingStatesList = (List <object>)pendingStatesVal;
                        foreach (IDictionary <string, object> pendingState in pendingStatesList)
                        {
                            FactionTrendingState pTrendingState = new FactionTrendingState(
                                FactionState.FromEDName(JsonParsing.getString(pendingState, "state")) ?? FactionState.None,
                                JsonParsing.getInt(pendingState, "trend")
                                );
                            factionPresence.PendingStates.Add(pTrendingState);
                        }
                    }

                    // Recovering states
                    presenceJson.TryGetValue("recovering_states", out object recoveringStatesVal);
                    if (recoveringStatesVal != null)
                    {
                        var recoveringStatesList = (List <object>)recoveringStatesVal;
                        foreach (IDictionary <string, object> recoveringState in recoveringStatesList)
                        {
                            FactionTrendingState rTrendingState = new FactionTrendingState(
                                FactionState.FromEDName(JsonParsing.getString(recoveringState, "state")) ?? FactionState.None,
                                JsonParsing.getInt(recoveringState, "trend")
                                );
                            factionPresence.RecoveringStates.Add(rTrendingState);
                        }
                    }

                    faction.presences.Add(factionPresence);
                }

                return(faction);
            }
            catch (Exception ex)
            {
                Dictionary <string, object> data = new Dictionary <string, object>()
                {
                    { "input", response },
                    { "exception", ex }
                };
                Logging.Error("Failed to parse BGS faction data.", data);
                return(null);
            }
        }
示例#17
0
        private static Faction ParseFaction(object response)
        {
            IDictionary <string, object> factionJson = Deserializtion.DeserializeData(response.ToString());
            Faction faction = new Faction
            {
                EDDBID     = (long)factionJson["eddb_id"],
                name       = (string)factionJson["name"],
                updatedAt  = (DateTime)factionJson["updated_at"],
                Government = Government.FromName((string)factionJson["government"]),
                Allegiance = Superpower.FromName((string)factionJson["allegiance"]),
            };

            foreach (object presence in (List <object>)factionJson["faction_presence"])
            {
                IDictionary <string, object> presenceJson = (IDictionary <string, object>)presence;
                FactionPresence factionPresence           = new FactionPresence()
                {
                    systemName   = (string)presenceJson["system_name"],
                    influence    = (decimal?)(double?)presenceJson["influence"] * 100, // Convert from a 0-1 range to a percentage
                    FactionState = FactionState.FromEDName((string)presenceJson["state"]) ?? FactionState.None,
                    Happiness    = Happiness.FromEDName((string)presenceJson["happiness"]) ?? Happiness.None,
                    updatedAt    = (DateTime)presenceJson["updated_at"],
                };

                // Active states
                presenceJson.TryGetValue("active_states", out object activeStatesVal);
                if (activeStatesVal != null)
                {
                    var activeStatesList = (List <object>)activeStatesVal;
                    foreach (IDictionary <string, object> activeState in activeStatesList)
                    {
                        factionPresence.ActiveStates.Add(FactionState.FromEDName(JsonParsing.getString(activeState, "state") ?? "None"));
                    }
                }

                // Pending states
                presenceJson.TryGetValue("pending_states", out object pendingStatesVal);
                if (pendingStatesVal != null)
                {
                    var pendingStatesList = (List <object>)pendingStatesVal;
                    foreach (IDictionary <string, object> pendingState in pendingStatesList)
                    {
                        FactionTrendingState pTrendingState = new FactionTrendingState(
                            FactionState.FromEDName(JsonParsing.getString(pendingState, "state") ?? "None"),
                            JsonParsing.getInt(pendingState, "trend")
                            );
                        factionPresence.PendingStates.Add(pTrendingState);
                    }
                }

                // Recovering states
                presenceJson.TryGetValue("recovering_states", out object recoveringStatesVal);
                if (recoveringStatesVal != null)
                {
                    var recoveringStatesList = (List <object>)recoveringStatesVal;
                    foreach (IDictionary <string, object> recoveringState in recoveringStatesList)
                    {
                        FactionTrendingState rTrendingState = new FactionTrendingState(
                            FactionState.FromEDName(JsonParsing.getString(recoveringState, "state") ?? "None"),
                            JsonParsing.getInt(recoveringState, "trend")
                            );
                        factionPresence.RecoveringStates.Add(rTrendingState);
                    }
                }

                faction.presences.Add(factionPresence);
            }

            return(faction);
        }
示例#18
0
        private Faction ParseStarMapFaction(JObject faction, string systemName)
        {
            try
            {
                if (faction is null)
                {
                    return(null);
                }
                Faction Faction = new Faction
                {
                    name       = (string)faction["name"],
                    EDSMID     = (long?)faction["id"],
                    Allegiance = Superpower.FromName((string)faction["allegiance"]) ?? Superpower.None,
                    Government = Government.FromName((string)faction["government"]) ?? Government.None,
                    isplayer   = (bool?)faction["isPlayer"],
                    updatedAt  = Dates.fromTimestamp((long?)faction["lastUpdate"]) ?? DateTime.MinValue
                };

                Faction.presences.Add(new FactionPresence()
                {
                    systemName   = systemName,
                    influence    = (decimal?)faction["influence"] * 100, // Convert from a 0-1 range to a percentage
                    FactionState = FactionState.FromName((string)faction["state"]) ?? FactionState.None,
                });

                IDictionary <string, object> factionDetail = faction.ToObject <IDictionary <string, object> >();

                // Active states
                factionDetail.TryGetValue("activeStates", out object activeStatesVal);
                if (activeStatesVal != null)
                {
                    var activeStatesList = (JArray)activeStatesVal;
                    foreach (var activeStateToken in activeStatesList)
                    {
                        var activeState = activeStateToken.ToObject <IDictionary <string, object> >();
                        Faction.presences.FirstOrDefault(p => p.systemName == systemName)?
                        .ActiveStates.Add(FactionState.FromName(JsonParsing.getString(activeState, "state")) ?? FactionState.None);
                    }
                }

                // Pending states
                factionDetail.TryGetValue("pendingStates", out object pendingStatesVal);
                if (pendingStatesVal != null)
                {
                    var pendingStatesList = ((JArray)pendingStatesVal).ToList();
                    foreach (var pendingStateToken in pendingStatesList)
                    {
                        var pendingState = pendingStateToken.ToObject <IDictionary <string, object> >();
                        FactionTrendingState pTrendingState = new FactionTrendingState(
                            FactionState.FromName(JsonParsing.getString(pendingState, "state")) ?? FactionState.None,
                            JsonParsing.getInt(pendingState, "trend")
                            );
                        Faction.presences.FirstOrDefault(p => p.systemName == systemName)?
                        .PendingStates.Add(pTrendingState);
                    }
                }

                // Recovering states
                factionDetail.TryGetValue("recoveringStates", out object recoveringStatesVal);
                if (recoveringStatesVal != null)
                {
                    var recoveringStatesList = (JArray)recoveringStatesVal;
                    foreach (var recoveringStateToken in recoveringStatesList)
                    {
                        var recoveringState = recoveringStateToken.ToObject <IDictionary <string, object> >();
                        FactionTrendingState rTrendingState = new FactionTrendingState(
                            FactionState.FromName(JsonParsing.getString(recoveringState, "state")) ?? FactionState.None,
                            JsonParsing.getInt(recoveringState, "trend")
                            );
                        Faction.presences.FirstOrDefault(p => p.systemName == systemName)?
                        .RecoveringStates.Add(rTrendingState);
                    }
                }

                return(Faction);
            }
            catch (Exception ex)
            {
                Dictionary <string, object> data = new Dictionary <string, object>
                {
                    { "faction", JsonConvert.SerializeObject(faction) },
                    { "exception", ex.Message },
                    { "stacktrace", ex.StackTrace }
                };
                Logging.Error("Error parsing EDSM faction result.", data);
            }
            return(null);
        }
示例#19
0
        private void handleRawEvent(Event theEvent)
        {
            IDictionary <string, object> data = Deserializtion.DeserializeData(theEvent.raw);
            string edType = JsonParsing.getString(data, "event");

            if (edType == "FSDTarget" || edType == "StartJump")
            {
                // FSDTarget events describing the system we are targetting rather than the system we are in.
                // Scan events can register after StartJump and before we actually leave the originating system.
                // These must be ignored.
                return;
            }
            else if (edType == "Location" || edType == "FSDJump")
            {
                // We always start fresh from Location and FSDJump events
                invalidState = false;
                ClearLocation();
            }

            // Except as noted above, always attempt to obtain available location data from the active event
            GetLocationData(data);

            // Confirm the data in memory is as accurate as possible
            if (edType == "Docked" || edType == "Scan")
            {
                CheckLocationData(data);
            }

            if (LocationIsSet())
            {
                if (edType == "Docked" && systemName != null && stationName != null && marketId != null)
                {
                    if (EDDI.Instance.CurrentStation?.name == stationName && EDDI.Instance.CurrentStarSystem?.systemAddress == systemAddress)
                    {
                        try
                        {
                            // Send station data from the CAPI servers
                            sendCommodityInformation();
                            sendOutfittingInformation();
                            sendShipyardInformation();
                        }
                        catch (Exception ex)
                        {
                            Dictionary <string, object> exdata = new Dictionary <string, object>
                            {
                                { "Responder state", this },
                                { "Exception", ex }
                            };
                            Logging.Error("Failed to send Frontier API data to EDDN", exdata);
                        }
                    }
                }

                if (edType == "Location" || edType == "FSDJump" || edType == "Docked" || edType == "Scan")
                {
                    data = StripPersonalData(data);
                    data = EnrichLocationData(edType, data);

                    if (data != null)
                    {
                        SendToEDDN("https://eddn.edcd.io/schemas/journal/1", data);
                    }
                }
            }
        }
示例#20
0
        private static Station ParseStarMapStation(JObject station, string system)
        {
            Station Station = new Station
            {
                systemname       = system,
                name             = (string)station["name"],
                marketId         = (long?)station["marketId"],
                EDSMID           = (long?)station["id"],
                Model            = StationModel.FromName((string)station["type"]) ?? StationModel.None,
                distancefromstar = (decimal?)station["distanceToArrival"], // Light seconds
            };

            var faction = station["controllingFaction"]?.ToObject <Dictionary <string, object> >();

            Station.Faction = new Faction()
            {
                name       = (string)faction["name"],
                EDSMID     = (long?)faction["id"],
                Allegiance = Superpower.FromName((string)station["allegiance"]) ?? Superpower.None,
                Government = Government.FromName((string)station["government"]) ?? Government.None,
            };

            List <Economy> Economies = new List <Economy>()
            {
                Economy.FromName((string)station["economy"]) ?? Economy.None,
                Economy.FromName((string)station["secondEconomy"]) ?? Economy.None
            };

            Station.Economies = Economies;

            List <StationService> stationServices = new List <StationService>();

            if ((bool?)station["haveMarket"] is true)
            {
                stationServices.Add(StationService.FromEDName("Commodities"));
            }
            ;
            if ((bool?)station["haveShipyard"] is true)
            {
                stationServices.Add(StationService.FromEDName("Shipyard"));
            }
            ;
            if ((bool?)station["haveOutfitting"] is true)
            {
                stationServices.Add(StationService.FromEDName("Outfitting"));
            }
            ;
            var services = station["otherServices"].ToObject <List <string> >();

            foreach (string service in services)
            {
                stationServices.Add(StationService.FromName(service));
            }
            ;
            // Add always available services for dockable stations
            stationServices.Add(StationService.FromEDName("Dock"));
            stationServices.Add(StationService.FromEDName("AutoDock"));
            stationServices.Add(StationService.FromEDName("Exploration"));
            stationServices.Add(StationService.FromEDName("Workshop"));
            stationServices.Add(StationService.FromEDName("FlightController"));
            stationServices.Add(StationService.FromEDName("StationOperations"));
            stationServices.Add(StationService.FromEDName("Powerplay"));
            Station.stationServices = stationServices;

            var    updateTimes = station["updateTime"].ToObject <Dictionary <string, object> >();
            string datetime;

            datetime = JsonParsing.getString(updateTimes, "information");
            long?infoLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);

            datetime = JsonParsing.getString(updateTimes, "market");
            long?marketLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);

            datetime = JsonParsing.getString(updateTimes, "shipyard");
            long?shipyardLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);

            datetime = JsonParsing.getString(updateTimes, "outfitting");
            long?        outfittingLastUpdated = Dates.fromDateTimeStringToSeconds(datetime);
            List <long?> updatedAt             = new List <long?>()
            {
                infoLastUpdated, marketLastUpdated, shipyardLastUpdated, outfittingLastUpdated
            };

            Station.updatedat            = updatedAt.Max();
            Station.outfittingupdatedat  = outfittingLastUpdated;
            Station.commoditiesupdatedat = marketLastUpdated;
            Station.shipyardupdatedat    = shipyardLastUpdated;

            return(Station);
        }
示例#21
0
        public Status ParseStatusEntry(string line)
        {
            Status status = new Status();

            try
            {
                Match match = JsonRegex.Match(line);
                if (match.Success)
                {
                    IDictionary <string, object> data = Deserializtion.DeserializeData(line);

                    // Every status event has a timestamp field
                    status.timestamp = DateTime.UtcNow;
                    try
                    {
                        status.timestamp = JsonParsing.getDateTime("timestamp", data);
                    }
                    catch
                    {
                        Logging.Warn("Status without timestamp; using current time");
                    }

                    status.flags = (Status.Flags)(JsonParsing.getOptionalLong(data, "Flags") ?? 0);
                    if (status.flags == Status.Flags.None)
                    {
                        // No flags are set. We aren't in game.
                        return(status);
                    }

                    data.TryGetValue("Pips", out object val);
                    List <long> pips = ((List <object>)val)?.Cast <long>()?.ToList(); // The 'TryGetValue' function returns these values as type 'object<long>'
                    status.pips_sys = pips != null ? ((decimal?)pips[0] / 2) : null;  // Set system pips (converting from half pips)
                    status.pips_eng = pips != null ? ((decimal?)pips[1] / 2) : null;  // Set engine pips (converting from half pips)
                    status.pips_wea = pips != null ? ((decimal?)pips[2] / 2) : null;  // Set weapon pips (converting from half pips)

                    status.firegroup = JsonParsing.getOptionalInt(data, "FireGroup");
                    int?gui_focus = JsonParsing.getOptionalInt(data, "GuiFocus");
                    switch (gui_focus)
                    {
                    case 0:     // No focus
                    {
                        status.gui_focus = "none";
                        break;
                    }

                    case 1:     // InternalPanel (right hand side)
                    {
                        status.gui_focus = "internal panel";
                        break;
                    }

                    case 2:     // ExternalPanel (left hand side)
                    {
                        status.gui_focus = "external panel";
                        break;
                    }

                    case 3:     // CommsPanel (top)
                    {
                        status.gui_focus = "communications panel";
                        break;
                    }

                    case 4:     // RolePanel (bottom)
                    {
                        status.gui_focus = "role panel";
                        break;
                    }

                    case 5:     // StationServices
                    {
                        status.gui_focus = "station services";
                        break;
                    }

                    case 6:     // GalaxyMap
                    {
                        status.gui_focus = "galaxy map";
                        break;
                    }

                    case 7:     // SystemMap
                    {
                        status.gui_focus = "system map";
                        break;
                    }

                    case 8:     // Orrery
                    {
                        status.gui_focus = "orrery";
                        break;
                    }

                    case 9:     // FSS mode
                    {
                        status.gui_focus = "fss mode";
                        break;
                    }

                    case 10:     // SAA mode
                    {
                        status.gui_focus = "saa mode";
                        break;
                    }

                    case 11:     // Codex
                    {
                        status.gui_focus = "codex";
                        break;
                    }
                    }
                    status.latitude  = JsonParsing.getOptionalDecimal(data, "Latitude");
                    status.longitude = JsonParsing.getOptionalDecimal(data, "Longitude");
                    status.altitude  = JsonParsing.getOptionalDecimal(data, "Altitude");
                    status.heading   = JsonParsing.getOptionalDecimal(data, "Heading");
                    if (data.TryGetValue("Fuel", out object fuelData))
                    {
                        if (fuelData is IDictionary <string, object> fuelInfo)
                        {
                            status.fuelInTanks     = JsonParsing.getOptionalDecimal(fuelInfo, "FuelMain");
                            status.fuelInReservoir = JsonParsing.getOptionalDecimal(fuelInfo, "FuelReservoir");
                        }
                    }
                    status.cargo_carried = (int?)JsonParsing.getOptionalDecimal(data, "Cargo");
                    status.legalStatus   = LegalStatus.FromEDName(JsonParsing.getString(data, "LegalState")) ?? LegalStatus.Clean;
                    status.bodyname      = JsonParsing.getString(data, "BodyName");
                    status.planetradius  = JsonParsing.getOptionalDecimal(data, "PlanetRadius");

                    // Calculated data
                    SetFuelExtras(status);
                    SetSlope(status);

                    return(status);
                }
            }
            catch (Exception ex)
            {
                Logging.Warn("Failed to parse Status.json line: " + ex.ToString());
                Logging.Error("", ex);
            }
            return(null);
        }
示例#22
0
        public static Status ParseStatusEntry(string line)
        {
            Status status = new Status();

            try
            {
                Match match = JsonRegex.Match(line);
                if (match.Success)
                {
                    IDictionary <string, object> data = Deserializtion.DeserializeData(line);

                    // Every status event has a timestamp field
                    if (data.ContainsKey("timestamp"))
                    {
                        if (data["timestamp"] is DateTime)
                        {
                            status.timestamp = ((DateTime)data["timestamp"]).ToUniversalTime();
                        }
                        else
                        {
                            status.timestamp = DateTime.Parse(JsonParsing.getString(data, "timestamp")).ToUniversalTime();
                        }
                    }
                    else
                    {
                        Logging.Warn("Status event without timestamp; using current time");
                    }

                    status.flags = (Status.Flags)(JsonParsing.getOptionalLong(data, "Flags") ?? 0);
                    if (status.flags == Status.Flags.None)
                    {
                        // No flags are set. We aren't in game.
                        return(status);
                    }

                    object val;
                    data.TryGetValue("Pips", out val);
                    List <long> pips = ((List <object>)val)?.Cast <long>()?.ToList(); // The 'TryGetValue' function returns these values as type 'object<long>'
                    status.pips_sys = pips != null ? ((decimal?)pips[0] / 2) : null;  // Set system pips (converting from half pips)
                    status.pips_eng = pips != null ? ((decimal?)pips[1] / 2) : null;  // Set engine pips (converting from half pips)
                    status.pips_wea = pips != null ? ((decimal?)pips[2] / 2) : null;  // Set weapon pips (converting from half pips)

                    status.firegroup = JsonParsing.getOptionalInt(data, "FireGroup");
                    int?gui_focus = JsonParsing.getOptionalInt(data, "GuiFocus");
                    switch (gui_focus)
                    {
                    case 0:     // No focus
                    {
                        status.gui_focus = "none";
                        break;
                    }

                    case 1:     // InternalPanel (right hand side)
                    {
                        status.gui_focus = "internal panel";
                        break;
                    }

                    case 2:     // ExternalPanel (left hand side)
                    {
                        status.gui_focus = "external panel";
                        break;
                    }

                    case 3:     // CommsPanel (top)
                    {
                        status.gui_focus = "communications panel";
                        break;
                    }

                    case 4:     // RolePanel (bottom)
                    {
                        status.gui_focus = "role panel";
                        break;
                    }

                    case 5:     // StationServices
                    {
                        status.gui_focus = "station services";
                        break;
                    }

                    case 6:     // GalaxyMap
                    {
                        status.gui_focus = "galaxy map";
                        break;
                    }

                    case 7:     // SystemMap
                    {
                        status.gui_focus = "system map";
                        break;
                    }
                    }
                    status.latitude  = JsonParsing.getOptionalDecimal(data, "Latitude");
                    status.longitude = JsonParsing.getOptionalDecimal(data, "Longitude");
                    status.altitude  = JsonParsing.getOptionalDecimal(data, "Altitude");
                    status.heading   = JsonParsing.getOptionalDecimal(data, "Heading");

                    return(status);
                }
            }
            catch (Exception ex)
            {
                Logging.Warn("Failed to parse Status.json line: " + ex.ToString());
                Logging.Error(ex);
            }
            return(status = null);
        }
示例#23
0
        public List <StarSystem> GetStarSystems(string[] names, bool refreshIfOutdated = true)
        {
            if (!File.Exists(DbFile))
            {
                return(null);
            }
            if (!names.Any())
            {
                return(null);
            }

            List <StarSystem> results = new List <StarSystem>();
            List <KeyValuePair <string, object> > systemsToUpdate = new List <KeyValuePair <string, object> >();
            List <KeyValuePair <string, string> > dataSets        = Instance.ReadStarSystems(names);

            bool needToUpdate = false;

            foreach (KeyValuePair <string, string> kv in dataSets)
            {
                if (!string.IsNullOrEmpty(kv.Value))
                {
                    string name = kv.Key;

                    // Old versions of the data could have a string "No volcanism" for volcanism.  If so we remove it
                    string data = kv.Value?.Replace(@"""No volcanism""", "null");

                    // Old versions of the data could have a string "InterstellarFactorsContact" for the facilitator station service.  If so we update it
                    data = kv.Value?.Replace(@"""InterstellarFactorsContact""", @"""Facilitator""");

                    // Determine whether our data is stale (We won't deserialize the the entire system if it's stale)
                    IDictionary <string, object> system = Deserializtion.DeserializeData(data);
                    system.TryGetValue("lastupdated", out object lastUpdatedVal);
                    system.TryGetValue("systemAddress", out object systemAddressVal);
                    system.TryGetValue("EDSMID", out object edsmIdVal);

                    DateTime?lastupdated   = (DateTime?)lastUpdatedVal;
                    long?    systemAddress = (long?)systemAddressVal;
                    long?    edsmId        = (long?)edsmIdVal;

                    if (refreshIfOutdated)
                    {
                        if (lastupdated < DateTime.UtcNow.AddHours(-1))
                        {
                            // Data is stale
                            needToUpdate = true;
                        }
                        else if (lastupdated is null)
                        {
                            // We have no record of ever updating this star system
                            needToUpdate = true;
                        }
                        else if (SCHEMA_VERSION >= 2 && (systemAddress is null || edsmId is null))
                        {
                            // Obtain data for optimized data searches starting with schema version 2
                            needToUpdate = true;
                        }
                    }

                    if (needToUpdate)
                    {
                        // We want to update this star system (don't deserialize the old result at this time)
                        systemsToUpdate.Add(new KeyValuePair <string, object>(name, system));
                    }
                    else
                    {
                        // Deserialize the old result
                        StarSystem result = DeserializeStarSystem(name, data, ref needToUpdate);
                        if (result != null)
                        {
                            results.Add(result);
                        }
                    }
                }
            }

            if (systemsToUpdate.Count > 0)
            {
                List <StarSystem> updatedSystems = dataProviderService.GetSystemsData(systemsToUpdate.Select(s => s.Key).ToArray());

                // If the newly fetched star system is an empty object except (for the object name), reject it
                // Return old results when new results have been rejected
                List <string> systemsToRevert = new List <string>();
                foreach (StarSystem starSystem in updatedSystems)
                {
                    if (starSystem.systemAddress == null)
                    {
                        systemsToRevert.Add(starSystem.systemname);
                    }
                }
                updatedSystems.RemoveAll(s => systemsToRevert.Contains(s.systemname));
                foreach (string systemName in systemsToRevert)
                {
                    results.Add(GetStarSystem(systemName, false));
                }

                // Synchronize EDSM visits and comments
                updatedSystems = dataProviderService.syncFromStarMapService(updatedSystems);

                // Update properties that aren't synced from the server and that we want to preserve
                foreach (StarSystem updatedSystem in updatedSystems)
                {
                    foreach (KeyValuePair <string, object> systemToUpdate in systemsToUpdate)
                    {
                        if (updatedSystem.systemname == systemToUpdate.Key)
                        {
                            Dictionary <string, object> oldStarSystem = (Dictionary <string, object>)systemToUpdate.Value;

                            if (oldStarSystem != null)
                            {
                                // Carry over StarSystem properties that we want to preserve
                                updatedSystem.totalbodies = JsonParsing.getOptionalInt(oldStarSystem, "discoverableBodies") ?? 0;

                                // Carry over Body properties that we want to preserve (e.g. exploration data)
                                oldStarSystem.TryGetValue("bodies", out object bodiesVal);
                                List <Body> oldBodies = JsonConvert.DeserializeObject <List <Body> >(JsonConvert.SerializeObject(bodiesVal));
                                updatedSystem.PreserveBodyData(oldBodies, updatedSystem.bodies);

                                // Carry over Faction properties that we want to preserve (e.g. reputation data)
                                oldStarSystem.TryGetValue("factions", out object factionsVal);
                                if (factionsVal != null)
                                {
                                    List <Faction> oldFactions = JsonConvert.DeserializeObject <List <Faction> >(JsonConvert.SerializeObject(factionsVal));
                                    if (oldFactions?.Count > 0)
                                    {
                                        foreach (var updatedFaction in updatedSystem.factions)
                                        {
                                            foreach (var oldFaction in oldFactions)
                                            {
                                                if (updatedFaction.name == oldFaction.name)
                                                {
                                                    updatedFaction.myreputation = oldFaction.myreputation;
                                                }
                                            }
                                        }
                                    }
                                }

                                // No station data needs to be carried over at this time.
                            }
                        }
                    }
                }

                // Update the `lastupdated` timestamps for the systems we have updated
                foreach (StarSystem starSystem in updatedSystems)
                {
                    starSystem.lastupdated = DateTime.UtcNow;
                }

                // Add our updated systems to our results
                results.AddRange(updatedSystems);

                // Save changes to our star systems
                Instance.updateStarSystems(updatedSystems);
            }
            return(results);
        }
示例#24
0
        private IDictionary <string, object> prepareEventData(Event theEvent)
        {
            // Prep transient game state info (metadata) per https://www.edsm.net/en/api-journal-v1.
            // Unpackage the event, add transient game state info as applicable, then repackage and send the event
            IDictionary <string, object> eventObject = Deserializtion.DeserializeData(theEvent.raw);
            string eventType = JsonParsing.getString(eventObject, "event");

            if (ignoredEvents.Contains(eventType) || theEvent.raw == null)
            {
                return(null);
            }

            // Add metadata from events
            switch (eventType)
            {
            case "LoadGame":
            {
                eventObject.Add("_systemAddress", null);
                eventObject.Add("_systemName", null);
                eventObject.Add("_systemCoordinates", null);
                eventObject.Add("_marketId", null);
                eventObject.Add("_stationName", null);
                break;
            }

            case "ShipyardBuy":
            {
                eventObject.Add("_shipId", null);
                break;
            }

            case "SetUserShipName":
            case "ShipyardSwap":
            case "Loadout":
            {
                eventObject.TryGetValue("ShipID", out object shipIdVal);
                if (shipIdVal != null)
                {
                    eventObject.Add("_shipId", (int)(long)shipIdVal);
                }
                break;
            }

            case "Undocked":
            {
                eventObject.Add("_marketId", null);
                eventObject.Add("_stationName", null);
                break;
            }

            case "Location":
            case "FSDJump":
            case "Docked":
            {
                if (eventObject.ContainsKey("StarSystem"))
                {
                    eventObject.Add("_systemName", JsonParsing.getString(eventObject, "StarSystem"));
                }
                if (eventObject.ContainsKey("SystemAddress"))
                {
                    long?systemAddress = JsonParsing.getOptionalLong(eventObject, "SystemAddress");
                    // Some events are bugged and return a SystemAddress of 1, regardles of the system we are in.
                    // We need to ignore data that matches this pattern.
                    systemAddress = (systemAddress > 1 ? systemAddress : null);
                    if (systemAddress != null)
                    {
                        eventObject.Add("_systemAddress", systemAddress);
                    }
                }
                if (eventObject.ContainsKey("StarPos"))
                {
                    eventObject.TryGetValue("StarPos", out object starpos);
                    if (starpos != null)
                    {
                        eventObject.Add("_systemCoordinates", starpos);
                    }
                }
                if (eventObject.ContainsKey("MarketID"))
                {
                    eventObject.Add("_marketId", JsonParsing.getOptionalLong(eventObject, "MarketID"));
                }
                if (eventObject.ContainsKey("StationName"))
                {
                    eventObject.Add("_stationName", JsonParsing.getString(eventObject, "StationName"));
                }
                break;
            }
            }

            // Supplement with metadata from the tracked game state, as applicable
            if (EDDI.Instance.CurrentStarSystem != null)
            {
                if (!eventObject.ContainsKey("_systemAddress"))
                {
                    eventObject.Add("_systemAddress", EDDI.Instance.CurrentStarSystem.systemAddress);
                }
                if (!eventObject.ContainsKey("_systemName"))
                {
                    eventObject.Add("_systemName", EDDI.Instance.CurrentStarSystem.systemname);
                }
                if (!eventObject.ContainsKey("_systemCoordinates"))
                {
                    List <decimal?> _coordinates = new List <decimal?>
                    {
                        EDDI.Instance.CurrentStarSystem.x,
                        EDDI.Instance.CurrentStarSystem.y,
                        EDDI.Instance.CurrentStarSystem.z
                    };
                    eventObject.Add("_systemCoordinates", _coordinates);
                }
            }
            if (EDDI.Instance.CurrentStation != null)
            {
                if (!eventObject.ContainsKey("_marketId"))
                {
                    eventObject.Add("_marketId", EDDI.Instance.CurrentStation.marketId);
                }
                if (!eventObject.ContainsKey("_stationName"))
                {
                    eventObject.Add("_stationName", EDDI.Instance.CurrentStation.name);
                }
            }
            if (EDDI.Instance.CurrentShip != null && !eventObject.ContainsKey("_shipId"))
            {
                eventObject.Add("_shipId", EDDI.Instance.CurrentShip.LocalId);
            }

            return(eventObject);
        }
示例#25
0
        private string prepareEventData(Event theEvent)
        {
            // Prep transient game state info (metadata) per https://www.edsm.net/en/api-journal-v1.
            // Unpackage the event, add transient game state info as applicable, then repackage and send the event
            IDictionary <string, object> eventObject = Deserializtion.DeserializeData(theEvent.raw);
            string eventType = JsonParsing.getString(eventObject, "event");

            if (ignoredEvents.Contains(eventType) || theEvent.raw == null)
            {
                return(null);
            }

            // Add metadata from events
            switch (eventType)
            {
            case "LoadGame":
            {
                eventObject.Add("_systemAddress", null);
                eventObject.Add("_systemName", null);
                eventObject.Add("_systemCoordinates", null);
                eventObject.Add("_marketId", null);
                eventObject.Add("_stationName", null);
                break;
            }

            case "SetUserShipName":
            {
                ShipRenamedEvent shipRenamedEvent = (ShipRenamedEvent)theEvent;
                eventObject.Add("_shipId", shipRenamedEvent.shipid);
                break;
            }

            case "ShipyardBuy":
            {
                eventObject.Add("_shipId", null);
                break;
            }

            case "ShipyardSwap":
            {
                ShipSwappedEvent shipSwappedEvent = (ShipSwappedEvent)theEvent;
                eventObject.Add("_shipId", shipSwappedEvent.shipid);
                break;
            }

            case "Loadout":
            {
                ShipLoadoutEvent shipLoadoutEvent = (ShipLoadoutEvent)theEvent;
                eventObject.Add("_shipId", shipLoadoutEvent.shipid);
                break;
            }

            case "Undocked":
            {
                eventObject.Add("_marketId", null);
                eventObject.Add("_stationName", null);
                break;
            }

            case "Location":
            {
                LocationEvent locationEvent = (LocationEvent)theEvent;
                eventObject.Add("_systemAddress", null);         // We don't collect this info yet
                eventObject.Add("_systemName", locationEvent.system);
                List <decimal?> _systemCoordinates = new List <decimal?>
                {
                    locationEvent.x,
                    locationEvent.y,
                    locationEvent.z
                };
                eventObject.Add("_systemCoordinates", _systemCoordinates);
                eventObject.Add("_marketId", null);         // We don't collect this info yet
                eventObject.Add("_stationName", locationEvent.station);
                break;
            }

            case "FSDJump":
            {
                JumpedEvent jumpedEvent = (JumpedEvent)theEvent;
                eventObject.Add("_systemAddress", null);         // We don't collect this info yet
                eventObject.Add("_systemName", jumpedEvent.system);
                List <decimal?> _systemCoordinates = new List <decimal?>
                {
                    jumpedEvent.x,
                    jumpedEvent.y,
                    jumpedEvent.z
                };
                eventObject.Add("_systemCoordinates", _systemCoordinates);
                break;
            }

            case "Docked":
            {
                DockedEvent dockedEvent = (DockedEvent)theEvent;
                eventObject.Add("_systemAddress", null);         // We don't collect this info yet
                eventObject.Add("_systemName", dockedEvent.system);
                eventObject.Add("_systemCoordinates", null);
                eventObject.Add("_marketId", null);         // We don't collect this info yet
                eventObject.Add("_stationName", dockedEvent.station);
                break;
            }
            }

            // Supplement with metadata from the tracked game state, as applicable
            if (EDDI.Instance.CurrentStarSystem != null)
            {
                if (!eventObject.ContainsKey("_systemAddress") && !eventObject.ContainsKey("SystemAddress"))
                {
                    eventObject.Add("_systemAddress", null); // We don't collect this info yet
                }
                if (!eventObject.ContainsKey("_systemName") && !eventObject.ContainsKey("SystemName"))
                {
                    eventObject.Add("_systemName", EDDI.Instance.CurrentStarSystem.name);
                }
                if (!eventObject.ContainsKey("_systemCoordinates") && !eventObject.ContainsKey("StarPos"))
                {
                    List <decimal?> _coordinates = new List <decimal?>
                    {
                        EDDI.Instance.CurrentStarSystem.x,
                        EDDI.Instance.CurrentStarSystem.y,
                        EDDI.Instance.CurrentStarSystem.z
                    };
                    eventObject.Add("_systemCoordinates", _coordinates);
                }
            }
            if (EDDI.Instance.CurrentStation != null)
            {
                if (!eventObject.ContainsKey("_marketId") && !eventObject.ContainsKey("MarketID"))
                {
                    eventObject.Add("_marketId", null); // We don't collect this info yet
                }
                if (!eventObject.ContainsKey("_stationName") && !eventObject.ContainsKey("StationName"))
                {
                    eventObject.Add("_stationName", EDDI.Instance.CurrentStation.name);
                }
            }
            if (EDDI.Instance.CurrentShip != null && !eventObject.ContainsKey("ShipId") && !eventObject.ContainsKey("_shipId"))
            {
                eventObject.Add("_shipId", EDDI.Instance.CurrentShip.LocalId);
            }

            return(JsonConvert.SerializeObject(eventObject).Normalize());
        }
示例#26
0
        private Body ParseStarMapBody(JObject body, string systemName)
        {
            // General items
            long?    bodyId            = (long?)body["bodyId"];
            long?    EDSMID            = (long?)body["id"];
            string   bodyname          = (string)body["name"];
            BodyType bodyType          = BodyType.FromName((string)body["type"]) ?? BodyType.None;
            decimal? distanceLs        = (decimal?)body["distanceToArrival"]; // Light Seconds
            decimal? temperatureKelvin = (long?)body["surfaceTemperature"];   // Kelvin

            // Orbital characteristics
            decimal?orbitalPeriodDays         = (decimal?)body["orbitalPeriod"];                           // Days
            decimal?semimajoraxisLs           = ConstantConverters.au2ls((decimal?)body["semiMajorAxis"]); // Light seconds
            decimal?eccentricity              = (decimal?)body["orbitalEccentricity"];
            decimal?orbitalInclinationDegrees = (decimal?)body["orbitalInclination"];                      // Degrees
            decimal?periapsisDegrees          = (decimal?)body["argOfPeriapsis"];                          // Degrees
            decimal?rotationPeriodDays        = (decimal?)body["rotationalPeriod"];                        // Days
            decimal?axialTiltDegrees          = (decimal?)body["axialTilt"];                               // Degrees

            List <IDictionary <string, object> > parents = new List <IDictionary <string, object> >();

            if (body["parents"] != null)
            {
                // Parent body types and IDs
                parents = body["parents"].ToObject <List <IDictionary <string, object> > >() ?? new List <IDictionary <string, object> >();
            }

            List <Ring> rings = new List <Ring>();

            if ((JArray)body["rings"] != null || (JArray)body["belts"] != null)
            {
                var ringsData = body["rings"] ?? body["belts"];
                if (ringsData != null)
                {
                    foreach (JObject ring in ringsData)
                    {
                        rings.Add(new Ring(
                                      (string)ring["name"],
                                      RingComposition.FromName((string)ring["type"]),
                                      (decimal)ring["mass"],
                                      (decimal)ring["innerRadius"],
                                      (decimal)ring["outerRadius"]
                                      ));
                    }
                }
            }

            if ((string)body["type"] == "Star")
            {
                // Star-specific items
                string stellarclass      = ((string)body["subType"]).Split(' ')[0]; // Splits "B (Blue-White) Star" to "B"
                int?   stellarsubclass   = null;
                string endOfStellarClass = stellarclass.ToCharArray().ElementAt(stellarclass.Length - 1).ToString();
                if (int.TryParse(endOfStellarClass, out int subclass))
                {
                    // If our stellarclass ends in a number, we need to separate the class from the subclass
                    stellarsubclass = subclass;
                    stellarclass    = stellarclass.Replace(endOfStellarClass, "");
                }

                long?   ageMegaYears      = (long?)body["age"]; // Age in megayears
                string  luminosityclass   = (string)body["luminosity"];
                decimal?absolutemagnitude = (decimal?)body["absoluteMagnitude"];
                decimal?stellarMass       = (decimal?)body["solarMasses"];
                decimal?solarradius       = (decimal?)body["solarRadius"];
                decimal radiusKm          = (decimal)(solarradius != null ? solarradius * Constants.solarRadiusMeters / 1000 : null);

                Body Body = new Body(bodyname, bodyId, parents, distanceLs, stellarclass, stellarsubclass, stellarMass,
                                     radiusKm, absolutemagnitude, ageMegaYears, temperatureKelvin, luminosityclass, semimajoraxisLs,
                                     eccentricity, orbitalInclinationDegrees, periapsisDegrees, orbitalPeriodDays, rotationPeriodDays,
                                     axialTiltDegrees, rings, true, false, systemName, null)
                {
                    EDSMID = EDSMID
                };
                DateTime updatedAt = JsonParsing.getDateTime("updateTime", body);
                Body.updatedat = updatedAt == null ? null : (long?)Dates.fromDateTimeToSeconds(updatedAt);

                return(Body);
            }

            if ((string)body["type"] == "Planet")
            {
                // Planet and moon specific items
                PlanetClass    planetClass    = PlanetClass.FromName((string)body["subType"]) ?? PlanetClass.None;
                bool?          tidallylocked  = (bool?)body["rotationalPeriodTidallyLocked"] ?? false;
                bool?          landable       = (bool?)body["isLandable"];
                decimal?       gravity        = (decimal?)body["gravity"]; // G's
                decimal?       earthmass      = (decimal?)body["earthMasses"];
                decimal?       radiusKm       = (decimal?)body["radius"];  // Kilometers
                TerraformState terraformState = TerraformState.FromName((string)body["terraformingState"]) ?? TerraformState.NotTerraformable;

                Volcanism volcanism = null;
                if ((string)body["volcanismType"] != null)
                {
                    volcanism = Volcanism.FromName((string)body["volcanismType"]);
                }

                List <AtmosphereComposition> atmosphereCompositions = new List <AtmosphereComposition>();
                if (body["atmosphereComposition"] is JObject)
                {
                    var compositions = body["atmosphereComposition"].ToObject <Dictionary <string, decimal?> >();

                    foreach (KeyValuePair <string, decimal?> compositionKV in compositions)
                    {
                        string  compositionName = compositionKV.Key;
                        decimal?share           = compositionKV.Value;
                        if (compositionName != null && share != null)
                        {
                            atmosphereCompositions.Add(new AtmosphereComposition(compositionName, (decimal)share));
                        }
                    }
                    if (atmosphereCompositions.Count > 0)
                    {
                        atmosphereCompositions = atmosphereCompositions.OrderByDescending(x => x.percent).ToList();
                    }
                }
                decimal?        pressureAtm     = (decimal?)body["surfacePressure"];
                AtmosphereClass atmosphereClass = null;
                if (((string)body["subType"]).Contains("gas giant") &&
                    (string)body["atmosphereType"] == "No atmosphere")
                {
                    // EDSM classifies any body with an empty string atmosphere property as "No atmosphere".
                    // However, gas giants also receive an empty string. Fix it, since gas giants have atmospheres.
                    atmosphereClass = AtmosphereClass.FromEDName("GasGiant");
                }
                else
                {
                    atmosphereClass = AtmosphereClass.FromName((string)body["atmosphereType"]);
                }

                List <SolidComposition> solidCompositions = new List <SolidComposition>();
                if (body["solidComposition"] is JObject)
                {
                    var compositions = body["solidComposition"].ToObject <Dictionary <string, decimal?> >();

                    foreach (KeyValuePair <string, decimal?> compositionKV in compositions)
                    {
                        string  composition = compositionKV.Key;
                        decimal?share       = compositionKV.Value;
                        if (composition != null && share != null)
                        {
                            solidCompositions.Add(new SolidComposition(composition, (decimal)share));
                        }
                    }
                    if (solidCompositions.Count > 0)
                    {
                        solidCompositions = solidCompositions.OrderByDescending(x => x.percent).ToList();
                    }
                }

                List <MaterialPresence> materials = new List <MaterialPresence>();
                if (body["materials"] is JObject)
                {
                    var materialsData = body["materials"].ToObject <Dictionary <string, decimal?> >();
                    foreach (KeyValuePair <string, decimal?> materialKV in materialsData)
                    {
                        Material material = Material.FromName(materialKV.Key);
                        decimal? amount   = materialKV.Value;
                        if (material != null && amount != null)
                        {
                            materials.Add(new MaterialPresence(material, (decimal)amount));
                        }
                    }
                    if (materials.Count > 0)
                    {
                        materials = materials.OrderByDescending(o => o.percentage).ToList();
                    }
                }
                ReserveLevel reserveLevel = ReserveLevel.FromName((string)body["reserveLevel"]) ?? ReserveLevel.None;

                DateTime updatedAt = JsonParsing.getDateTime("updateTime", body);
                Body     Body      = new Body(bodyname, bodyId, parents, distanceLs, tidallylocked, terraformState, planetClass, atmosphereClass, atmosphereCompositions, volcanism, earthmass, radiusKm, (decimal)gravity, temperatureKelvin, pressureAtm, landable, materials, solidCompositions, semimajoraxisLs, eccentricity, orbitalInclinationDegrees, periapsisDegrees, orbitalPeriodDays, rotationPeriodDays, axialTiltDegrees, rings, reserveLevel, true, true, systemName, null)
                {
                    EDSMID    = EDSMID,
                    updatedat = updatedAt == null ? null : (long?)Dates.fromDateTimeToSeconds(updatedAt)
                };

                return(Body);
            }


            return(null);
        }
        internal static RepositoryDescription FromJson(JObject json, TraceContext trace, Uri documentRoot)
        {
            Guard.NotNull(json, "json");
            Guard.NotNull(trace, "trace");

            using (trace.EnterExit())
            {
                // Read the version field
                int majorVersion      = 0;
                var majorVersionToken = json["version"];
                if (majorVersionToken != null && majorVersionToken.Type != JTokenType.Null)
                {
                    if (majorVersionToken.Type != JTokenType.Integer)
                    {
                        trace.JsonParseWarning(
                            majorVersionToken,
                            String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidVersion, majorVersionToken.ToDisplayString()));
                    }
                    else
                    {
                        majorVersion = majorVersionToken.Value <int>();

                        if (majorVersion < 0)
                        {
                            trace.JsonParseWarning(
                                majorVersionToken,
                                String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidVersion, majorVersion));
                            majorVersion = 0;
                        }
                    }
                }
                else
                {
                    trace.JsonParseWarning(
                        json,
                        String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "version"));
                }
                var version = new Version(majorVersion, 0);

                // Read mirrors/alternates
                // TODO: Remove old "alternates" name
                var mirrorsToken = json["mirrors"] ?? json["alternates"];
                IEnumerable <Uri> mirrors;
                if (mirrorsToken != null && mirrorsToken.Type != JTokenType.Null)
                {
                    if (mirrorsToken.Type != JTokenType.Array)
                    {
                        trace.JsonParseWarning(
                            mirrorsToken,
                            String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidMirrors, mirrorsToken.ToDisplayString()));
                        mirrors = Enumerable.Empty <Uri>();
                    }
                    else
                    {
                        mirrors = JsonParsing.ParseUrlArray((JArray)mirrorsToken, trace, documentRoot, Strings.RepositoryDescription_InvalidMirrorUrl);
                    }
                }
                else
                {
                    trace.JsonParseWarning(
                        json,
                        String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "mirrors"));
                    mirrors = Enumerable.Empty <Uri>();
                }

                // Read services
                var servicesToken = json["services"];
                IEnumerable <ServiceDescription> services;
                if (servicesToken != null && servicesToken.Type != JTokenType.Null)
                {
                    if (servicesToken.Type != JTokenType.Object)
                    {
                        trace.JsonParseWarning(
                            mirrorsToken,
                            String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidServices, servicesToken.ToDisplayString()));
                        services = Enumerable.Empty <ServiceDescription>();
                    }
                    else
                    {
                        services = JsonParsing.ParseUrlDictionary(json.Value <JObject>("services"), trace, documentRoot, Strings.RepositoryDescription_InvalidServiceUrl).Select(pair => new ServiceDescription(pair.Key, pair.Value));
                    }
                }
                else
                {
                    trace.JsonParseWarning(
                        json,
                        String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "services"));
                    services = Enumerable.Empty <ServiceDescription>();
                }

                // Create the object!
                return(new RepositoryDescription(version, mirrors, services));
            }
        }