Beispiel #1
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);
            }
        }
Beispiel #2
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);
        }
Beispiel #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
                }
            }
        }
Beispiel #4
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);
                    }
                }
            }
        }
Beispiel #5
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);
                        }
                    }
                }
            }
        }
Beispiel #6
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);
            }
        }
Beispiel #7
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);
        }
Beispiel #8
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);
            }
        }
Beispiel #9
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);
        }
Beispiel #10
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);
            }
        }
Beispiel #11
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);
        }
Beispiel #12
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);
        }
Beispiel #13
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);
                    }
                }
            }
        }
Beispiel #14
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);
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
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());
        }
Beispiel #18
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);
        }
Beispiel #19
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);
        }