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 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); } }
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 } } }
public void LoadSuccessTest() { JsonParsing JsonParser = new JsonParsing(); int expectedAnswer = JsonParser.PathJsonTest("questions.json"); Assert.AreEqual(1, expectedAnswer); }
public MicroResourceInfo FromData(IDictionary <string, object> data) { timestamp = JsonParsing.getDateTime("timestamp", data); Components = ReadMicroResources("Components", data, "Component"); Consumables = ReadMicroResources("Consumables", data, "Consumable"); Data = ReadMicroResources("Data", data, "Data"); Items = ReadMicroResources("Items", data, "Item"); return(this); }
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); } }
void Start() { jsonP = Camera.main.GetComponent <JsonParsing>(); path = Path.Combine(Application.streamingAssetsPath, folder); snap = GetComponentInParent <SnapScrolling>(); answerInt = question.answer; answer[0].SetActive(false); answer[1].SetActive(false); answer[2].SetActive(false); answer[3].SetActive(false); offsetText *= snap.kh; offsetBetweenText = snap.kh; if (question.url != "001") { StartCoroutine(LoadSprite(question.url)); Question.GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.text.Length / numToTransfer) * offsetText); } else { Destroy(QuestionImage.gameObject); Question.GetComponent <RectTransform>().offsetMax = new Vector2(0, 180 * snap.kh); Question.GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.text.Length / numToTransfer) * offsetText + (180 * snap.kh)); } Question.text = question.text; Question.fontSize = Mathf.RoundToInt((float)Question.fontSize * snap.kw); for (int i = 0; i < question.opt.Length; i++) { answer[i].SetActive(true); if (i == 0) { answer[i].GetComponent <RectTransform>().offsetMax = new Vector2(0, Question.GetComponent <RectTransform>().offsetMin.y); answer[i].GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.opt[i].Length / numToTransfer) * offsetText + Question.GetComponent <RectTransform>().offsetMin.y); } if (i != 0) { answer[i].GetComponent <RectTransform>().offsetMax = new Vector2(0, (answer[i - 1].GetComponent <RectTransform>().offsetMin.y) - offsetBetweenText); answer[i].GetComponent <RectTransform>().offsetMin = new Vector2(0, (3 - question.opt[i].Length / numToTransfer) * offsetText + (answer[i - 1].GetComponent <RectTransform>().offsetMin.y) - offsetBetweenText); } answer[i].GetComponentInChildren <Text>().text = question.opt[i]; answer[i].GetComponentInChildren <Text>().fontSize = Mathf.RoundToInt((float)answer[i].GetComponentInChildren <Text>().fontSize *snap.kw); int t = i + 1; answer[i].GetComponent <Button>().onClick.AddListener(() => OnClick(t)); } }
private static void PreserveSystemProperties(StarSystem updatedSystem, IDictionary <string, object> oldStarSystem) { // Carry over StarSystem properties that we want to preserve updatedSystem.totalbodies = JsonParsing.getOptionalInt(oldStarSystem, "discoverableBodies") ?? 0; if (oldStarSystem.TryGetValue("visitLog", out object visitLogObj)) { // Visits should sync from EDSM, but in case there is a problem with the connection we will also seed back in our old star system visit data if (visitLogObj is List <object> oldVisitLog) { foreach (DateTime visit in oldVisitLog) { // The SortedSet<T> class does not accept duplicate elements so we can safely add timestamps which may be duplicates of visits already reported from EDSM. // If an item is already in the set, processing continues and no exception is thrown. updatedSystem.visitLog.Add(visit); } } } }
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 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); }
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); }
private void SendEventBatch(List <IDictionary <string, object> > eventData, StarMapConfiguration starMapConfiguration) { if (!EdsmCredentialsSet()) { return; } // Filter any stale data eventData = eventData .Where(e => JsonParsing.getDateTime("timestamp", e) > starMapConfiguration.lastJournalSync) .ToList(); if (eventData.Count == 0) { return; } // The EDSM responder has a `gameIsBeta` flag that it checks prior to sending data via this method. var request = new RestRequest("api-journal-v1", Method.POST); request.AddParameter("commanderName", commanderName); request.AddParameter("apiKey", apiKey); request.AddParameter("fromSoftware", Constants.EDDI_NAME); request.AddParameter("fromSoftwareVersion", Constants.EDDI_VERSION); request.AddParameter("message", JsonConvert.SerializeObject(eventData).Normalize()); request.Timeout = JournalTimeoutMilliseconds; try { Logging.Debug("Sending message to EDSM: " + restClient.BuildUri(request).AbsoluteUri); var clientResponse = restClient.Execute <StarMapLogResponse>(request); StarMapLogResponse response = clientResponse.Data; if (response is null) { Logging.Warn(clientResponse.ErrorMessage); ReEnqueueEvents(eventData); } else if (response.msgnum >= 100 && response.msgnum <= 103) { // 100 - Everything went fine! // 101 - The journal message was already processed in our database. // 102 - The journal message was already in a newer version in our database. // 103 - Duplicate event request (already reported from another software client). starMapConfiguration.lastJournalSync = eventData .Select(e => JsonParsing.getDateTime("timestamp", e)) .Max(); starMapConfiguration.ToFile(); } if (response?.msgnum != 100) { if (!string.IsNullOrEmpty(response?.msg)) { Logging.Warn("EDSM responded with: " + response.msg); } else { Logging.Warn("EDSM responded with: " + JsonConvert.SerializeObject(response)); } } } catch (Exception ex) { Logging.Warn("Failed to send event to EDSM", ex); } }
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 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); }
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); }
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 List <StarSystem> GetStarSystems(string[] names, bool refreshIfOutdated = true) { if (!File.Exists(DbFile)) { return(null); } if (!names.Any()) { return(null); } List <StarSystem> results = new List <StarSystem>(); List <KeyValuePair <string, object> > systemsToUpdate = new List <KeyValuePair <string, object> >(); List <KeyValuePair <string, string> > dataSets = Instance.ReadStarSystems(names); bool needToUpdate = false; foreach (KeyValuePair <string, string> kv in dataSets) { if (!string.IsNullOrEmpty(kv.Value)) { string name = kv.Key; // Old versions of the data could have a string "No volcanism" for volcanism. If so we remove it string data = kv.Value?.Replace(@"""No volcanism""", "null"); // Old versions of the data could have a string "InterstellarFactorsContact" for the facilitator station service. If so we update it data = kv.Value?.Replace(@"""InterstellarFactorsContact""", @"""Facilitator"""); // Determine whether our data is stale (We won't deserialize the the entire system if it's stale) IDictionary <string, object> system = Deserializtion.DeserializeData(data); system.TryGetValue("lastupdated", out object lastUpdatedVal); system.TryGetValue("systemAddress", out object systemAddressVal); system.TryGetValue("EDSMID", out object edsmIdVal); DateTime?lastupdated = (DateTime?)lastUpdatedVal; long? systemAddress = (long?)systemAddressVal; long? edsmId = (long?)edsmIdVal; if (refreshIfOutdated) { if (lastupdated < DateTime.UtcNow.AddHours(-1)) { // Data is stale needToUpdate = true; } else if (lastupdated is null) { // We have no record of ever updating this star system needToUpdate = true; } else if (SCHEMA_VERSION >= 2 && (systemAddress is null || edsmId is null)) { // Obtain data for optimized data searches starting with schema version 2 needToUpdate = true; } } if (needToUpdate) { // We want to update this star system (don't deserialize the old result at this time) systemsToUpdate.Add(new KeyValuePair <string, object>(name, system)); } else { // Deserialize the old result StarSystem result = DeserializeStarSystem(name, data, ref needToUpdate); if (result != null) { results.Add(result); } } } } if (systemsToUpdate.Count > 0) { List <StarSystem> updatedSystems = dataProviderService.GetSystemsData(systemsToUpdate.Select(s => s.Key).ToArray()); // If the newly fetched star system is an empty object except (for the object name), reject it // Return old results when new results have been rejected List <string> systemsToRevert = new List <string>(); foreach (StarSystem starSystem in updatedSystems) { if (starSystem.systemAddress == null) { systemsToRevert.Add(starSystem.systemname); } } updatedSystems.RemoveAll(s => systemsToRevert.Contains(s.systemname)); foreach (string systemName in systemsToRevert) { results.Add(GetStarSystem(systemName, false)); } // Synchronize EDSM visits and comments updatedSystems = dataProviderService.syncFromStarMapService(updatedSystems); // Update properties that aren't synced from the server and that we want to preserve foreach (StarSystem updatedSystem in updatedSystems) { foreach (KeyValuePair <string, object> systemToUpdate in systemsToUpdate) { if (updatedSystem.systemname == systemToUpdate.Key) { Dictionary <string, object> oldStarSystem = (Dictionary <string, object>)systemToUpdate.Value; if (oldStarSystem != null) { // Carry over StarSystem properties that we want to preserve updatedSystem.totalbodies = JsonParsing.getOptionalInt(oldStarSystem, "discoverableBodies") ?? 0; // Carry over Body properties that we want to preserve (e.g. exploration data) oldStarSystem.TryGetValue("bodies", out object bodiesVal); List <Body> oldBodies = JsonConvert.DeserializeObject <List <Body> >(JsonConvert.SerializeObject(bodiesVal)); updatedSystem.PreserveBodyData(oldBodies, updatedSystem.bodies); // Carry over Faction properties that we want to preserve (e.g. reputation data) oldStarSystem.TryGetValue("factions", out object factionsVal); if (factionsVal != null) { List <Faction> oldFactions = JsonConvert.DeserializeObject <List <Faction> >(JsonConvert.SerializeObject(factionsVal)); if (oldFactions?.Count > 0) { foreach (var updatedFaction in updatedSystem.factions) { foreach (var oldFaction in oldFactions) { if (updatedFaction.name == oldFaction.name) { updatedFaction.myreputation = oldFaction.myreputation; } } } } } // No station data needs to be carried over at this time. } } } } // Update the `lastupdated` timestamps for the systems we have updated foreach (StarSystem starSystem in updatedSystems) { starSystem.lastupdated = DateTime.UtcNow; } // Add our updated systems to our results results.AddRange(updatedSystems); // Save changes to our star systems Instance.updateStarSystems(updatedSystems); } return(results); }
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 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()); }
private Body ParseStarMapBody(JObject body, string systemName) { // General items long? bodyId = (long?)body["bodyId"]; long? EDSMID = (long?)body["id"]; string bodyname = (string)body["name"]; BodyType bodyType = BodyType.FromName((string)body["type"]) ?? BodyType.None; decimal? distanceLs = (decimal?)body["distanceToArrival"]; // Light Seconds decimal? temperatureKelvin = (long?)body["surfaceTemperature"]; // Kelvin // Orbital characteristics decimal?orbitalPeriodDays = (decimal?)body["orbitalPeriod"]; // Days decimal?semimajoraxisLs = ConstantConverters.au2ls((decimal?)body["semiMajorAxis"]); // Light seconds decimal?eccentricity = (decimal?)body["orbitalEccentricity"]; decimal?orbitalInclinationDegrees = (decimal?)body["orbitalInclination"]; // Degrees decimal?periapsisDegrees = (decimal?)body["argOfPeriapsis"]; // Degrees decimal?rotationPeriodDays = (decimal?)body["rotationalPeriod"]; // Days decimal?axialTiltDegrees = (decimal?)body["axialTilt"]; // Degrees List <IDictionary <string, object> > parents = new List <IDictionary <string, object> >(); if (body["parents"] != null) { // Parent body types and IDs parents = body["parents"].ToObject <List <IDictionary <string, object> > >() ?? new List <IDictionary <string, object> >(); } List <Ring> rings = new List <Ring>(); if ((JArray)body["rings"] != null || (JArray)body["belts"] != null) { var ringsData = body["rings"] ?? body["belts"]; if (ringsData != null) { foreach (JObject ring in ringsData) { rings.Add(new Ring( (string)ring["name"], RingComposition.FromName((string)ring["type"]), (decimal)ring["mass"], (decimal)ring["innerRadius"], (decimal)ring["outerRadius"] )); } } } if ((string)body["type"] == "Star") { // Star-specific items string stellarclass = ((string)body["subType"]).Split(' ')[0]; // Splits "B (Blue-White) Star" to "B" int? stellarsubclass = null; string endOfStellarClass = stellarclass.ToCharArray().ElementAt(stellarclass.Length - 1).ToString(); if (int.TryParse(endOfStellarClass, out int subclass)) { // If our stellarclass ends in a number, we need to separate the class from the subclass stellarsubclass = subclass; stellarclass = stellarclass.Replace(endOfStellarClass, ""); } long? ageMegaYears = (long?)body["age"]; // Age in megayears string luminosityclass = (string)body["luminosity"]; decimal?absolutemagnitude = (decimal?)body["absoluteMagnitude"]; decimal?stellarMass = (decimal?)body["solarMasses"]; decimal?solarradius = (decimal?)body["solarRadius"]; decimal radiusKm = (decimal)(solarradius != null ? solarradius * Constants.solarRadiusMeters / 1000 : null); Body Body = new Body(bodyname, bodyId, parents, distanceLs, stellarclass, stellarsubclass, stellarMass, radiusKm, absolutemagnitude, ageMegaYears, temperatureKelvin, luminosityclass, semimajoraxisLs, eccentricity, orbitalInclinationDegrees, periapsisDegrees, orbitalPeriodDays, rotationPeriodDays, axialTiltDegrees, rings, true, false, systemName, null) { EDSMID = EDSMID }; DateTime updatedAt = JsonParsing.getDateTime("updateTime", body); Body.updatedat = updatedAt == null ? null : (long?)Dates.fromDateTimeToSeconds(updatedAt); return(Body); } if ((string)body["type"] == "Planet") { // Planet and moon specific items PlanetClass planetClass = PlanetClass.FromName((string)body["subType"]) ?? PlanetClass.None; bool? tidallylocked = (bool?)body["rotationalPeriodTidallyLocked"] ?? false; bool? landable = (bool?)body["isLandable"]; decimal? gravity = (decimal?)body["gravity"]; // G's decimal? earthmass = (decimal?)body["earthMasses"]; decimal? radiusKm = (decimal?)body["radius"]; // Kilometers TerraformState terraformState = TerraformState.FromName((string)body["terraformingState"]) ?? TerraformState.NotTerraformable; Volcanism volcanism = null; if ((string)body["volcanismType"] != null) { volcanism = Volcanism.FromName((string)body["volcanismType"]); } List <AtmosphereComposition> atmosphereCompositions = new List <AtmosphereComposition>(); if (body["atmosphereComposition"] is JObject) { var compositions = body["atmosphereComposition"].ToObject <Dictionary <string, decimal?> >(); foreach (KeyValuePair <string, decimal?> compositionKV in compositions) { string compositionName = compositionKV.Key; decimal?share = compositionKV.Value; if (compositionName != null && share != null) { atmosphereCompositions.Add(new AtmosphereComposition(compositionName, (decimal)share)); } } if (atmosphereCompositions.Count > 0) { atmosphereCompositions = atmosphereCompositions.OrderByDescending(x => x.percent).ToList(); } } decimal? pressureAtm = (decimal?)body["surfacePressure"]; AtmosphereClass atmosphereClass = null; if (((string)body["subType"]).Contains("gas giant") && (string)body["atmosphereType"] == "No atmosphere") { // EDSM classifies any body with an empty string atmosphere property as "No atmosphere". // However, gas giants also receive an empty string. Fix it, since gas giants have atmospheres. atmosphereClass = AtmosphereClass.FromEDName("GasGiant"); } else { atmosphereClass = AtmosphereClass.FromName((string)body["atmosphereType"]); } List <SolidComposition> solidCompositions = new List <SolidComposition>(); if (body["solidComposition"] is JObject) { var compositions = body["solidComposition"].ToObject <Dictionary <string, decimal?> >(); foreach (KeyValuePair <string, decimal?> compositionKV in compositions) { string composition = compositionKV.Key; decimal?share = compositionKV.Value; if (composition != null && share != null) { solidCompositions.Add(new SolidComposition(composition, (decimal)share)); } } if (solidCompositions.Count > 0) { solidCompositions = solidCompositions.OrderByDescending(x => x.percent).ToList(); } } List <MaterialPresence> materials = new List <MaterialPresence>(); if (body["materials"] is JObject) { var materialsData = body["materials"].ToObject <Dictionary <string, decimal?> >(); foreach (KeyValuePair <string, decimal?> materialKV in materialsData) { Material material = Material.FromName(materialKV.Key); decimal? amount = materialKV.Value; if (material != null && amount != null) { materials.Add(new MaterialPresence(material, (decimal)amount)); } } if (materials.Count > 0) { materials = materials.OrderByDescending(o => o.percentage).ToList(); } } ReserveLevel reserveLevel = ReserveLevel.FromName((string)body["reserveLevel"]) ?? ReserveLevel.None; DateTime updatedAt = JsonParsing.getDateTime("updateTime", body); Body Body = new Body(bodyname, bodyId, parents, distanceLs, tidallylocked, terraformState, planetClass, atmosphereClass, atmosphereCompositions, volcanism, earthmass, radiusKm, (decimal)gravity, temperatureKelvin, pressureAtm, landable, materials, solidCompositions, semimajoraxisLs, eccentricity, orbitalInclinationDegrees, periapsisDegrees, orbitalPeriodDays, rotationPeriodDays, axialTiltDegrees, rings, reserveLevel, true, true, systemName, null) { EDSMID = EDSMID, updatedat = updatedAt == null ? null : (long?)Dates.fromDateTimeToSeconds(updatedAt) }; return(Body); } return(null); }
internal static RepositoryDescription FromJson(JObject json, TraceContext trace, Uri documentRoot) { Guard.NotNull(json, "json"); Guard.NotNull(trace, "trace"); using (trace.EnterExit()) { // Read the version field int majorVersion = 0; var majorVersionToken = json["version"]; if (majorVersionToken != null && majorVersionToken.Type != JTokenType.Null) { if (majorVersionToken.Type != JTokenType.Integer) { trace.JsonParseWarning( majorVersionToken, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidVersion, majorVersionToken.ToDisplayString())); } else { majorVersion = majorVersionToken.Value <int>(); if (majorVersion < 0) { trace.JsonParseWarning( majorVersionToken, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidVersion, majorVersion)); majorVersion = 0; } } } else { trace.JsonParseWarning( json, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "version")); } var version = new Version(majorVersion, 0); // Read mirrors/alternates // TODO: Remove old "alternates" name var mirrorsToken = json["mirrors"] ?? json["alternates"]; IEnumerable <Uri> mirrors; if (mirrorsToken != null && mirrorsToken.Type != JTokenType.Null) { if (mirrorsToken.Type != JTokenType.Array) { trace.JsonParseWarning( mirrorsToken, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidMirrors, mirrorsToken.ToDisplayString())); mirrors = Enumerable.Empty <Uri>(); } else { mirrors = JsonParsing.ParseUrlArray((JArray)mirrorsToken, trace, documentRoot, Strings.RepositoryDescription_InvalidMirrorUrl); } } else { trace.JsonParseWarning( json, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "mirrors")); mirrors = Enumerable.Empty <Uri>(); } // Read services var servicesToken = json["services"]; IEnumerable <ServiceDescription> services; if (servicesToken != null && servicesToken.Type != JTokenType.Null) { if (servicesToken.Type != JTokenType.Object) { trace.JsonParseWarning( mirrorsToken, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_InvalidServices, servicesToken.ToDisplayString())); services = Enumerable.Empty <ServiceDescription>(); } else { services = JsonParsing.ParseUrlDictionary(json.Value <JObject>("services"), trace, documentRoot, Strings.RepositoryDescription_InvalidServiceUrl).Select(pair => new ServiceDescription(pair.Key, pair.Value)); } } else { trace.JsonParseWarning( json, String.Format(CultureInfo.CurrentCulture, Strings.RepositoryDescription_MissingExpectedProperty, "services")); services = Enumerable.Empty <ServiceDescription>(); } // Create the object! return(new RepositoryDescription(version, mirrors, services)); } }