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