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); } }
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); } }
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); }
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); }
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); }
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); } }