diff --git a/ConsoleTestApp/App.config b/ConsoleTestApp/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/ConsoleTestApp/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ConsoleTestApp/ConsoleTestApp.csproj b/ConsoleTestApp/ConsoleTestApp.csproj
new file mode 100644
index 0000000..9b365ff
--- /dev/null
+++ b/ConsoleTestApp/ConsoleTestApp.csproj
@@ -0,0 +1,58 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {1B0953DC-3CE0-4982-91C2-0F59635FFA61}
+ Exe
+ ConsoleTestApp
+ ConsoleTestApp
+ v4.6.1
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {160c10d6-f300-4766-8120-58f0bc4c427a}
+ ED-Router
+
+
+
+
\ No newline at end of file
diff --git a/ConsoleTestApp/Program.cs b/ConsoleTestApp/Program.cs
new file mode 100644
index 0000000..b267604
--- /dev/null
+++ b/ConsoleTestApp/Program.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Text;
+using ED_Router;
+
+namespace ConsolTestApp
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ /*
+ var Api = new SpanchApi();
+ var result = Api.PlotRoute("Kashyapa", "Sol", 48);
+
+ StringBuilder route = new StringBuilder();
+
+ foreach (var system in result.SystemJumps)
+ {
+ route.AppendLine(system.System);
+ }
+
+ Console.Write(route);*/
+
+ /*
+ var router = EdRouter.Instance;
+ router.Start = "Sol";
+ router.Destination = "Ao Shun";
+ router.Range = 48;
+ router.Efficiency = 60;
+
+ router.CalculateRoute();
+
+ Console.WriteLine("Start Sys: {0}", router.CurrentWaypoint);
+
+ router.NextWaypoint();
+ Console.WriteLine("Sys 1: {0}", router.CurrentWaypoint);
+
+ router.NextWaypoint();
+ Console.WriteLine("Sys 2: {0}", router.CurrentWaypoint);
+
+ router.NextWaypoint();
+ Console.WriteLine("Sys 3: {0}", router.CurrentWaypoint);
+
+ router.PreviousWaypoint();
+ Console.WriteLine("Sys 2: {0}", router.CurrentWaypoint);
+ Console.ReadLine();
+ */
+
+ //var l1 = JournalMonitor.GetLocaction("{ \"timestamp\":\"2018 - 03 - 17T20: 05:59Z\", \"event\":\"StartJump\", \"JumpType\":\"Hyperspace\", \"StarSystem\":\"Kyloarph IN-S d4-2021\", \"SystemAddress\":69449931411883, \"StarClass\":\"N\" }");
+ //var l2 = JournalMonitor.GetLocaction("{ \"timestamp\":\"2018-03-17T20:03:25Z\", \"event\":\"Location\", \"Docked\":false, \"StarSystem\":\"Kyloarph DB-X e1-5559\", \"SystemAddress\":23876836747476, \"StarPos\":[-7504.34375,-727.28125,21081.59375], \"SystemAllegiance\":\"\", \"SystemEconomy\":\"$economy_None;\", \"SystemEconomy_Localised\":\"n/v\", \"SystemGovernment\":\"$government_None;\", \"SystemGovernment_Localised\":\"n/v\", \"SystemSecurity\":\"$GAlAXY_MAP_INFO_state_anarchy;\", \"SystemSecurity_Localised\":\"Anarchie\", \"Population\":0, \"Body\":\"Kyloarph DB-X e1-5559 1\", \"BodyID\":1, \"BodyType\":\"Planet\" }");
+ var l3 = JournalMonitor.GetLocaction("{ \"timestamp\":\"2018-03-17T20:09:52Z\", \"event\":\"Scan\", \"ScanType\":\"Detailed\", \"BodyName\":\"Kyloarph PT-Q d5-3862 A 1\", \"BodyID\":7, \"Parents\":[ {\"Star\":1}, {\"Null\":0} ], \"DistanceFromArrivalLS\":239.561920, \"TidalLock\":false, \"TerraformState\":\"\", \"PlanetClass\":\"High metal content body\", \"Atmosphere\":\"thin sulfur dioxide atmosphere\", \"AtmosphereType\":\"SulphurDioxide\", \"AtmosphereComposition\":[ { \"Name\":\"SulphurDioxide\", \"Percent\":100.000000 } ], \"Volcanism\":\"\", \"MassEM\":0.134808, \"Radius\":3276403.500000, \"SurfaceGravity\":5.005291, \"SurfaceTemperature\":378.430450, \"SurfacePressure\":359.917908, \"Landable\":false, \"Composition\":{ \"Ice\":0.000000, \"Rock\":0.672977, \"Metal\":0.327023 }, \"SemiMajorAxis\":71812833280.000000, \"Eccentricity\":0.000085, \"OrbitalInclination\":-0.000587, \"Periapsis\":246.785690, \"OrbitalPeriod\":10816627.000000, \"RotationPeriod\":208069.937500, \"AxialTilt\":-0.499019 }");
+
+
+ }
+ }
+}
diff --git a/ConsoleTestApp/Properties/AssemblyInfo.cs b/ConsoleTestApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c198308
--- /dev/null
+++ b/ConsoleTestApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("ConsoleTestApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ConsoleTestApp")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("1b0953dc-3ce0-4982-91c2-0f59635ffa61")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ED-Router.UI.Desktop/App.config b/ED-Router.UI.Desktop/App.config
new file mode 100644
index 0000000..5bb33fd
--- /dev/null
+++ b/ED-Router.UI.Desktop/App.config
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/App.xaml b/ED-Router.UI.Desktop/App.xaml
new file mode 100644
index 0000000..d9c04e5
--- /dev/null
+++ b/ED-Router.UI.Desktop/App.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/App.xaml.cs b/ED-Router.UI.Desktop/App.xaml.cs
new file mode 100644
index 0000000..73835f4
--- /dev/null
+++ b/ED-Router.UI.Desktop/App.xaml.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace ED_Router.UI.Desktop
+{
+ ///
+ /// Interaktionslogik für "App.xaml"
+ ///
+ public partial class App : Application
+ {
+ private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
+ {
+ MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
+ e.Handled = true;
+ }
+ }
+}
diff --git a/ED-Router.UI.Desktop/ED-Router.UI.Desktop.csproj b/ED-Router.UI.Desktop/ED-Router.UI.Desktop.csproj
new file mode 100644
index 0000000..b7a247e
--- /dev/null
+++ b/ED-Router.UI.Desktop/ED-Router.UI.Desktop.csproj
@@ -0,0 +1,132 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}
+ WinExe
+ ED_Router.UI.Desktop
+ ED-Router.UI.Desktop
+ v4.6.1
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\CommonServiceLocator.2.0.3\lib\net45\CommonServiceLocator.dll
+
+
+ ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.dll
+
+
+ ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.Extras.dll
+
+
+ ..\packages\MvvmLightLibs.5.4.1\lib\net45\GalaSoft.MvvmLight.Platform.dll
+
+
+ ..\packages\NHotkey.1.2.1\lib\net20\NHotkey.dll
+
+
+ ..\packages\NHotkey.Wpf.1.2.1\lib\net35\NHotkey.Wpf.dll
+
+
+
+
+ ..\packages\MvvmLightLibs.5.4.1\lib\net45\System.Windows.Interactivity.dll
+ True
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+ MainWindow.xaml
+ Code
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+ {160c10d6-f300-4766-8120-58f0bc4c427a}
+ ED-Router
+
+
+ {9d0fb9d4-345d-4874-b469-f5caec09ae91}
+ libspanch
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/MainWindow.xaml b/ED-Router.UI.Desktop/MainWindow.xaml
new file mode 100644
index 0000000..0efd746
--- /dev/null
+++ b/ED-Router.UI.Desktop/MainWindow.xaml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ED-Router.UI.Desktop/MainWindow.xaml.cs b/ED-Router.UI.Desktop/MainWindow.xaml.cs
new file mode 100644
index 0000000..d3db78f
--- /dev/null
+++ b/ED-Router.UI.Desktop/MainWindow.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace ED_Router.UI.Desktop
+{
+ ///
+ /// Interaktionslogik für MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/ED-Router.UI.Desktop/Properties/AssemblyInfo.cs b/ED-Router.UI.Desktop/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d1c8410
--- /dev/null
+++ b/ED-Router.UI.Desktop/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("ED-Router.UI.Desktop")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ED-Router.UI.Desktop")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+//Um mit dem Erstellen lokalisierbarer Anwendungen zu beginnen, legen Sie
+//ImCodeVerwendeteKultur in der .csproj-Datei
+//in einer fest. Wenn Sie in den Quelldateien beispielsweise Deutsch
+//(Deutschland) verwenden, legen Sie auf \"de-DE\" fest. Heben Sie dann die Auskommentierung
+//des nachstehenden NeutralResourceLanguage-Attributs auf. Aktualisieren Sie "en-US" in der nachstehenden Zeile,
+//sodass es mit der UICulture-Einstellung in der Projektdatei übereinstimmt.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //Speicherort der designspezifischen Ressourcenwörterbücher
+ //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird,
+ // oder in den Anwendungsressourcen-Wörterbüchern nicht gefunden werden kann.)
+ ResourceDictionaryLocation.SourceAssembly //Speicherort des generischen Ressourcenwörterbuchs
+ //(wird verwendet, wenn eine Ressource auf der Seite nicht gefunden wird,
+ // designspezifischen Ressourcenwörterbuch nicht gefunden werden kann.)
+)]
+
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ED-Router.UI.Desktop/Properties/Resources.Designer.cs b/ED-Router.UI.Desktop/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..2f7d071
--- /dev/null
+++ b/ED-Router.UI.Desktop/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// Dieser Code wurde von einem Tool generiert.
+// Laufzeitversion: 4.0.30319.42000
+//
+// Änderungen an dieser Datei können fehlerhaftes Verhalten verursachen und gehen verloren, wenn
+// der Code neu generiert wird.
+//
+//------------------------------------------------------------------------------
+
+namespace ED_Router.UI.Desktop.Properties
+{
+
+
+ ///
+ /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+ ///
+ // Diese Klasse wurde von der StronglyTypedResourceBuilder-Klasse
+ // über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+ // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+ // mit der Option /str erneut aus, oder erstellen Sie Ihr VS-Projekt neu.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ED_Router.UI.Desktop.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+ /// Ressourcenlookups, die diese stark typisierte Ressourcenklasse verwenden.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/ED-Router.UI.Desktop/Properties/Resources.resx b/ED-Router.UI.Desktop/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/ED-Router.UI.Desktop/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/Properties/Settings.Designer.cs b/ED-Router.UI.Desktop/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..cf36ccf
--- /dev/null
+++ b/ED-Router.UI.Desktop/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ED_Router.UI.Desktop.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/ED-Router.UI.Desktop/Properties/Settings.settings b/ED-Router.UI.Desktop/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/ED-Router.UI.Desktop/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/ViewModel/MainViewModel.cs b/ED-Router.UI.Desktop/ViewModel/MainViewModel.cs
new file mode 100644
index 0000000..8a8c87c
--- /dev/null
+++ b/ED-Router.UI.Desktop/ViewModel/MainViewModel.cs
@@ -0,0 +1,159 @@
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using libspanch;
+using System.Collections.ObjectModel;
+using System.Windows.Input;
+using System.Linq;
+using System.Windows;
+
+namespace ED_Router.UI.Desktop.ViewModel
+{
+ ///
+ /// This class contains properties that the main View can data bind to.
+ ///
+ /// Use the mvvminpc snippet to add bindable properties to this ViewModel.
+ ///
+ ///
+ /// You can also use Blend to data bind with the tool's support.
+ ///
+ ///
+ /// See http://www.galasoft.ch/mvvm
+ ///
+ ///
+ public class MainViewModel : ViewModelBase
+ {
+
+ ///
+ /// Initializes a new instance of the MainViewModel class.
+ ///
+ public MainViewModel()
+ {
+ ////if (IsInDesignMode)
+ ////{
+ //// // Code runs in Blend --> create design time data.
+ ////}
+ ////else
+ ////{
+ //// // Code runs "for real"
+ ////}
+
+ CalculateCommand = new RelayCommand(CalculateMethod);
+ NextWaypointCommand = new RelayCommand(NextWaypointMethod);
+ PrevWaypointCommand = new RelayCommand(PrevWaypointMethod);
+ CopyToClipboardCommand = new RelayCommand(WaypointToClipboard);
+
+ Router = EdRouter.Instance;
+ MyRoute = new ObservableCollection();
+ From = new ObservableCollection();
+ To = new ObservableCollection();
+ }
+
+ public ICommand CalculateCommand { get; private set; }
+ public ICommand NextWaypointCommand { get; private set; }
+ public ICommand PrevWaypointCommand { get; private set; }
+ public ICommand CopyToClipboardCommand { get; private set; }
+
+
+ public EdRouter Router { get; private set; }
+ public ObservableCollection MyRoute { get; set; }
+ public ObservableCollection From { get; private set; }
+ public ObservableCollection To { get; private set; }
+
+ private string _fromSearch;
+
+ public string FromSearch
+ {
+ get { return _fromSearch; }
+ set
+ {
+ _fromSearch = value;
+ if (_fromSearch.Length > 2)
+ {
+ var suggestionSystems = Router.GetSystems(value);
+
+ // Add new Systems
+ foreach (var sys in suggestionSystems)
+ {
+ if (From.Contains(sys) == false)
+ From.Add(sys);
+ }
+
+ // Remove systems which not in suggestion list
+ foreach (var sys in From.ToList())
+ {
+ if (suggestionSystems.Contains(sys) == false)
+ From.Remove(sys);
+ }
+ }
+ }
+ }
+
+ private string _toSearch;
+
+ public string ToSearch
+ {
+ get { return _toSearch; }
+ set
+ {
+ _toSearch = value;
+ if (_toSearch.Length > 2)
+ {
+ var suggestionSystems = Router.GetSystems(value);
+
+ // Add new Systems
+ foreach (var sys in suggestionSystems)
+ {
+ if (To.Contains(sys) == false)
+ To.Add(sys);
+ }
+
+ // Remove systems which not in suggestion list
+ foreach (var sys in To.ToList())
+ {
+ if (suggestionSystems.Contains(sys) == false)
+ To.Remove(sys);
+ }
+ }
+ }
+ }
+
+
+ public void CalculateMethod()
+ {
+ Router.Start = FromSearch;
+ Router.Destination = ToSearch;
+ try
+ {
+ Router.CalculateRoute();
+ MyRoute.Clear();
+ foreach (var jump in Router.Route.SystemJumps)
+ {
+ MyRoute.Add(jump);
+ }
+ }
+ catch (System.Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
+ }
+ }
+
+ public void NextWaypointMethod()
+ {
+ Router.NextWaypoint();
+ WaypointToClipboard();
+ RaisePropertyChanged("Router");
+ }
+
+ public void PrevWaypointMethod()
+ {
+ Router.PreviousWaypoint();
+ WaypointToClipboard();
+ RaisePropertyChanged("Router");
+ }
+
+ public void WaypointToClipboard()
+ {
+ Clipboard.SetText(Router.CurrentWaypoint.System);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/ViewModel/ViewModelLocator.cs b/ED-Router.UI.Desktop/ViewModel/ViewModelLocator.cs
new file mode 100644
index 0000000..7df1118
--- /dev/null
+++ b/ED-Router.UI.Desktop/ViewModel/ViewModelLocator.cs
@@ -0,0 +1,61 @@
+/*
+ In App.xaml:
+
+
+
+
+ In the View:
+ DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
+
+ You can also use Blend to do all this with the tool's support.
+ See http://www.galasoft.ch/mvvm
+*/
+
+using CommonServiceLocator;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Ioc;
+
+namespace ED_Router.UI.Desktop.ViewModel
+{
+ ///
+ /// This class contains static references to all the view models in the
+ /// application and provides an entry point for the bindings.
+ ///
+ public class ViewModelLocator
+ {
+ ///
+ /// Initializes a new instance of the ViewModelLocator class.
+ ///
+ public ViewModelLocator()
+ {
+ ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
+
+ ////if (ViewModelBase.IsInDesignModeStatic)
+ ////{
+ //// // Create design time view services and models
+ //// SimpleIoc.Default.Register();
+ ////}
+ ////else
+ ////{
+ //// // Create run time view services and models
+ //// SimpleIoc.Default.Register();
+ ////}
+
+ SimpleIoc.Default.Register();
+ }
+
+ public MainViewModel Main
+ {
+ get
+ {
+ return ServiceLocator.Current.GetInstance();
+ }
+ }
+
+ public static void Cleanup()
+ {
+ // TODO Clear the ViewModels
+ }
+ }
+}
\ No newline at end of file
diff --git a/ED-Router.UI.Desktop/packages.config b/ED-Router.UI.Desktop/packages.config
new file mode 100644
index 0000000..58fac59
--- /dev/null
+++ b/ED-Router.UI.Desktop/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.VoiceAttack/Commands/CalculateRoute.cs b/ED-Router.VoiceAttack/Commands/CalculateRoute.cs
new file mode 100644
index 0000000..79d9d38
--- /dev/null
+++ b/ED-Router.VoiceAttack/Commands/CalculateRoute.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ED_Router.VoiceAttack.Commands
+{
+ class CalculateRoute : ICommand
+ {
+ public string Command => throw new NotImplementedException();
+
+ public bool Execute()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ED-Router.VoiceAttack/Commands/ICommand.cs b/ED-Router.VoiceAttack/Commands/ICommand.cs
new file mode 100644
index 0000000..d8c5820
--- /dev/null
+++ b/ED-Router.VoiceAttack/Commands/ICommand.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ED_Router.VoiceAttack.Commands
+{
+ public interface ICommand
+ {
+ string Command { get; }
+ bool Execute();
+ }
+}
diff --git a/ED-Router.VoiceAttack/Commands/NextWaypoint.cs b/ED-Router.VoiceAttack/Commands/NextWaypoint.cs
new file mode 100644
index 0000000..be31a4d
--- /dev/null
+++ b/ED-Router.VoiceAttack/Commands/NextWaypoint.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ED_Router.VoiceAttack.Commands
+{
+ class NextWaypoint
+ {
+ }
+}
diff --git a/ED-Router.VoiceAttack/Commands/OpenGui.cs b/ED-Router.VoiceAttack/Commands/OpenGui.cs
new file mode 100644
index 0000000..7949c1f
--- /dev/null
+++ b/ED-Router.VoiceAttack/Commands/OpenGui.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ED_Router.VoiceAttack.Commands
+{
+ class OpenGui
+ {
+ }
+}
diff --git a/ED-Router.VoiceAttack/Commands/PreviousWaypoint.cs b/ED-Router.VoiceAttack/Commands/PreviousWaypoint.cs
new file mode 100644
index 0000000..24abbc4
--- /dev/null
+++ b/ED-Router.VoiceAttack/Commands/PreviousWaypoint.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ED_Router.VoiceAttack.Commands
+{
+ class PreviousWaypoint
+ {
+ }
+}
diff --git a/ED-Router.VoiceAttack/ED-Router.VoiceAttack.csproj b/ED-Router.VoiceAttack/ED-Router.VoiceAttack.csproj
new file mode 100644
index 0000000..4ebb47d
--- /dev/null
+++ b/ED-Router.VoiceAttack/ED-Router.VoiceAttack.csproj
@@ -0,0 +1,72 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}
+ Library
+ Properties
+ ED_Router.VoiceAttack
+ ED-Router.VoiceAttack
+ v4.6.1
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}
+ ED-Router.UI.Desktop
+
+
+ {160c10d6-f300-4766-8120-58f0bc4c427a}
+ ED-Router
+
+
+ {9d0fb9d4-345d-4874-b469-f5caec09ae91}
+ libspanch
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.VoiceAttack/Properties/AssemblyInfo.cs b/ED-Router.VoiceAttack/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..bdff2f2
--- /dev/null
+++ b/ED-Router.VoiceAttack/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("ED-Router.VoiceAttack")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ED-Router.VoiceAttack")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("40837fad-1a6b-4b2d-b5e0-6d1087ea2adc")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ED-Router.VoiceAttack/VoiceAttackPlugin.cs b/ED-Router.VoiceAttack/VoiceAttackPlugin.cs
new file mode 100644
index 0000000..cb31830
--- /dev/null
+++ b/ED-Router.VoiceAttack/VoiceAttackPlugin.cs
@@ -0,0 +1,85 @@
+using ED_Router.UI.Desktop;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace ED_Router.VoiceAttack
+{
+ public class VoiceAttackPlugin
+ {
+ public static string VA_DisplayName()
+ {
+ return "VoiceAttack ED-Router Plugin"; //a name to distinguish my plugin from others
+ }
+
+ public static Guid VA_Id()
+ {
+ return new Guid("{ACC53782-C0B9-40EC-8916-4C57786BF914}"); //note this is a new guid for this plugin
+ }
+
+ public static string VA_DisplayInfo()
+ {
+ return "VoiceAttack ED-Router Plugin\r\n\r\nRoute your neutron highway.\r\n\r\n2018 chriszero"; //this is just extended info that you might want to give to the user. note that you should format this up properly.
+ }
+
+ public static void VA_Init1(dynamic vaProxy)
+ {
+ }
+
+ public static void VA_Exit1(dynamic vaProxy)
+ {
+ //no need to do anything on exit with this implementation
+ }
+
+ public static void VA_StopCommand()
+ {
+ //no need to monitor this
+ }
+
+ public static void VA_Invoke1(dynamic vaProxy)
+ {
+ string context = vaProxy.Context;
+
+ switch (context)
+ {
+ case "next_waypoint":
+ var next = EdRouter.Instance.NextWaypoint();
+ vaProxy.SetText("next_waypoint", next.System);
+ break;
+ case "prev_waypoint":
+ var prev = EdRouter.Instance.PreviousWaypoint();
+ vaProxy.SetText("prev_waypoint", prev.System);
+ break;
+ case "open_gui":
+ InvokeConfiguration();
+ break;
+ case "calculate_route":
+ EdRouter.Instance.CalculateRoute();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private static void InvokeConfiguration()
+ {
+ Thread thread = new Thread(() =>
+ {
+ MainWindow window = new MainWindow();
+ window.ShowDialog();
+
+ });
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ }
+
+ private static void WaypointToClipboard()
+ {
+ Clipboard.SetText(EdRouter.Instance.CurrentWaypoint.System);
+ }
+ }
+}
diff --git a/ED-Router.VoiceAttack/app.config b/ED-Router.VoiceAttack/app.config
new file mode 100644
index 0000000..9a1a9fa
--- /dev/null
+++ b/ED-Router.VoiceAttack/app.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router.sln b/ED-Router.sln
new file mode 100644
index 0000000..385ac2c
--- /dev/null
+++ b/ED-Router.sln
@@ -0,0 +1,57 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2036
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ED-Router.UI.Desktop", "ED-Router.UI.Desktop\ED-Router.UI.Desktop.csproj", "{F120B7B2-5FE9-424F-A5F6-9C0119C5B423}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ED-Router", "ED-Router\ED-Router.csproj", "{160C10D6-F300-4766-8120-58F0BC4C427A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libspanch", "libspanch\libspanch.csproj", "{9D0FB9D4-345D-4874-B469-F5CAEC09AE91}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ED-Router.VoiceAttack", "ED-Router.VoiceAttack\ED-Router.VoiceAttack.csproj", "{40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423} = {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleTestApp", "ConsoleTestApp\ConsoleTestApp.csproj", "{1B0953DC-3CE0-4982-91C2-0F59635FFA61}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CCE3E7A9-1F5D-47A2-9225-15A748D79231}"
+ ProjectSection(SolutionItems) = preProject
+ Readme.md = Readme.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F120B7B2-5FE9-424F-A5F6-9C0119C5B423}.Release|Any CPU.Build.0 = Release|Any CPU
+ {160C10D6-F300-4766-8120-58F0BC4C427A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {160C10D6-F300-4766-8120-58F0BC4C427A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {160C10D6-F300-4766-8120-58F0BC4C427A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {160C10D6-F300-4766-8120-58F0BC4C427A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9D0FB9D4-345D-4874-B469-F5CAEC09AE91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9D0FB9D4-345D-4874-B469-F5CAEC09AE91}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9D0FB9D4-345D-4874-B469-F5CAEC09AE91}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9D0FB9D4-345D-4874-B469-F5CAEC09AE91}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40837FAD-1A6B-4B2D-B5E0-6D1087EA2ADC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1B0953DC-3CE0-4982-91C2-0F59635FFA61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1B0953DC-3CE0-4982-91C2-0F59635FFA61}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1B0953DC-3CE0-4982-91C2-0F59635FFA61}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1B0953DC-3CE0-4982-91C2-0F59635FFA61}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F5D42F9F-E584-478D-9DA9-761F68AFF419}
+ EndGlobalSection
+EndGlobal
diff --git a/ED-Router/ED-Router.csproj b/ED-Router/ED-Router.csproj
new file mode 100644
index 0000000..aa9dd86
--- /dev/null
+++ b/ED-Router/ED-Router.csproj
@@ -0,0 +1,61 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {160C10D6-F300-4766-8120-58F0BC4C427A}
+ Library
+ Properties
+ ED_Router
+ ED-Router
+ v4.6.1
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {9d0fb9d4-345d-4874-b469-f5caec09ae91}
+ libspanch
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ED-Router/EdRouter.cs b/ED-Router/EdRouter.cs
new file mode 100644
index 0000000..f2cd21a
--- /dev/null
+++ b/ED-Router/EdRouter.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using libspanch;
+
+namespace ED_Router
+{
+ public class EdRouter : INotifyPropertyChanged
+ {
+
+ private static readonly EdRouter _instance = new EdRouter();
+ public static EdRouter Instance
+ {
+ get
+ {
+ return _instance;
+ }
+ }
+
+ private EdRouter()
+ {
+ _api = new SpanchApi();
+ _jMon = new JournalMonitor();
+ _jMon.NewLocation += _jMon_NewLocation;
+
+ var backgroundTask = Task.Factory.StartNew(() =>
+ {
+ _jMon.Start();
+ //do something with the result
+ });
+
+ Efficiency = 60;
+ Range = 20;
+ }
+
+ private void _jMon_NewLocation(string obj)
+ {
+ Start = obj;
+ }
+
+ private SpanchApi _api;
+ private int _currentWaypoint;
+ private JournalMonitor _jMon;
+
+ public Route Route { get; set; }
+ //public string CurrentLocation { get; private set; }
+
+
+ private string _start;
+ public string Start
+ {
+ get { return _start; }
+ set
+ {
+ var list = _api.GetSystems(value);
+ if (list.Contains(value))
+ _start = value;
+ else
+ _destination = string.Empty;
+
+ PropertyChanged(this, new PropertyChangedEventArgs("Start"));
+ }
+ }
+
+ private string _destination;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public string Destination
+ {
+ get { return _destination; }
+ set
+ {
+ var list = _api.GetSystems(value);
+ if (list.Contains(value))
+ _destination = value;
+ else
+ _destination = string.Empty;
+ }
+ }
+
+ public int Range { get; set; }
+ public int Efficiency { get; set; }
+
+ public void CalculateRoute()
+ {
+ if (Start?.Length > 0 && Destination?.Length > 0)
+ {
+ var route = _api.PlotRoute(Start, Destination, Range, Efficiency);
+ if (route.TotalJumps > 0)
+ {
+ Route = route;
+ _currentWaypoint = 0;
+ CurrentWaypoint = Route.SystemJumps.ElementAt(0);
+ }
+ }
+ else
+ throw new Exception("Start or Destination is empty.");
+ }
+
+ public string GetCurrentSystem()
+ {
+ return "";
+ }
+
+ public SystemJump NextWaypoint()
+ {
+ if (Route.TotalJumps > 0 && _currentWaypoint+ 1 < Route.SystemJumps.Count)
+ {
+ var next = Route.SystemJumps[++_currentWaypoint];
+ CurrentWaypoint = next;
+ }
+ return CurrentWaypoint;
+ }
+
+ public SystemJump PreviousWaypoint()
+ {
+ if (Route.TotalJumps > 0 && _currentWaypoint - 1 >= 0)
+ {
+ var next = Route.SystemJumps[--_currentWaypoint];
+ CurrentWaypoint = next;
+ }
+ return CurrentWaypoint;
+ }
+
+ public SystemJump CurrentWaypoint { get; private set; }
+
+ public List GetSystems(string value)
+ {
+ return _api.GetSystems(value);
+ }
+
+ }
+}
diff --git a/ED-Router/JournalMonitor.cs b/ED-Router/JournalMonitor.cs
new file mode 100644
index 0000000..22fdf6f
--- /dev/null
+++ b/ED-Router/JournalMonitor.cs
@@ -0,0 +1,80 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+
+namespace ED_Router
+{
+ public class JournalMonitor : LogMonitor
+ {
+ private static Regex JsonRegex = new Regex(@"^{.*}$");
+
+ public JournalMonitor() : base(GetSavedGamesDir(), @"^Journal.*\.[0-9\.]+\.log$")
+ { }
+
+ public event Action NewLocation;
+
+ public override void EventCallback(string data)
+ {
+ string location = GetLocation(data);
+ if(!string.IsNullOrEmpty(location))
+ {
+ //raise event
+ NewLocation(location);
+ }
+ }
+
+ public static string GetLocation(string line)
+ {
+ string location = "";
+ try
+ {
+ Match match = JsonRegex.Match(line);
+ if (match.Success)
+ {
+ JObject o = JObject.Parse(line);
+ /*dynamic ev = JObject.Parse(line);
+ string loca = ev.StarSystem;*/
+
+ string eventType = (string)o["event"];
+
+ switch (eventType)
+ {
+ case "StartJump":
+ case "FSDJump":
+ case "Location":
+ location = (string)o["StarSystem"];
+
+ break;
+ }
+
+ }
+ }
+ catch (Exception)
+ {
+ }
+ return location;
+ }
+
+ private static string GetSavedGamesDir()
+ {
+ IntPtr path;
+ int result = NativeMethods.SHGetKnownFolderPath(new Guid("4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4"), 0, new IntPtr(0), out path);
+ if (result >= 0)
+ {
+ return Marshal.PtrToStringUni(path) + @"\Frontier Developments\Elite Dangerous";
+ }
+ else
+ {
+ throw new ExternalException("Failed to find the saved games directory.", result);
+ }
+ }
+
+ internal class NativeMethods
+ {
+ [DllImport("Shell32.dll")]
+ internal static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr ppszPath);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/ED-Router/LogMonitor.cs b/ED-Router/LogMonitor.cs
new file mode 100644
index 0000000..4ac4a48
--- /dev/null
+++ b/ED-Router/LogMonitor.cs
@@ -0,0 +1,176 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+
+namespace ED_Router
+{
+ public abstract class LogMonitor
+ {
+ // What we are monitoring and what to do with it
+ public string Directory;
+ public Regex Filter;
+ public static string journalFileName = null;
+
+ // Keep track of status
+ private bool running;
+
+ public LogMonitor(string filter) { Filter = new Regex(filter); }
+
+ public LogMonitor(string directory, string filter)
+ {
+ Directory = directory;
+ Filter = new Regex(filter);
+ }
+
+ public abstract void EventCallback(string data);
+
+ /// Monitor the netlog for changes, running a callback when the file changes
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] // this usage is perfectly correct
+ public void Start()
+ {
+ if (Directory == null || Directory.Trim() == "")
+ {
+ return;
+ }
+
+ running = true;
+
+ // Start off by moving to the end of the file
+ long lastSize = 0;
+ string lastName = null;
+ FileInfo fileInfo = null;
+ try
+ {
+ fileInfo = FindLatestFile(Directory, Filter);
+ }
+ catch (NotSupportedException nsex)
+ {
+ //Logging.Error("Directory " + Directory + " not supported: ", nsex);
+ }
+ if (fileInfo != null)
+ {
+ lastSize = fileInfo.Length;
+ lastName = fileInfo.Name;
+ journalFileName = lastName;
+
+ // Elite-specific: start off by grabbing the first line so that we know if we're in beta or live
+ using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ using (StreamReader reader = new StreamReader(fs, Encoding.UTF8))
+ {
+ string firstLine = reader.ReadLine() ?? "";
+ // First line should be a file header
+ if (firstLine.Contains("Fileheader"))
+ {
+ // Pass this along as an event
+ EventCallback(firstLine);
+ }
+ }
+ }
+
+ // Main loop
+ while (running)
+ {
+ fileInfo = FindLatestFile(Directory, Filter);
+ if (fileInfo == null || fileInfo.Name != lastName)
+ {
+ lastName = fileInfo == null ? null : fileInfo.Name;
+ lastSize = 0;
+ if (fileInfo != null)
+ {
+ journalFileName = fileInfo.Name;
+ }
+ else
+ {
+ // A player journal file could not be found. Sleep until a player journal file is found.
+ //Logging.Info("Error locating Elite Dangerous player journal. Journal monitor is not active. Have you installed and run Elite Dangerous previously? ");
+ while (fileInfo == null)
+ {
+ Thread.Sleep(500);
+ fileInfo = FindLatestFile(Directory, Filter);
+ }
+ //Logging.Info("Elite Dangerous player journal found. Journal monitor activated.");
+ return;
+ }
+ }
+ else
+ {
+ journalFileName = fileInfo.Name;
+ long thisSize = fileInfo.Length;
+ long seekPos = 0;
+ int readLen = 0;
+ if (lastSize != thisSize)
+ {
+ if (thisSize > lastSize)
+ {
+ // File has been appended - read the remaining info
+ seekPos = lastSize;
+ readLen = (int)(thisSize - lastSize);
+ }
+ else if (thisSize < lastSize)
+ {
+ // File has been truncated - read all of the info
+ seekPos = 0;
+ readLen = (int)thisSize;
+ }
+
+ using (FileStream fs = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ fs.Seek(seekPos, SeekOrigin.Begin);
+ byte[] bytes = new byte[readLen];
+ int haveRead = 0;
+ while (haveRead < readLen)
+ {
+ haveRead += fs.Read(bytes, haveRead, readLen - haveRead);
+ fs.Seek(seekPos + haveRead, SeekOrigin.Begin);
+ }
+ // Convert bytes to string
+ string s = Encoding.UTF8.GetString(bytes);
+ string[] lines = Regex.Split(s, "\r?\n");
+ foreach (string line in lines)
+ {
+ EventCallback(line);
+ }
+ }
+ }
+ lastSize = thisSize;
+ }
+ Thread.Sleep(100);
+ }
+ }
+
+ public void Stop()
+ {
+ running = false;
+ }
+
+ /// Find the latest file in a given directory matching a given expression, or null if no such file exists
+ private static FileInfo FindLatestFile(string path, Regex filter = null)
+ {
+ if (path == null)
+ {
+ // Configuration can be changed underneath us so we do have to check each time...
+ return null;
+ }
+
+ var directory = new DirectoryInfo(path);
+ if (directory != null)
+ {
+ try
+ {
+ FileInfo info = directory.GetFiles().Where(f => filter == null || filter.IsMatch(f.Name)).OrderByDescending(f => f.LastWriteTime).FirstOrDefault();
+ if (info != null)
+ {
+ // This info can be cached so force a refresh
+ info.Refresh();
+ }
+ return info;
+ }
+ catch { }
+ }
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ED-Router/Properties/AssemblyInfo.cs b/ED-Router/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6bdae69
--- /dev/null
+++ b/ED-Router/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("ED-Router")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ED-Router")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("160c10d6-f300-4766-8120-58f0bc4c427a")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ED-Router/packages.config b/ED-Router/packages.config
new file mode 100644
index 0000000..77c4932
--- /dev/null
+++ b/ED-Router/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Licence.md b/Licence.md
new file mode 100644
index 0000000..4c82d07
--- /dev/null
+++ b/Licence.md
@@ -0,0 +1,194 @@
+Apache License
+==============
+
+_Version 2.0, January 2004_
+_<>_
+
+### Terms and Conditions for use, reproduction, and distribution
+
+#### 1. Definitions
+
+“License” shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+“Licensor” shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+“Legal Entity” shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, “control” means **(i)** the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
+outstanding shares, or **(iii)** beneficial ownership of such entity.
+
+“You” (or “Your”) shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+“Source” form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+“Object” form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+“Work” shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+“Derivative Works” shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+“Contribution” shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+“submitted” means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as “Not a Contribution.”
+
+“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+#### 2. Grant of Copyright License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+#### 3. Grant of Patent License
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+#### 4. Redistribution
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+* **(b)** You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+#### 5. Submission of Contributions
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+#### 6. Trademarks
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+#### 7. Disclaimer of Warranty
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+#### 8. Limitation of Liability
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+#### 9. Accepting Warranty or Additional Liability
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+_END OF TERMS AND CONDITIONS_
+
+### APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets `[]` replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same “printed page” as the copyright notice for easier identification within
+third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Readme.md b/Readme.md
new file mode 100644
index 0000000..52be984
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,18 @@
+# ED-Router: A handsfree helper to plot neutron routes throug the galaxy
+
+ED-Route is a companion app for Elite: Dangerous. Standalone or as VoiceAttack plugin.
+I've created the app primary as a helper for deepspace exploration in VR (Rift/Vive)
+
+ALPHA version! use for testing only!
+
+## Installing ED-Router
+
+If used as stand alone, just save it on your desktop and start.
+If used as VoiceAttack plugin, copy the files to your VoiceAttack Apps folder ([PROGRAMFILES]\VoiceAttack\Apps\edrouter and enable plugin support
+
+## VoiceAttack commands
+
+* next_waypoint, copies next waypoint to clipboard
+* prev_waypoint, copies previous waypoint to clipboard
+* open_gui, opens the GUI of ED-Router
+* calculate_route, calculates a new route, starting from your current location, to the destination you entered in the GUI. Copies the first waypoint to the clipboard
diff --git a/libspanch/Properties/AssemblyInfo.cs b/libspanch/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9f3165f
--- /dev/null
+++ b/libspanch/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("libspanch")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("libspanch")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("9d0fb9d4-345d-4874-b469-f5caec09ae91")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/libspanch/Route.cs b/libspanch/Route.cs
new file mode 100644
index 0000000..9040456
--- /dev/null
+++ b/libspanch/Route.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace libspanch
+{
+ public class Route
+ {
+ public List SystemJumps { get; set; }
+ public string DestinationSystem { get; set; }
+ public double distance { get; set; }
+ public int Efficiency { get; set; }
+ public double Range { get; set; }
+ public string SourceSystem { get; set; }
+ public int TotalJumps { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/libspanch/ScanBody.cs b/libspanch/ScanBody.cs
new file mode 100644
index 0000000..10a7c50
--- /dev/null
+++ b/libspanch/ScanBody.cs
@@ -0,0 +1,12 @@
+namespace libspanch
+{
+ public class ScanBody
+ {
+ public int DistanceToArrival { get; set; }
+ public int EstimatedScanValue { get; set; }
+ public string Id { get; set; }
+ public bool IsTerraformable { get; set; }
+ public string Name { get; set; }
+ public string Type { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/libspanch/ScanSystem.cs b/libspanch/ScanSystem.cs
new file mode 100644
index 0000000..893aa1c
--- /dev/null
+++ b/libspanch/ScanSystem.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+
+namespace libspanch
+{
+ public class ScanSystem
+ {
+ public int Jumps { get; set; }
+ public string Name { get; set; }
+ public List Bodies { get; set; }
+}
+}
\ No newline at end of file
diff --git a/libspanch/SpanchApi.cs b/libspanch/SpanchApi.cs
new file mode 100644
index 0000000..801a177
--- /dev/null
+++ b/libspanch/SpanchApi.cs
@@ -0,0 +1,114 @@
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace libspanch
+{
+ public class SpanchApi
+ {
+ private readonly string baseUri = "https://spansh.co.uk/api/";
+
+ ///
+ /// If response is null, the request may be queued by the server, repeat request
+ ///
+ ///
+ ///
+ ///
+ private T Execute(RestRequest request) where T : new()
+ {
+ var client = new RestClient();
+ client.UserAgent = "libspanch";
+ client.BaseUrl = new Uri(baseUri);
+ var response = client.Execute(request);
+
+ if (response.ErrorException != null)
+ {
+ const string message = "Error retrieving response. Check inner details for more info.";
+ throw new ApplicationException(message, response.ErrorException);
+ }
+
+ return response.Data;
+ }
+
+
+ // Todo: make async!
+ public Route PlotRoute(string startSystem, string destinationSystem, double jumpRange, int efficiency = 60)
+ {
+ var request = new RestRequest("route");
+ request.AddParameter("efficiency", efficiency)
+ .AddParameter("range", jumpRange)
+ .AddParameter("from", startSystem)
+ .AddParameter("to", destinationSystem);
+
+ var response = Execute(request);
+
+ var routeRequest = new RestRequest("results/{job}");
+ routeRequest.AddParameter("job", response.Job, ParameterType.UrlSegment);
+
+ var routeResponse = Execute>(routeRequest);
+ while (routeResponse.Status.ToLower() == "queued")
+ {
+ routeResponse = Execute>(routeRequest);
+ // wait few ms? limit via time?
+ Thread.Sleep(1000);
+ }
+
+ return routeResponse.Result;
+ }
+
+ ///
+ /// Returns a list of systems that maches "system"
+ ///
+ ///
+ ///
+ public List GetSystems(string system)
+ {
+ var request = new RestRequest("systems");
+ request.AddParameter("q", system);
+
+ var response = Execute>(request);
+ return response;
+ }
+
+ public List Route2Riches(string from, string to, int radius, int range, int maxResults, int maxDistance = 1000000, int minValue = 300000)
+ {
+ var request = new RestRequest("riches/route");
+ request.AddParameter("radius", radius)
+ .AddParameter("range", range)
+ .AddParameter("from", from)
+ .AddParameter("to", to)
+ .AddParameter("max_results", maxResults)
+ .AddParameter("max_distance", maxDistance)
+ .AddParameter("min_value", minValue);
+
+ var response = Execute(request);
+
+ var routeRequest = new RestRequest("results/{job}");
+ routeRequest.AddParameter("job", response.Job, ParameterType.UrlSegment);
+
+ var routeResponse = Execute>>(routeRequest);
+ while (routeResponse.Status.ToLower() == "queued")
+ {
+ routeResponse = Execute>>(routeRequest);
+ // wait few ms? limit via time?
+ Thread.Sleep(1000);
+ }
+
+ return routeResponse.Result;
+ }
+
+ }
+
+ internal class RequestResult
+ {
+ public string Status { get; set; }
+ public string Job { get; set; }
+ public string Error { get; set; }
+ }
+
+ internal class RequestResult : RequestResult
+ {
+ public T Result { get; set; }
+ }
+}
diff --git a/libspanch/SystemJump.cs b/libspanch/SystemJump.cs
new file mode 100644
index 0000000..c0a39e6
--- /dev/null
+++ b/libspanch/SystemJump.cs
@@ -0,0 +1,11 @@
+namespace libspanch
+{
+ public class SystemJump
+ {
+ public string System { get; set; }
+ public bool NeutronStar { get; set; }
+ public int Jumps { get; set; }
+ public double DistanceJumped { get; set; }
+ public double DistanceLeft { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/libspanch/libspanch.csproj b/libspanch/libspanch.csproj
new file mode 100644
index 0000000..2264bb1
--- /dev/null
+++ b/libspanch/libspanch.csproj
@@ -0,0 +1,61 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9D0FB9D4-345D-4874-B469-F5CAEC09AE91}
+ Library
+ Properties
+ libspanch
+ libspanch
+ v4.6.1
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\RestSharp.106.2.1\lib\net452\RestSharp.dll
+
+
+
+
+ ..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libspanch/packages.config b/libspanch/packages.config
new file mode 100644
index 0000000..0029f87
--- /dev/null
+++ b/libspanch/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/voiceattack-router.sln b/voiceattack-router.sln
deleted file mode 100644
index d59fc5b..0000000
--- a/voiceattack-router.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27004.2009
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "voiceattack-router", "voiceattack-router\voiceattack-router.csproj", "{BAFE8FB4-0E29-4165-952D-97C20886F61D}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {BAFE8FB4-0E29-4165-952D-97C20886F61D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BAFE8FB4-0E29-4165-952D-97C20886F61D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BAFE8FB4-0E29-4165-952D-97C20886F61D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BAFE8FB4-0E29-4165-952D-97C20886F61D}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {F5D42F9F-E584-478D-9DA9-761F68AFF419}
- EndGlobalSection
-EndGlobal
diff --git a/voiceattack-router/Class1.cs b/voiceattack-router/Class1.cs
deleted file mode 100644
index 96ae158..0000000
--- a/voiceattack-router/Class1.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace voiceattack_router
-{
- public class Class1
- {
- }
-}
diff --git a/voiceattack-router/voiceattack-router.csproj b/voiceattack-router/voiceattack-router.csproj
deleted file mode 100644
index 9f5c4f4..0000000
--- a/voiceattack-router/voiceattack-router.csproj
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
- netstandard2.0
-
-
-