Example #1
0
        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);
        }
Example #2
0
 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);
             }
         }
     }
 }
Example #3
0
        public Status ParseStatusEntry(string line)
        {
            Status status = new Status();

            try
            {
                Match match = JsonRegex.Match(line);
                if (match.Success)
                {
                    IDictionary <string, object> data = Deserializtion.DeserializeData(line);

                    // Every status event has a timestamp field
                    status.timestamp = DateTime.UtcNow;
                    try
                    {
                        status.timestamp = JsonParsing.getDateTime("timestamp", data);
                    }
                    catch
                    {
                        Logging.Warn("Status without timestamp; using current time");
                    }

                    status.flags = (Status.Flags)(JsonParsing.getOptionalLong(data, "Flags") ?? 0);
                    if (status.flags == Status.Flags.None)
                    {
                        // No flags are set. We aren't in game.
                        return(status);
                    }

                    data.TryGetValue("Pips", out object val);
                    List <long> pips = ((List <object>)val)?.Cast <long>()?.ToList(); // The 'TryGetValue' function returns these values as type 'object<long>'
                    status.pips_sys = pips != null ? ((decimal?)pips[0] / 2) : null;  // Set system pips (converting from half pips)
                    status.pips_eng = pips != null ? ((decimal?)pips[1] / 2) : null;  // Set engine pips (converting from half pips)
                    status.pips_wea = pips != null ? ((decimal?)pips[2] / 2) : null;  // Set weapon pips (converting from half pips)

                    status.firegroup = JsonParsing.getOptionalInt(data, "FireGroup");
                    int?gui_focus = JsonParsing.getOptionalInt(data, "GuiFocus");
                    switch (gui_focus)
                    {
                    case 0:     // No focus
                    {
                        status.gui_focus = "none";
                        break;
                    }

                    case 1:     // InternalPanel (right hand side)
                    {
                        status.gui_focus = "internal panel";
                        break;
                    }

                    case 2:     // ExternalPanel (left hand side)
                    {
                        status.gui_focus = "external panel";
                        break;
                    }

                    case 3:     // CommsPanel (top)
                    {
                        status.gui_focus = "communications panel";
                        break;
                    }

                    case 4:     // RolePanel (bottom)
                    {
                        status.gui_focus = "role panel";
                        break;
                    }

                    case 5:     // StationServices
                    {
                        status.gui_focus = "station services";
                        break;
                    }

                    case 6:     // GalaxyMap
                    {
                        status.gui_focus = "galaxy map";
                        break;
                    }

                    case 7:     // SystemMap
                    {
                        status.gui_focus = "system map";
                        break;
                    }

                    case 8:     // Orrery
                    {
                        status.gui_focus = "orrery";
                        break;
                    }

                    case 9:     // FSS mode
                    {
                        status.gui_focus = "fss mode";
                        break;
                    }

                    case 10:     // SAA mode
                    {
                        status.gui_focus = "saa mode";
                        break;
                    }

                    case 11:     // Codex
                    {
                        status.gui_focus = "codex";
                        break;
                    }
                    }
                    status.latitude  = JsonParsing.getOptionalDecimal(data, "Latitude");
                    status.longitude = JsonParsing.getOptionalDecimal(data, "Longitude");
                    status.altitude  = JsonParsing.getOptionalDecimal(data, "Altitude");
                    status.heading   = JsonParsing.getOptionalDecimal(data, "Heading");
                    if (data.TryGetValue("Fuel", out object fuelData))
                    {
                        if (fuelData is IDictionary <string, object> fuelInfo)
                        {
                            status.fuelInTanks     = JsonParsing.getOptionalDecimal(fuelInfo, "FuelMain");
                            status.fuelInReservoir = JsonParsing.getOptionalDecimal(fuelInfo, "FuelReservoir");
                        }
                    }
                    status.cargo_carried = (int?)JsonParsing.getOptionalDecimal(data, "Cargo");
                    status.legalStatus   = LegalStatus.FromEDName(JsonParsing.getString(data, "LegalState")) ?? LegalStatus.Clean;
                    status.bodyname      = JsonParsing.getString(data, "BodyName");
                    status.planetradius  = JsonParsing.getOptionalDecimal(data, "PlanetRadius");

                    // Calculated data
                    SetFuelExtras(status);
                    SetSlope(status);

                    return(status);
                }
            }
            catch (Exception ex)
            {
                Logging.Warn("Failed to parse Status.json line: " + ex.ToString());
                Logging.Error("", ex);
            }
            return(null);
        }
