public void insertSystems(string jsonFilePath) { using (var file = new StreamReader(jsonFilePath)) { using (var con = SimpleDbConnection()) { con.Open(); using (var transaction = con.BeginTransaction()) { using (var cmd = new SQLiteCommand(con)) { cmd.CommandText = INSERT_SYSTEM_SQL; cmd.Prepare(); string line; while ((line = file.ReadLine()) != null) { IDictionary <string, object> data = Deserializtion.DeserializeData(line); cmd.Parameters.AddWithValue("@id", data["id"]); cmd.Parameters.AddWithValue("@edsm_id", data["edsm_id"]); cmd.Parameters.AddWithValue("@name", data["name"]); cmd.Parameters.AddWithValue("@x", data["x"]); cmd.Parameters.AddWithValue("@y", data["y"]); cmd.Parameters.AddWithValue("@z", data["z"]); cmd.ExecuteNonQuery(); } } transaction.Commit(); } con.Close(); } file.Close(); } }
private static List <StarSystem> PreserveUnsyncedProperties(List <StarSystem> updatedSystems, List <DatabaseStarSystem> systemsToUpdate) { if (updatedSystems is null) { return(new List <StarSystem>()); } foreach (StarSystem updatedSystem in updatedSystems) { foreach (DatabaseStarSystem systemToUpdate in systemsToUpdate) { if (updatedSystem.systemname == systemToUpdate.systemName) { IDictionary <string, object> oldStarSystem = Deserializtion.DeserializeData(systemToUpdate.systemJson); if (oldStarSystem != null) { PreserveSystemProperties(updatedSystem, oldStarSystem); PreserveBodyProperties(updatedSystem, oldStarSystem); PreserveFactionProperties(updatedSystem, oldStarSystem); // No station data needs to be carried over at this time. } } } } return(updatedSystems); }
private void handleRawEvent(Event theEvent) { IDictionary <string, object> data = Deserializtion.DeserializeData(theEvent.raw); // Need to strip a number of entries data.Remove("CockpitBreach"); data.Remove("BoostUsed"); data.Remove("FuelLevel"); data.Remove("FuelUsed"); data.Remove("JumpDist"); // Need to remove any keys ending with _Localised data = data.Where(x => !x.Key.EndsWith("_Localised")).ToDictionary(x => x.Key, x => x.Value); // Can only proceed if we know our current system // Need to add StarSystem to scan events - can only do so if we have the data if (theEvent is BeltScannedEvent || theEvent is StarScannedEvent || theEvent is BodyScannedEvent) { if (systemName == null || systemX == null || systemY == null || systemZ == null) { Logging.Debug("Missing current starsystem information, cannot send message to EDDN"); return; } data.Add("StarSystem", systemName); } // Need to add StarPos to all events that don't already have them if (!data.ContainsKey("StarPos")) { if (systemName == null || systemX == null || systemY == null || systemZ == null) { Logging.Debug("Missing current starsystem information, cannot send message to EDDN"); return; } IList <decimal> starpos = new List <decimal> { systemX.Value, systemY.Value, systemZ.Value }; data.Add("StarPos", starpos); } EDDNBody body = new EDDNBody { header = generateHeader(), #if DEBUG // Use the test schema while in development. schemaRef = "https://eddn.edcd.io/schemas/journal/1/test", #else schemaRef = "https://eddn.edcd.io/schemas/journal/1" + (EDDI.Instance.inBeta ? "/test" : ""), #endif message = data }; sendMessage(body); }
public MicroResourceInfo FromFile(string filename = null) { var inventory = new MicroResourceInfo(); string json = Files.FromSavedGames(filename); if (!string.IsNullOrEmpty(json)) { var data = Deserializtion.DeserializeData(json); inventory = FromData(data); } return(inventory); }
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 void handleRawEvent(Event theEvent) { IDictionary <string, object> data = Deserializtion.DeserializeData(theEvent.raw); // Need to strip a number of entries data.Remove("CockpitBreach"); data.Remove("BoostUsed"); data.Remove("FuelLevel"); data.Remove("FuelUsed"); data.Remove("JumpDist"); // Need to remove any keys ending with _Localised data = data.Where(x => !x.Key.EndsWith("_Localised")).ToDictionary(x => x.Key, x => x.Value); // Need to add StarSystem to scan events if (theEvent is StarScannedEvent || theEvent is BodyScannedEvent) { data.Add("StarSystem", EDDI.Instance.CurrentStarSystem.name); } // Need to add StarPos to all events that don't already have them if (!data.ContainsKey("StarPos")) { if (EDDI.Instance.CurrentStarSystem == null || EDDI.Instance.CurrentStarSystem.x == null) { Logging.Debug("Missing current starsystem information, cannot send message to EDDN"); } IList <decimal> starpos = new List <decimal>(); starpos.Add((decimal)EDDI.Instance.CurrentStarSystem.x); starpos.Add((decimal)EDDI.Instance.CurrentStarSystem.y); starpos.Add((decimal)EDDI.Instance.CurrentStarSystem.z); data.Add("StarPos", starpos); } EDDNBody body = new EDDNBody(); body.header = generateHeader(); body.schemaRef = "http://schemas.elite-markets.net/eddn/journal/1"; body.message = data; sendMessage(body); }
public void TestMicroResourceInfo() { var json = TestBase.DeserializeJsonResource <string>(Resources.shipLocker); var data = Deserializtion.DeserializeData(json); var info = new MicroResourceInfo().FromData(data); Assert.AreEqual(38, info.Items.Count); Assert.AreEqual("WeaponSchematic", info.Items[0].edname); Assert.AreEqual(1, info.Items[0].amount); Assert.AreEqual("Item", info.Items[0].microResource.Category.edname); Assert.AreEqual(770652507, info.Items[0].missionId); Assert.AreEqual(0, info.Items[0].ownerId); Assert.AreEqual(null, info.Items[0].price); Assert.AreEqual(33, info.Components.Count); Assert.AreEqual("Graphene", info.Components[1].edname); Assert.AreEqual(55, info.Components[1].amount); Assert.AreEqual("Component", info.Components[1].microResource.Category.edname); Assert.AreEqual(null, info.Components[1].missionId); Assert.AreEqual(0, info.Components[1].ownerId); Assert.AreEqual(null, info.Components[1].price); Assert.AreEqual(6, info.Consumables.Count); Assert.AreEqual("HealthPack", info.Consumables[0].edname); Assert.AreEqual(56, info.Consumables[0].amount); Assert.AreEqual("Consumable", info.Consumables[0].microResource.Category.edname); Assert.AreEqual(null, info.Consumables[0].missionId); Assert.AreEqual(0, info.Consumables[0].ownerId); Assert.AreEqual(null, info.Consumables[0].price); Assert.AreEqual(70, info.Data.Count); Assert.AreEqual("InternalCorrespondence", info.Data[0].edname); Assert.AreEqual(5, info.Data[0].amount); Assert.AreEqual("Data", info.Data[0].microResource.Category.edname); Assert.AreEqual(null, info.Data[0].missionId); Assert.AreEqual(0, info.Data[0].ownerId); Assert.AreEqual(null, info.Data[0].price); }
public void insertStations(string jsonFilePath) { using (var file = new StreamReader(jsonFilePath)) { using (var con = SimpleDbConnection()) { con.Open(); using (var transaction = con.BeginTransaction()) { using (var cmd = new SQLiteCommand(con)) { cmd.CommandText = INSERT_STATION_SQL; cmd.Prepare(); string line; while ((line = file.ReadLine()) != null) { IDictionary <string, object> data = Deserializtion.DeserializeData(line); cmd.Parameters.AddWithValue("@id", data["id"]); cmd.Parameters.AddWithValue("@system_id", data["system_id"]); cmd.Parameters.AddWithValue("@name", data["name"]); var distance = data["distance_to_star"]; if (distance == null) { distance = 1000; } cmd.Parameters.AddWithValue("@distance", distance); cmd.ExecuteNonQuery(); } } transaction.Commit(); } con.Close(); } file.Close(); } }
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 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); } } } }
public StarSystem GetStarSystem(string name, bool refreshIfOutdated = true) { if (!File.Exists(DbFile)) { return(null); } StarSystem result = null; try { bool needToUpdate = false; using (var con = SimpleDbConnection()) { con.Open(); using (var cmd = new SQLiteCommand(con)) { cmd.CommandText = SELECT_BY_NAME_SQL; cmd.Prepare(); cmd.Parameters.AddWithValue("@name", name); using (SQLiteDataReader rdr = cmd.ExecuteReader()) { if (rdr.Read()) { string data = rdr.GetString(2); // Old versions of the data could have a string "No volcanism" for volcanism. If so we remove it data = data.Replace(@"""No volcanism""", "null"); try { result = JsonConvert.DeserializeObject <StarSystem>(data); if (result == null) { Logging.Info("Failed to obtain system for " + name + " from the SQLiteRepository"); } if (result != null) { if (result.visits < 1) { // Old-style system; need to update result.visits = rdr.GetInt32(0); result.lastvisit = rdr.GetDateTime(1); needToUpdate = true; } if (result.lastupdated == null) { result.lastupdated = rdr.GetDateTime(4); } if (result.comment == null) { if (!rdr.IsDBNull(4)) { result.comment = rdr.GetString(4); } } } if (refreshIfOutdated && result.lastupdated < DateTime.UtcNow.AddHours(-1)) { // Data is stale StarSystem updatedResult = DataProviderService.GetSystemData(name); if (updatedResult.systemAddress == null && result.systemAddress != null) { // The "updated" data might be a basic system, empty except for the name. // If so, return the old result. return(result); } else { updatedResult.visits = result.visits; updatedResult.lastvisit = result.lastvisit; updatedResult.lastupdated = DateTime.UtcNow; result = updatedResult; needToUpdate = true; } } } catch (Exception) { Logging.Warn("Problem reading data for star system '" + name + "' from database, re-obtaining from source. "); try { result = DataProviderService.GetSystemData(name); // Recover data unique to the local user and database IDictionary <string, object> system = Deserializtion.DeserializeData(data); system.TryGetValue("visits", out object visitVal); result.visits = (int)(long)visitVal; system.TryGetValue("comment", out object commentVal); result.comment = (string)commentVal; system.TryGetValue("lastvisit", out object lastVisitVal); result.lastvisit = (DateTime?)lastVisitVal; result.lastupdated = DateTime.UtcNow; needToUpdate = true; } catch (Exception ex) { Logging.Warn("Problem obtaining data from source: " + ex); result = null; } } } } } } if (needToUpdate) { updateStarSystem(result); } } catch (SQLiteException) { Logging.Warn("Problem reading data for star system '" + name + "' from database, refreshing database and re-obtaining from source."); RecoverStarSystemDB(); GetStarSystem(name); } return(result); }
public List <StarSystem> GetStarSystems(string[] names, bool refreshIfOutdated = true) { if (!File.Exists(DbFile)) { return(null); } if (names.Count() == 0) { return(null); } List <StarSystem> results = new List <StarSystem>(); List <string> systemsToUpdate = new List <string>(); List <KeyValuePair <string, string> > dataSets = Instance.ReadStarSystems(names); foreach (KeyValuePair <string, string> kv in dataSets) { bool needToUpdate = false; StarSystem result = null; if (kv.Value != null && 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"); // 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("comment", out object commentVal); system.TryGetValue("lastupdated", out object lastUpdatedVal); system.TryGetValue("systemAddress", out object systemAddressVal); system.TryGetValue("EDSMID", out object edsmIdVal); string comment = (string)commentVal ?? ""; 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 systemsToUpdate.Add(name); } else { // Deserialize the old result result = DeserializeStarSystem(name, data, ref needToUpdate); if (result != null) { results.Add(result); } } } } if (systemsToUpdate.Count > 0) { List <StarSystem> updatedSystems = DataProviderService.GetSystemsData(systemsToUpdate.ToArray()); // If the newly fetched star system is an empty object except (for the object name), reject it 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)); // Return old results when new results have been rejected foreach (string systemName in systemsToRevert) { results.Add(GetStarSystem(systemName, false)); } // Synchronize EDSM visits and comments updatedSystems = DataProviderService.syncFromStarMapService(updatedSystems); // Add our updated systems to our results results.AddRange(updatedSystems); // Save changes to our star systems Instance.updateStarSystems(updatedSystems); } foreach (StarSystem starSystem in results) { starSystem.lastupdated = DateTime.UtcNow; } return(results); }
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); }
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); } }
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); }
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); }
public List <StarSystem> GetStarSystems(string[] names, bool refreshIfOutdated = true) { if (!File.Exists(DbFile)) { return(null); } if (names.Count() == 0) { return(null); } List <StarSystem> results = new List <StarSystem>(); List <StarSystem> systemsToUpdate = new List <StarSystem>(); List <KeyValuePair <string, string> > dataSets = Instance.ReadStarSystems(names); foreach (KeyValuePair <string, string> kv in dataSets) { bool needToUpdate = false; StarSystem result = null; if (kv.Value != null && 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 = ((string)kv.Value)?.Replace(@"""No volcanism""", "null"); // 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("visits", out object visitVal); system.TryGetValue("comment", out object commentVal); system.TryGetValue("lastvisit", out object lastVisitVal); system.TryGetValue("lastupdated", out object lastUpdatedVal); system.TryGetValue("systemAddress", out object systemAddressVal); int visits = (int)(long)visitVal; string comment = (string)commentVal ?? ""; DateTime?lastvisit = (DateTime?)lastVisitVal; DateTime?lastupdated = (DateTime?)lastUpdatedVal; long? systemAddress = (long?)systemAddressVal; if (lastvisit == null || lastupdated == null || comment == "") { if (Instance.OldDataFormat(name, ref visits, comment, ref lastupdated, ref lastvisit)) { needToUpdate = true; } } if (refreshIfOutdated && lastupdated < DateTime.UtcNow.AddHours(-1)) { // Data is stale StarSystem updatedResult = DataProviderService.GetSystemData(name); if (updatedResult.systemAddress == null && systemAddress != null) { // The "updated" data might be a basic system, empty except for the name. If so, return the old result. updatedResult = DeserializeStarSystem(name, data, ref needToUpdate); } else { needToUpdate = true; } result = updatedResult; } else { // Data is fresh result = DeserializeStarSystem(name, data, ref needToUpdate); } result.visits = visits; result.comment = comment; result.lastvisit = lastvisit; result.lastupdated = DateTime.UtcNow; if (needToUpdate) { systemsToUpdate.Add(result); } } results.Add(result); } Instance.updateStarSystems(systemsToUpdate); return(results); }