diff --git a/EDDB/API.cs b/EDDB/API.cs index bddb66f..ea350bb 100644 --- a/EDDB/API.cs +++ b/EDDB/API.cs @@ -1,20 +1,29 @@ using System; using System.IO; using System.Net; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace NonaBGS.EDDB { public class API { private static readonly string EDDB_SYSTEMS_ARCHIVE = "https://eddb.io/archive/v6/systems_populated.json"; + private static readonly string EDDB_STATIONS_ARCHIVE = "https://eddb.io/archive/v6/stations.json"; + private string cache_folder = null; - private readonly WebClient client = new WebClient(); private string systems_file = null; + private string stations_file = null; + private string stations_file_short = null; public delegate void DatabaseAvailableDelegate(); public event DatabaseAvailableDelegate SystemsAvailable; + public event DatabaseAvailableDelegate StationsAvailable; public string SystemsFile => systems_file; + public string StationsFile => stations_file; + public string StationsFileShort => stations_file_short; public string Cache { get => cache_folder; @@ -28,19 +37,70 @@ namespace NonaBGS.EDDB { private void Initialise(string cache_folder) { this.cache_folder = cache_folder; systems_file = Path.Combine(this.cache_folder, "systems_populated.json"); - client.DownloadDataCompleted += Client_DownloadDataCompleted; + stations_file = Path.Combine(this.cache_folder, "stations.json"); + stations_file_short = Path.Combine(this.cache_folder, "stations_short.json"); } private void DownloadFile(string url, string file, DatabaseAvailableDelegate notifier) { + WebClient client = new WebClient(); + client.DownloadDataCompleted += Client_DownloadDataCompleted; client.DownloadFileAsync(new Uri(url), file, notifier); } + private void TranslateStations() { + if (!HaveStationsFile) { + return; + } + + Dictionary> systems = new Dictionary>(); + + using (var str = new StreamReader(StationsFile)) { + using (var reader = new JsonTextReader(str)) { + JArray obj = (JArray)JToken.ReadFrom(reader); + + + foreach (JObject child in obj.Children()) { + int system_id = child.Value("system_id"); + string name = child.Value("name"); + + if (!systems.ContainsKey(system_id)) { + systems.Add(system_id, new List()); + } + + systems[system_id].Add(name); + } + } + } + + JObject short_stations = new JObject(); + + foreach(int ids in systems.Keys) { + JArray station_names = new JArray(); + foreach(string system in systems[ids]) { + station_names.Add(system); + } + short_stations.Add(ids.ToString(), station_names); + } + + using (var outstr = new StreamWriter(stations_file_short)) { + using (var jwriter = new JsonTextWriter(outstr)) { + short_stations.WriteTo(jwriter); + } + } + } + public void Download(bool force) { if (!HaveSystemsFile || force) { DownloadFile(EDDB_SYSTEMS_ARCHIVE, systems_file, SystemsAvailable); } else if (HaveSystemsFile) { SystemsAvailable?.Invoke(); } + + if (!HaveStationsFile || force) { + DownloadFile(EDDB_STATIONS_ARCHIVE, stations_file, StationsAvailable); + } else if (HaveStationsFile) { + StationsAvailable?.Invoke(); + } } public void Download() { @@ -51,6 +111,14 @@ namespace NonaBGS.EDDB { get { return systems_file != null && File.Exists(systems_file); } } + public bool HaveStationsFile { + get { return stations_file != null && File.Exists(stations_file); } + } + + public bool HaveStationsFileShort { + get { return stations_file_short != null && File.Exists(stations_file_short); } + } + public PopulatedSystems MakePopulatedSystems() { if (!HaveSystemsFile) { throw new InvalidOperationException("no local systems file downloaded"); @@ -59,6 +127,18 @@ namespace NonaBGS.EDDB { return PopulatedSystems.FromFile(SystemsFile); } + public Stations MakeStations() { + if (!HaveStationsFile) { + throw new InvalidOperationException("no local systems file downloaded"); + } + + if (!HaveStationsFileShort) { + TranslateStations(); + } + + return Stations.FromFile(StationsFileShort); + } + private void Client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e) { DatabaseAvailableDelegate notifier = e.UserState as DatabaseAvailableDelegate; notifier?.Invoke(); diff --git a/EDDB/PopulatedSystems.cs b/EDDB/PopulatedSystems.cs index 7a3fa79..af3aa94 100644 --- a/EDDB/PopulatedSystems.cs +++ b/EDDB/PopulatedSystems.cs @@ -1,6 +1,6 @@ using System.IO; using System.Linq; -using System; +using System.Collections.Generic; using System.Globalization; using Newtonsoft.Json.Linq; @@ -9,6 +9,7 @@ namespace NonaBGS.EDDB { private string json_file = null; private JArray root = null; private string[] system_names = null; + private Dictionary to_id; public static PopulatedSystems FromFile(string file) { PopulatedSystems pop = new PopulatedSystems(); @@ -16,10 +17,21 @@ namespace NonaBGS.EDDB { pop.json_file = file; pop.root = JArray.Parse(content); + pop.Initialise(); return pop; } + private void Initialise() { + MakeSystemNames(); + + to_id = root.ToDictionary(x => x.Value("name"), x => x.Value("id")); + } + + public int ToId(string name) { + return to_id.First(x => string.Compare(x.Key, name, true) == 0).Value; + } + private void MakeSystemNames() { if (root == null) { throw new InvalidDataException("no JSON loaded"); diff --git a/EDDB/Stations.cs b/EDDB/Stations.cs new file mode 100644 index 0000000..c4d5355 --- /dev/null +++ b/EDDB/Stations.cs @@ -0,0 +1,51 @@ +using System.Globalization; +using System.Collections.Generic; +using System.Linq; +using System.IO; +using Newtonsoft.Json.Linq; + +namespace NonaBGS.EDDB { + public class Stations { + private JObject root = null; + private Dictionary> by_system_id = null; + + public JObject JSON => root; + + private Stations() { + } + + private void Initialise() { + by_system_id = new Dictionary>(); + foreach (var station in root.Properties()) { + int id = int.Parse(station.Name); + var names = root.Value(id.ToString()).Values().ToArray(); + + if (!by_system_id.ContainsKey(id)) { + by_system_id[id] = new List(); + } + + by_system_id[id].AddRange(names); + } + } + + public static Stations FromFile(string filename) { + string alltext = File.ReadAllText(filename); + Stations stations = new Stations { + root = JObject.Parse(alltext), + }; + stations.Initialise(); + + return stations; + } + + public string[] StationNamesBySystemId(int systemid, string filter) { + if (!by_system_id.ContainsKey(systemid)) { + return new string[0]; + } + return by_system_id[systemid] + .Where(x => CultureInfo.InvariantCulture.CompareInfo.IndexOf(x, filter, CompareOptions.IgnoreCase) > -1) + .ToArray() + ; + } + } +} diff --git a/Journal/MissionCompletedEntry.cs b/Journal/MissionCompletedEntry.cs index 7f48752..fecae89 100644 --- a/Journal/MissionCompletedEntry.cs +++ b/Journal/MissionCompletedEntry.cs @@ -28,13 +28,16 @@ namespace NonaBGS.Journal { { "Mission_Delivery_Retreat_name", "Delivery (Retreat)" }, { "Mission_Delivery_name", "Delivery" }, { "Mission_Delivery_Agriculture_name", "Delivery (Agriculture)" }, + { "Mission_Delivery_RankEmp_name", "Delivery (Imperial Rank)" }, { "Mission_HackMegaship_name", "Hack Megaship" }, { "Mission_MassacreWing_name", "Massacre (Wing)" }, { "Mission_OnFoot_Onslaught_MB_name", "On Foot Onslaught" }, + { "Mission_OnFoot_Onslaught_Offline_MB_name", "On Foot Onslaught (Offline)" }, { "Mission_OnFoot_RebootRestore_MB_name", "On Foot Reboot/Restore" }, { "Mission_OnFoot_Reboot_MB_name", "On Foot Reboot" }, { "Mission_Rescue_Planet_name", "Planet Rescue" }, { "Mission_Salvage_name", "Salvage" }, + { "MISSION_Salvage_CivilUnrest_name", "Salvage (Civil Unrest)" }, { "MISSION_Salvage_Illegal_name", "Salvage (Illegal)" }, { "MISSION_Salvage_Retreat_name", "Salvage (Retreat)" }, { "MISSION_Salvage_Expansion_name", "Salvage (Expansion)" }, diff --git a/MainWindow.xaml b/MainWindow.xaml index 4cd1423..1010bd5 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -32,7 +32,7 @@