Example #4
0
        public static Status ParseStatusEntry(string line)
        {
            Status status = new Status();

            try
            {
                Match match = JsonRegex.Match(line);
                if (match.Success)
                {
                    IDictionary <string, object> data = Deserializtion.DeserializeData(line);

                    // Every status event has a timestamp field
                    if (data.ContainsKey("timestamp"))
                    {
                        if (data["timestamp"] is DateTime)
                        {
                            status.timestamp = ((DateTime)data["timestamp"]).ToUniversalTime();
                        }
                        else
                        {
                            status.timestamp = DateTime.Parse(JsonParsing.getString(data, "timestamp")).ToUniversalTime();
                        }
                    }
                    else
                    {
                        Logging.Warn("Status event without timestamp; using current time");
                    }

                    status.flags = (Status.Flags)(JsonParsing.getOptionalLong(data, "Flags") ?? 0);
                    if (status.flags == Status.Flags.None)
                    {
                        // No flags are set. We aren't in game.
                        return(status);
                    }

                    object val;
                    data.TryGetValue("Pips", out val);
                    List <long> pips = ((List <object>)val)?.Cast <long>()?.ToList(); // The 'TryGetValue' function returns these values as type 'object<long>'
                    status.pips_sys = pips != null ? ((decimal?)pips[0] / 2) : null;  // Set system pips (converting from half pips)
                    status.pips_eng = pips != null ? ((decimal?)pips[1] / 2) : null;  // Set engine pips (converting from half pips)
                    status.pips_wea = pips != null ? ((decimal?)pips[2] / 2) : null;  // Set weapon pips (converting from half pips)

                    status.firegroup = JsonParsing.getOptionalInt(data, "FireGroup");
                    int?gui_focus = JsonParsing.getOptionalInt(data, "GuiFocus");
                    switch (gui_focus)
                    {
                    case 0:     // No focus
                    {
                        status.gui_focus = "none";
                        break;
                    }

                    case 1:     // InternalPanel (right hand side)
                    {
                        status.gui_focus = "internal panel";
                        break;
                    }

                    case 2:     // ExternalPanel (left hand side)
                    {
                        status.gui_focus = "external panel";
                        break;
                    }

                    case 3:     // CommsPanel (top)
                    {
                        status.gui_focus = "communications panel";
                        break;
                    }

                    case 4:     // RolePanel (bottom)
                    {
                        status.gui_focus = "role panel";
                        break;
                    }

                    case 5:     // StationServices
                    {
                        status.gui_focus = "station services";
                        break;
                    }

                    case 6:     // GalaxyMap
                    {
                        status.gui_focus = "galaxy map";
                        break;
                    }

                    case 7:     // SystemMap
                    {
                        status.gui_focus = "system map";
                        break;
                    }
                    }
                    status.latitude  = JsonParsing.getOptionalDecimal(data, "Latitude");
                    status.longitude = JsonParsing.getOptionalDecimal(data, "Longitude");
                    status.altitude  = JsonParsing.getOptionalDecimal(data, "Altitude");
                    status.heading   = JsonParsing.getOptionalDecimal(data, "Heading");

                    return(status);
                }
            }
            catch (Exception ex)
            {
                Logging.Warn("Failed to parse Status.json line: " + ex.ToString());
                Logging.Error(ex);
            }
            return(status = null);
        }
Example #5
0
        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);
        }