Пример #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);
            }
        }
Пример #2
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);
            }
        }
Пример #3
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);
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
0
        public Faction ParseFaction(object response)
        {
            try
            {
                Logging.Debug($"Response from EliteBGS bgsRestClient endpoint {factionEndpoint} is: ", response);

                IDictionary <string, object> factionJson = Deserializtion.DeserializeData(response.ToString());
                Faction faction = new Faction
                {
                    name       = (string)factionJson["name"],
                    updatedAt  = (DateTime)factionJson["updated_at"],
                    Government = Government.FromName((string)factionJson["government"]),
                    Allegiance = Superpower.FromName((string)factionJson["allegiance"]),
                };
                // EDDB ID may not be present for new / unknown factions
                faction.EDDBID = JsonParsing.getOptionalLong(factionJson, "eddb_id");

                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")?.Replace("none", "")) ?? 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);
            }
        }