From 77bd87b8b692cd240a2b30fb027da1966eb26746 Mon Sep 17 00:00:00 2001 From: Xjph Date: Fri, 14 Jun 2019 13:26:06 -0230 Subject: [PATCH] Initial Commit - Lots left to do --- EDDisco/App.config | 12 ++ EDDisco/EDDisco.cs | 27 +++ EDDisco/EDDisco.csproj | 74 +++++++-- EDDisco/EDDiscoFrm.Designer.cs | 233 ++++++++++++++++++++++++++ EDDisco/EDDiscoFrm.cs | 256 +++++++++++++++++++++++++++++ EDDisco/EDDiscoFrm.resx | 141 ++++++++++++++++ EDDisco/EDDiscoMon.ico | Bin 0 -> 31702 bytes EDDisco/Form1.Designer.cs | 40 ----- EDDisco/Form1.cs | 20 --- EDDisco/ILMergeConfig.json | 31 ++++ EDDisco/JournalPoker.cs | 46 ++++++ EDDisco/LogMonitor.cs | 199 ++++++++++++++++++++++ EDDisco/Program.cs | 22 --- EDDisco/Properties/AssemblyInfo.cs | 4 +- EDDisco/ScanEvent.cs | 209 +++++++++++++++++++++++ EDDisco/ScanReader.cs | 200 ++++++++++++++++++++++ EDDisco/packages.config | 7 + 17 files changed, 1427 insertions(+), 94 deletions(-) create mode 100644 EDDisco/EDDisco.cs create mode 100644 EDDisco/EDDiscoFrm.Designer.cs create mode 100644 EDDisco/EDDiscoFrm.cs create mode 100644 EDDisco/EDDiscoFrm.resx create mode 100644 EDDisco/EDDiscoMon.ico delete mode 100644 EDDisco/Form1.Designer.cs delete mode 100644 EDDisco/Form1.cs create mode 100644 EDDisco/ILMergeConfig.json create mode 100644 EDDisco/JournalPoker.cs create mode 100644 EDDisco/LogMonitor.cs delete mode 100644 EDDisco/Program.cs create mode 100644 EDDisco/ScanEvent.cs create mode 100644 EDDisco/ScanReader.cs create mode 100644 EDDisco/packages.config diff --git a/EDDisco/App.config b/EDDisco/App.config index 8e15646..1b97f03 100644 --- a/EDDisco/App.config +++ b/EDDisco/App.config @@ -1,6 +1,18 @@  + + +
+ + + + + + + + + \ No newline at end of file diff --git a/EDDisco/EDDisco.cs b/EDDisco/EDDisco.cs new file mode 100644 index 0000000..64087cb --- /dev/null +++ b/EDDisco/EDDisco.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using Newtonsoft.Json.Linq; + +namespace EDDisco +{ + static class EDDisco + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + //JObject test = JObject.Parse("{ \"timestamp\":\"2019 - 06 - 05T01: 41:44Z\", \"event\":\"Scan\", \"ScanType\":\"Detailed\", \"BodyName\":\"Plaa Fleau QS-J c22-0 5 a\", \"BodyID\":8, \"Parents\":[ {\"Planet\":7}, {\"Star\":0} ], \"DistanceFromArrivalLS\":3068.617188, \"TidalLock\":false, \"TerraformState\":\"\", \"PlanetClass\":\"Icy body\", \"Atmosphere\":\"\", \"AtmosphereType\":\"None\", \"Volcanism\":\"\", \"MassEM\":0.039342, \"Radius\":2984278.000000, \"SurfaceGravity\":1.760719, \"SurfaceTemperature\":67.210930, \"SurfacePressure\":90.113243, \"Landable\":true, \"Materials\":[ { \"Name\":\"sulphur\", \"Percent\":27.437029 }, { \"Name\":\"carbon\", \"Percent\":23.071699 }, { \"Name\":\"phosphorus\", \"Percent\":14.770898 }, { \"Name\":\"iron\", \"Percent\":11.999499 }, { \"Name\":\"nickel\", \"Percent\":9.075918 }, { \"Name\":\"chromium\", \"Percent\":5.396573 }, { \"Name\":\"germanium\", \"Percent\":3.174578 }, { \"Name\":\"vanadium\", \"Percent\":2.946659 }, { \"Name\":\"cadmium\", \"Percent\":0.931815 }, { \"Name\":\"antimony\", \"Percent\":0.671342 }, { \"Name\":\"mercury\", \"Percent\":0.523998 } ], \"Composition\":{ \"Ice\":0.878241, \"Rock\":0.104724, \"Metal\":0.017035 }, \"SemiMajorAxis\":2443254784.000000, \"Eccentricity\":0.000000, \"OrbitalInclination\":-37.623867, \"Periapsis\":149.435867, \"OrbitalPeriod\":53715820.000000, \"RotationPeriod\":176866.078125, \"AxialTilt\":-0.354162, \"WasDiscovered\":false, \"WasMapped\":false }"); + //ScanEvent scanEvent; + //scanEvent = test.ToObject(); + //Properties.Settings.Default. + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new EDDiscoFrm()); + } + } +} diff --git a/EDDisco/EDDisco.csproj b/EDDisco/EDDisco.csproj index 4372375..2d06825 100644 --- a/EDDisco/EDDisco.csproj +++ b/EDDisco/EDDisco.csproj @@ -1,5 +1,6 @@  + Debug @@ -11,9 +12,26 @@ v4.5 512 true + false + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 0.1.0.%2a + false + true - AnyCPU + x86 true full false @@ -24,35 +42,51 @@ AnyCPU - pdbonly + none true bin\Release\ TRACE prompt 4 + + EDDisco.EDDisco + + + EDDiscoMon.ico + + + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + - - - + + + ..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + - - + + + Form - - Form1.cs + + EDDiscoFrm.cs - + + + + + EDDiscoFrm.cs + ResXFileCodeGenerator Resources.Designer.cs @@ -62,6 +96,8 @@ True Resources.resx + + SettingsSingleFileGenerator Settings.Designer.cs @@ -75,5 +111,23 @@ + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/EDDisco/EDDiscoFrm.Designer.cs b/EDDisco/EDDiscoFrm.Designer.cs new file mode 100644 index 0000000..1d1b4d8 --- /dev/null +++ b/EDDisco/EDDiscoFrm.Designer.cs @@ -0,0 +1,233 @@ +namespace EDDisco +{ + partial class EDDiscoFrm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + speech?.Dispose(); + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EDDiscoFrm)); + this.btnToggleMonitor = new System.Windows.Forms.Button(); + this.listEvent = new System.Windows.Forms.ListView(); + this.body = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.interest = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.timestamp = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.detail = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.landable = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.btnReadAll = new System.Windows.Forms.Button(); + this.progressReadAll = new System.Windows.Forms.ProgressBar(); + this.cbxToast = new System.Windows.Forms.CheckBox(); + this.cbxTts = new System.Windows.Forms.CheckBox(); + this.contextCopy = new System.Windows.Forms.ContextMenuStrip(this.components); + this.copyNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.cbxTtsDetail = new System.Windows.Forms.CheckBox(); + this.contextCopy.SuspendLayout(); + this.SuspendLayout(); + // + // btnToggleMonitor + // + this.btnToggleMonitor.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnToggleMonitor.Location = new System.Drawing.Point(597, 496); + this.btnToggleMonitor.Name = "btnToggleMonitor"; + this.btnToggleMonitor.Size = new System.Drawing.Size(100, 23); + this.btnToggleMonitor.TabIndex = 1; + this.btnToggleMonitor.Text = "Start Monitoring"; + this.btnToggleMonitor.UseVisualStyleBackColor = true; + this.btnToggleMonitor.Click += new System.EventHandler(this.BtnToggleMonitor_Click); + // + // listEvent + // + this.listEvent.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listEvent.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.body, + this.interest, + this.timestamp, + this.detail, + this.landable}); + this.listEvent.FullRowSelect = true; + this.listEvent.Location = new System.Drawing.Point(12, 12); + this.listEvent.Name = "listEvent"; + this.listEvent.Size = new System.Drawing.Size(685, 478); + this.listEvent.TabIndex = 2; + this.listEvent.UseCompatibleStateImageBehavior = false; + this.listEvent.View = System.Windows.Forms.View.Details; + this.listEvent.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ListEvent_KeyDown); + this.listEvent.MouseClick += new System.Windows.Forms.MouseEventHandler(this.ListEvent_MouseClick); + // + // body + // + this.body.DisplayIndex = 1; + this.body.Text = "Body"; + this.body.Width = 146; + // + // interest + // + this.interest.DisplayIndex = 3; + this.interest.Text = "Description"; + this.interest.Width = 177; + // + // timestamp + // + this.timestamp.DisplayIndex = 0; + this.timestamp.Text = "Time"; + this.timestamp.Width = 114; + // + // detail + // + this.detail.DisplayIndex = 4; + this.detail.Text = "Detail"; + this.detail.Width = 200; + // + // landable + // + this.landable.DisplayIndex = 2; + this.landable.Text = ""; + this.landable.Width = 28; + // + // btnReadAll + // + this.btnReadAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnReadAll.Location = new System.Drawing.Point(503, 496); + this.btnReadAll.Name = "btnReadAll"; + this.btnReadAll.Size = new System.Drawing.Size(88, 23); + this.btnReadAll.TabIndex = 3; + this.btnReadAll.Text = "Read All Logs"; + this.btnReadAll.UseVisualStyleBackColor = true; + this.btnReadAll.Click += new System.EventHandler(this.BtnReadAll_Click); + // + // progressReadAll + // + this.progressReadAll.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressReadAll.Location = new System.Drawing.Point(14, 496); + this.progressReadAll.Name = "progressReadAll"; + this.progressReadAll.Size = new System.Drawing.Size(483, 23); + this.progressReadAll.TabIndex = 4; + this.progressReadAll.Visible = false; + // + // cbxToast + // + this.cbxToast.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxToast.AutoSize = true; + this.cbxToast.Location = new System.Drawing.Point(14, 500); + this.cbxToast.Name = "cbxToast"; + this.cbxToast.Size = new System.Drawing.Size(113, 17); + this.cbxToast.TabIndex = 5; + this.cbxToast.Text = "Popup Notification"; + this.cbxToast.UseVisualStyleBackColor = true; + this.cbxToast.CheckedChanged += new System.EventHandler(this.CbxToast_CheckedChanged); + // + // cbxTts + // + this.cbxTts.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxTts.AutoSize = true; + this.cbxTts.Location = new System.Drawing.Point(129, 500); + this.cbxTts.Name = "cbxTts"; + this.cbxTts.Size = new System.Drawing.Size(99, 17); + this.cbxTts.TabIndex = 6; + this.cbxTts.Text = "Text-to-Speech"; + this.cbxTts.UseVisualStyleBackColor = true; + this.cbxTts.CheckedChanged += new System.EventHandler(this.CbxTts_CheckedChanged); + // + // contextCopy + // + this.contextCopy.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.copyNameToolStripMenuItem, + this.copyAllToolStripMenuItem}); + this.contextCopy.Name = "contextCopy"; + this.contextCopy.Size = new System.Drawing.Size(138, 48); + // + // copyNameToolStripMenuItem + // + this.copyNameToolStripMenuItem.Name = "copyNameToolStripMenuItem"; + this.copyNameToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.copyNameToolStripMenuItem.Text = "Copy Name"; + this.copyNameToolStripMenuItem.Click += new System.EventHandler(this.CopyNameToolStripMenuItem_Click); + // + // copyAllToolStripMenuItem + // + this.copyAllToolStripMenuItem.Name = "copyAllToolStripMenuItem"; + this.copyAllToolStripMenuItem.Size = new System.Drawing.Size(137, 22); + this.copyAllToolStripMenuItem.Text = "Copy All"; + this.copyAllToolStripMenuItem.Click += new System.EventHandler(this.CopyAllToolStripMenuItem_Click); + // + // cbxTtsDetail + // + this.cbxTtsDetail.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.cbxTtsDetail.AutoSize = true; + this.cbxTtsDetail.Location = new System.Drawing.Point(235, 500); + this.cbxTtsDetail.Name = "cbxTtsDetail"; + this.cbxTtsDetail.Size = new System.Drawing.Size(115, 17); + this.cbxTtsDetail.TabIndex = 7; + this.cbxTtsDetail.Text = "TTS Include Detail"; + this.cbxTtsDetail.UseVisualStyleBackColor = true; + this.cbxTtsDetail.Visible = false; + // + // EDDiscoFrm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(710, 530); + this.Controls.Add(this.progressReadAll); + this.Controls.Add(this.cbxTtsDetail); + this.Controls.Add(this.btnReadAll); + this.Controls.Add(this.listEvent); + this.Controls.Add(this.btnToggleMonitor); + this.Controls.Add(this.cbxTts); + this.Controls.Add(this.cbxToast); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Name = "EDDiscoFrm"; + this.Text = "EDDiscoMon"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EDDiscoFrm_FormClosing); + this.contextCopy.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + private System.Windows.Forms.Button btnToggleMonitor; + private System.Windows.Forms.ListView listEvent; + private System.Windows.Forms.ColumnHeader body; + private System.Windows.Forms.ColumnHeader interest; + private System.Windows.Forms.Button btnReadAll; + private System.Windows.Forms.ProgressBar progressReadAll; + private System.Windows.Forms.CheckBox cbxToast; + private System.Windows.Forms.CheckBox cbxTts; + private System.Windows.Forms.ColumnHeader timestamp; + private System.Windows.Forms.ColumnHeader detail; + private System.Windows.Forms.ColumnHeader landable; + private System.Windows.Forms.ContextMenuStrip contextCopy; + private System.Windows.Forms.ToolStripMenuItem copyNameToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem copyAllToolStripMenuItem; + private System.Windows.Forms.CheckBox cbxTtsDetail; + } +} + diff --git a/EDDisco/EDDiscoFrm.cs b/EDDisco/EDDiscoFrm.cs new file mode 100644 index 0000000..f84879b --- /dev/null +++ b/EDDisco/EDDiscoFrm.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Speech.Synthesis; + +namespace EDDisco +{ + public partial class EDDiscoFrm : Form + { + private LogMonitor logMonitor; + private NotifyIcon notifyIcon; + private SpeechSynthesizer speech; + + public EDDiscoFrm() + { + InitializeComponent(); + logMonitor = new LogMonitor(""); + logMonitor.LogEntry += LogEvent; + Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); + notifyIcon = new NotifyIcon() + { + Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath), + Visible = false + }; + } + + private void BtnToggleMonitor_Click(object sender, EventArgs e) + { + if (logMonitor.IsMonitoring()) + { + logMonitor.MonitorStop(); + btnToggleMonitor.Text = "Start Monitoring"; + } + else + { + logMonitor.MonitorStart(); + btnToggleMonitor.Text = "Stop Monitoring"; + } + } + + private void LogEvent(object source, EventArgs e) + { + if (logMonitor.LastScanValid) + { + ScanReader scan = new ScanReader(logMonitor.LastScan, logMonitor.SystemBody, logMonitor.CurrentSystem); + + if (scan.IsInteresting()) + { + Invoke((MethodInvoker)delegate () + { + if (!logMonitor.ReadAllInProgress && listEvent.Items[listEvent.Items.Count - 1].SubItems[1].Text == "Uninteresting") + { + listEvent.Items.RemoveAt(listEvent.Items.Count - 1); + } + bool addItem; + List<(string, string, string)> pendingRemoval = new List<(string, string, string)>(); + foreach (var item in scan.Interest) + { + addItem = true; + if (item.Item2 == "All jumponium materials in system") + { + for (int i = Math.Max(0, listEvent.Items.Count - 10); i < listEvent.Items.Count; i++) + { + if (listEvent.Items[i].SubItems[0].Text.Contains(logMonitor.CurrentSystem) && listEvent.Items[i].SubItems[1].Text == "All jumponium materials in system") + { + addItem = false; + } + } + } + + if (addItem) + { + AddListItem(item); + } + else + { + pendingRemoval.Add(item); + } + } + foreach (var item in pendingRemoval) + { + scan.Interest.Remove(item); + } + if (!logMonitor.ReadAllInProgress && scan.Interest.Count > 0) { AnnounceItems(scan.Interest); } + }); + } + else if (!logMonitor.ReadAllInProgress) + { + + ListViewItem newItem = new ListViewItem(new string[] { scan.Interest[0].Item1, "Uninteresting" }) + { + UseItemStyleForSubItems = false + }; + Invoke((MethodInvoker)delegate () { + if (listEvent.Items.Count > 0 && listEvent.Items[listEvent.Items.Count - 1].SubItems[1].Text == "Uninteresting") + { + listEvent.Items.RemoveAt(listEvent.Items.Count - 1); + } + + newItem.SubItems[0].ForeColor = Color.DarkGray; + newItem.SubItems[1].ForeColor = Color.DarkGray; + listEvent.Items.Add(newItem).EnsureVisible(); }); + } + } + } + + private void AnnounceItems(List<(string,string,string)> items) + { + if (cbxToast.Checked || cbxTts.Checked) + { + notifyIcon.BalloonTipTitle = "Discovery:"; + string fullSystemName = items[0].Item1; + StringBuilder announceText = new StringBuilder(); + + foreach (var item in items) + { + announceText.Append(item.Item2); + if (!item.Equals(items.Last())) + { + announceText.AppendLine(", "); + } + } + if (cbxToast.Checked) + { + notifyIcon.BalloonTipText = fullSystemName + ": " + announceText.ToString(); + notifyIcon.ShowBalloonTip(3000); + } + if (cbxTts.Checked) + { + string sector = fullSystemName.Substring(0, fullSystemName.IndexOf('-') - 2); + string system = fullSystemName.Remove(0, sector.Length).Replace('-', '–'); //Want it to say "dash", not "hyphen". + + speech.SpeakSsmlAsync($"{sector}{system}{announceText}"); + } + } + } + + private void AddListItem((string,string,string) item) + { + ListViewItem newItem = new ListViewItem( + new string[] { + item.Item1, + item.Item2, + logMonitor.LastScan.Timestamp.ToString("yyyy-MM-dd HH:mm:ss"), + item.Item3, + (logMonitor.LastScan.Landable.GetValueOrDefault(false) && !(item.Item2 == "All jumponium materials in system")) ? "🌐" : string.Empty + }); + if (item.Item2.Contains("Interesting Object")) + { + newItem.UseItemStyleForSubItems = false; + newItem.SubItems[1].Font = new Font(newItem.Font, FontStyle.Bold); + } + + listEvent.Items.Add(newItem).EnsureVisible(); + } + + private void BtnReadAll_Click(object sender, EventArgs e) + { + if (logMonitor.ReadAllComplete) + { + DialogResult confirmResult; + confirmResult = MessageBox.Show("This will clear the current list and re-read all journal logs. Contine?", "Confirm Refresh", MessageBoxButtons.OKCancel); + if (confirmResult == DialogResult.OK) + { + listEvent.Items.Clear(); + } + else + { + return; + } + } + logMonitor.ReadAll(progressReadAll); + } + + private void CbxToast_CheckedChanged(object sender, EventArgs e) + { + notifyIcon.Visible = cbxToast.Checked; + } + + private void CbxTts_CheckedChanged(object sender, EventArgs e) + { + if (cbxTts.Checked) + { + speech = new SpeechSynthesizer(); + speech.SetOutputToDefaultAudioDevice(); + //cbxTtsDetail.Visible = true; + } + else + { + speech.Dispose(); + //cbxTtsDetail.Visible = false; + } + } + + private void EDDiscoFrm_FormClosing(object sender, FormClosingEventArgs e) + { + notifyIcon.Icon = null; + notifyIcon.Dispose(); + speech?.Dispose(); + } + + private void ListEvent_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + if (listEvent.FocusedItem.Bounds.Contains(e.Location)) + { + contextCopy.Show(Cursor.Position); + contextCopy.Items[0].Enabled = listEvent.SelectedItems.Count == 1; + } + } + } + + private void CopyNameToolStripMenuItem_Click(object sender, EventArgs e) + { + Clipboard.SetText(listEvent.FocusedItem.Text); + } + + private void CopyAllToolStripMenuItem_Click(object sender, EventArgs e) + { + CopyAllSelected(); + } + + private void ListEvent_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.C && e.Control) + { + CopyAllSelected(); + } + } + + private void CopyAllSelected() + { + StringBuilder copyText = new StringBuilder(); + foreach (ListViewItem item in listEvent.SelectedItems) + { + copyText.AppendLine( + item.SubItems[2].Text + " - " + + item.SubItems[0].Text + " - " + + (item.SubItems[4].Text.Length > 0 ? "Landable - " : string.Empty) + + item.SubItems[1].Text + + (item.SubItems[3].Text.Length > 0 ? " - " + item.SubItems[3].Text : string.Empty) + ); + + } + Clipboard.SetText(copyText.ToString()); + } + } +} diff --git a/EDDisco/EDDiscoFrm.resx b/EDDisco/EDDiscoFrm.resx new file mode 100644 index 0000000..cae2ef0 --- /dev/null +++ b/EDDisco/EDDiscoFrm.resx @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + AAABAAEAICAQcgAAAADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAgAIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP// + AAD///8AAAAAAAAAAAAAAHd3d3AAAAAAAAAAAAAAB3d3d3d3cAAAAAAAAAAAd3d3d3d3d3d3AAAAAAB3 + d3d3d3d3d3d3dwAAAAd3d3d3d3d3d3d3d3cAAHd3d3d3d3d3d3d3d3d3B3d3d3d3d3d3d3d3d3d3d3d3 + d3d3d3AAAAAAAHd3d3dwAAAAAAAAAAAAAAB3d3d3AAAAAAAAAHd3AAAAd3d3dwAAAAAAAAd3d3cAAHd3 + d3cAAAAAAAB3d3d3AAB3d3d3AAAAAAAHd3d3dwAAd3d3dwAHcAAAd3d3d3cAAHd3d3cAd3dwB3d3d3d3 + AAB3d3d3AHd3d3d3d3d3dwAAd3d3dwB3d3d3d3cAd3cAAHd3d3cAdwd3d3dwAHd3AAB3d3d3AHcHd3d3 + AAB3dwAAd3d3dwB3d3d3d3AAd3cAAHd3d3cAd3d3d3d3cHd3AAB3d3d3AHd3dwd3d3d3dwAAd3d3dwB3 + dwAAd3d3d3cAAHd3d3cAB3AAAAd3d3d3AAB3d3d3AAAAAAAAd3d3dwAAd3d3dwAAAAAAAAd3d3cAAHd3 + d3cAAAAAAAAAd3dwAAB3d3d3AAAAAAAAAAdwAAAAd3d3dwAAAAAAAAAAAAAAAHd3d3cAAAAAAAAAAAAA + AAB3d3d3AAAAAAAAAAAAAAAAd3dwAAAAAAAAAAAAAAAAAHdwAAD///Af//+AB//8AAD/wAAA/gAAAPAA + AACAAAAAAAf/AH///wD//D8A//gPAP/wDwD/4A8A58APAMGADwDAAA8AwAMPAMgHDwDIDw8AwAcPAMAB + DwDAgA8Aw8APAOfgDwD/8A8A//gPAP/8HwD//n8A////AP///wD///8H////Hw== + + + \ No newline at end of file diff --git a/EDDisco/EDDiscoMon.ico b/EDDisco/EDDiscoMon.ico new file mode 100644 index 0000000000000000000000000000000000000000..13e1bd69756a348b6e47c4e93d296dbff131a7f5 GIT binary patch literal 31702 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 - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; - } - - #endregion - } -} - diff --git a/EDDisco/Form1.cs b/EDDisco/Form1.cs deleted file mode 100644 index a668f30..0000000 --- a/EDDisco/Form1.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace EDDisco -{ - public partial class Form1 : Form - { - public Form1() - { - InitializeComponent(); - } - } -} diff --git a/EDDisco/ILMergeConfig.json b/EDDisco/ILMergeConfig.json new file mode 100644 index 0000000..1f5363f --- /dev/null +++ b/EDDisco/ILMergeConfig.json @@ -0,0 +1,31 @@ +{ + "General": { + "OutputFile": null, + "TargetPlatform": null, + "KeyFile": null, + "AlternativeILMergePath": null, + "InputAssemblies": [] + }, + "Advanced": { + "AllowDuplicateType": null, + "AllowMultipleAssemblyLevelAttributes": false, + "AllowWildCards": false, + "AllowZeroPeKind": false, + "AttributeFile": null, + "Closed": false, + "CopyAttributes": false, + "DebugInfo": false, + "DelaySign": false, + "ExcludeFile": "", + "FileAlignment": 512, + "Internalize": false, + "Log": false, + "LogFile": null, + "PublicKeyTokens": true, + "SearchDirectories": [], + "TargetKind": null, + "UnionMerge": false, + "Version": null, + "XmlDocumentation": false + } +} \ No newline at end of file diff --git a/EDDisco/JournalPoker.cs b/EDDisco/JournalPoker.cs new file mode 100644 index 0000000..2f85b80 --- /dev/null +++ b/EDDisco/JournalPoker.cs @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using System.IO; + +namespace EDDisco +{ + class JournalPoker + { + private bool Running = false; + private DirectoryInfo DirectoryInfo; + + public JournalPoker(string dir) + { + DirectoryInfo = new DirectoryInfo(dir); + } + + public async void Start() + { + Running = true; + await Task.Run(() => + { + while (Running) + { + FileStream stream; + FileInfo fileToPoke = null; + + foreach (var file in DirectoryInfo.GetFiles("Journal.????????????.??.log")) + { + if (fileToPoke == null || string.Compare(file.Name, fileToPoke.Name) > 0) + { + fileToPoke = file; + } + } + + stream = fileToPoke.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + stream.Close(); + System.Threading.Thread.Sleep(250); + } + }); + } + + public void Stop() + { + Running = false; + } + } +} diff --git a/EDDisco/LogMonitor.cs b/EDDisco/LogMonitor.cs new file mode 100644 index 0000000..1640ad8 --- /dev/null +++ b/EDDisco/LogMonitor.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using System.IO; + +namespace EDDisco +{ + class LogMonitor + { + private readonly FileSystemWatcher logWatcher; + public string CurrentSystem { get; private set; } + public string CurrentLogPath { get; private set; } + public string CurrentLogLine { get; private set; } + private string PreviousScan; + private string LogDirectory; + private string JsonException; + public bool LastScanValid { get; private set; } + public bool ReadAllInProgress { get; private set; } + public bool ReadAllComplete { get; private set; } + public ScanEvent LastScan { get; private set; } + public Dictionary<(string, long), ScanEvent> SystemBody { get; private set; } + private JournalPoker Poker; + + public LogMonitor(string logPath) + { + + LogDirectory = logPath; + LogDirectory = CheckLogPath(); + logWatcher = new FileSystemWatcher(LogDirectory, "Journal.????????????.??.log") + { + NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.FileName + }; + logWatcher.Changed += LogChanged; + logWatcher.Created += LogChanged; + SystemBody = new Dictionary<(string, long), ScanEvent>(); + ReadAllInProgress = false; + ReadAllComplete = false; + } + + public void MonitorStart() + { + logWatcher.EnableRaisingEvents = true; + Poker = new JournalPoker(LogDirectory); + Poker.Start(); + } + + public void MonitorStop() + { + logWatcher.EnableRaisingEvents = false; + Poker.Stop(); + Poker = null; + } + + public void ReadAll(ProgressBar progressBar) + { + ReadAllInProgress = true; + progressBar.Visible = true; + DirectoryInfo logDir = new DirectoryInfo(CheckLogPath()); + FileInfo[] allJournals = logDir.GetFiles("Journal.????????????.??.log"); + int progress = 0; + foreach (var journalFile in allJournals) + { + using (StreamReader currentLog = new StreamReader(File.Open(journalFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) + { + while (!currentLog.EndOfStream) + { + CurrentLogLine = currentLog.ReadLine(); + + ProcessLine(); + } + } + progressBar.Value = (progress++ * 100) / allJournals.Count(); + progressBar.Refresh(); + } + progressBar.Visible = false; + ReadAllInProgress = false; + ReadAllComplete = true; + } + + public bool IsMonitoring() + { + return logWatcher.EnableRaisingEvents; + } + + private string CheckLogPath() + { + LogDirectory = string.IsNullOrEmpty(LogDirectory) ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + "\\Saved Games\\Frontier Developments\\Elite Dangerous" : LogDirectory; + if (!Directory.Exists(LogDirectory) || new DirectoryInfo(LogDirectory).GetFiles("Journal.????????????.??.log").Count() == 0) + { + System.Windows.Forms.FolderBrowserDialog folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog + { + RootFolder = Environment.SpecialFolder.MyComputer, + ShowNewFolderButton = false, + Description = "Select Elite Dangerous Journal Folder" + }; + + System.Windows.Forms.DialogResult result = folderBrowserDialog.ShowDialog(); + if (result == System.Windows.Forms.DialogResult.OK && !string.IsNullOrWhiteSpace(folderBrowserDialog.SelectedPath)) + { + LogDirectory = folderBrowserDialog.SelectedPath; + } + } + return LogDirectory; + } + + private void LogChanged(object source, FileSystemEventArgs e) + { + switch (e.ChangeType) + { + case WatcherChangeTypes.Created: + CurrentLogPath = e.FullPath; + CurrentLogPath = string.Empty; + break; + + case WatcherChangeTypes.Changed: + CurrentLogPath = e.FullPath; + bool updateScan = false; + using (StreamReader currentLog = new StreamReader(File.Open(CurrentLogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) + { + while (!currentLog.EndOfStream) + { + string checkLine = currentLog.ReadLine(); + if (checkLine.Contains("\"event\":\"Scan\"") && checkLine != PreviousScan) + { + CurrentLogLine = checkLine; + updateScan = true; + } + else if (checkLine.Contains("\"event\":\"Location\"") || checkLine.Contains("\"event\":\"FSDJump\"")) + { + CurrentLogLine = checkLine; + } + } + } + if (updateScan) + { + PreviousScan = CurrentLogLine; + } + ProcessLine(); + + break; + + default: + break; + } + } + + private void ProcessLine() + { + try + { + if (CurrentLogLine != null) + { + JObject lastEvent = JObject.Parse(CurrentLogLine); + LastScanValid = false; + //Journals prior to Elite Dangerous 2.3 "The Commanders" had differently formatted scan events which I can't be bothered to support. + if (DateTime.Parse(lastEvent["timestamp"].ToString(), null, System.Globalization.DateTimeStyles.RoundtripKind) > new DateTime(2017, 04, 12)) + { + switch (lastEvent["event"].ToString()) + { + case "Scan": + LastScan = lastEvent.ToObject(); + SystemBody[(CurrentSystem, LastScan.BodyId)] = LastScan; + LastScanValid = true; + break; + case "FSDJump": + case "Location": + CurrentSystem = lastEvent["StarSystem"].ToString(); + break; + case "FSSDiscoveryScan": + case "FSSAllBodiesFound": + if (lastEvent["SystemName"] != null) + { + CurrentSystem = lastEvent["SystemName"].ToString(); + } + break; + default: + break; + } + } + } + } + //Garbage data from unexpected games crashes during journal writes can happen, ignore it. + catch (Newtonsoft.Json.JsonReaderException ex) + { + JsonException = ex.Message; + return; + } + + EventHandler entry = LogEntry; + entry?.Invoke(this, EventArgs.Empty); + } + + public event EventHandler LogEntry; + } +} diff --git a/EDDisco/Program.cs b/EDDisco/Program.cs deleted file mode 100644 index ef28e6e..0000000 --- a/EDDisco/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace EDDisco -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/EDDisco/Properties/AssemblyInfo.cs b/EDDisco/Properties/AssemblyInfo.cs index 9c9a366..3fed2ed 100644 --- a/EDDisco/Properties/AssemblyInfo.cs +++ b/EDDisco/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("0.1.19.165")] +[assembly: AssemblyFileVersion("0.1.19.165")] diff --git a/EDDisco/ScanEvent.cs b/EDDisco/ScanEvent.cs new file mode 100644 index 0000000..cc88001 --- /dev/null +++ b/EDDisco/ScanEvent.cs @@ -0,0 +1,209 @@ +using System; +using Newtonsoft.Json; + +namespace EDDisco +{ + + public partial class ScanEvent + { + private ParentObject[] ParentObjects; + + [JsonProperty("timestamp")] + public DateTime Timestamp { get; set; } + + [JsonProperty("event")] + public string Event { get; set; } + + [JsonProperty("ScanType")] + public string ScanType { get; set; } + + [JsonProperty("BodyName")] + public string BodyName { get; set; } + + [JsonProperty("BodyID")] + public long BodyId { get; set; } + + [JsonProperty("Parents", NullValueHandling = NullValueHandling.Ignore)] + public ParentObject[] Parents { + get + { + return ParentObjects; + } + set + { + ParentObjects = value; + Parent = new (string, long)[value.Length]; + for (int i = 0; i < value.Length; i++) + { + if (value[i].Null != null) + { + Parent[i] = ("Null", (long)value[i].Null); + } + else if (value[i].Planet != null) + { + Parent[i] = ("Planet", (long)value[i].Planet); + } + else if (value[i].Star != null) + { + Parent[i] = ("Star", (long)value[i].Star); + } + } + } + } + + public (string,long)[] Parent { get; private set; } + + [JsonProperty("DistanceFromArrivalLS")] + public double DistanceFromArrivalLs { get; set; } + + [JsonProperty("TidalLock", NullValueHandling = NullValueHandling.Ignore)] + public bool? TidalLock { get; set; } + + [JsonProperty("TerraformState", NullValueHandling = NullValueHandling.Ignore)] + public string TerraformState { get; set; } + + [JsonProperty("PlanetClass", NullValueHandling = NullValueHandling.Ignore)] + public string PlanetClass { get; set; } + + [JsonProperty("Atmosphere", NullValueHandling = NullValueHandling.Ignore)] + public string Atmosphere { get; set; } + + [JsonProperty("AtmosphereType", NullValueHandling = NullValueHandling.Ignore)] + public string AtmosphereType { get; set; } + + [JsonProperty("AtmosphereComposition", NullValueHandling = NullValueHandling.Ignore)] + public MaterialComposition[] AtmosphereComposition { get; set; } + + [JsonProperty("Volcanism", NullValueHandling = NullValueHandling.Ignore)] + public string Volcanism { get; set; } + + [JsonProperty("MassEM", NullValueHandling = NullValueHandling.Ignore)] + public double? MassEm { get; set; } + + [JsonProperty("Radius", NullValueHandling = NullValueHandling.Ignore)] + public double? Radius { get; set; } + + [JsonProperty("SurfaceGravity", NullValueHandling = NullValueHandling.Ignore)] + public double? SurfaceGravity { get; set; } + + [JsonProperty("SurfaceTemperature", NullValueHandling = NullValueHandling.Ignore)] + public double? SurfaceTemperature { get; set; } + + [JsonProperty("SurfacePressure", NullValueHandling = NullValueHandling.Ignore)] + public double? SurfacePressure { get; set; } + + [JsonProperty("Landable", NullValueHandling = NullValueHandling.Ignore)] + public bool? Landable { get; set; } + + [JsonProperty("Materials", NullValueHandling = NullValueHandling.Ignore)] + public MaterialComposition[] Materials { get; set; } + + [JsonProperty("Composition", NullValueHandling = NullValueHandling.Ignore)] + public Composition Composition { get; set; } + + [JsonProperty("SemiMajorAxis", NullValueHandling = NullValueHandling.Ignore)] + public long? SemiMajorAxis { get; set; } + + [JsonProperty("Eccentricity", NullValueHandling = NullValueHandling.Ignore)] + public double? Eccentricity { get; set; } + + [JsonProperty("OrbitalInclination", NullValueHandling = NullValueHandling.Ignore)] + public double? OrbitalInclination { get; set; } + + [JsonProperty("Periapsis", NullValueHandling = NullValueHandling.Ignore)] + public double? Periapsis { get; set; } + + [JsonProperty("OrbitalPeriod", NullValueHandling = NullValueHandling.Ignore)] + public long? OrbitalPeriod { get; set; } + + [JsonProperty("RotationPeriod", NullValueHandling = NullValueHandling.Ignore)] + public double? RotationPeriod { get; set; } + + [JsonProperty("AxialTilt", NullValueHandling = NullValueHandling.Ignore)] + public double? AxialTilt { get; set; } + + [JsonProperty("Rings", NullValueHandling = NullValueHandling.Ignore)] + public Ring[] Rings { get; set; } + + [JsonProperty("ReserveLevel", NullValueHandling = NullValueHandling.Ignore)] + public string ReserveLevel { get; set; } + + [JsonProperty("StarType", NullValueHandling = NullValueHandling.Ignore)] + public string StarType { get; set; } + + [JsonProperty("Subclass", NullValueHandling = NullValueHandling.Ignore)] + public long? Subclass { get; set; } + + [JsonProperty("StellarMass", NullValueHandling = NullValueHandling.Ignore)] + public double? StellarMass { get; set; } + + [JsonProperty("AbsoluteMagnitude", NullValueHandling = NullValueHandling.Ignore)] + public double? AbsoluteMagnitude { get; set; } + + [JsonProperty("Age_MY", NullValueHandling = NullValueHandling.Ignore)] + public long? Age_MY { get; set; } + + [JsonProperty("Luminosity", NullValueHandling = NullValueHandling.Ignore)] + public string Luminosity { get; set; } + + [JsonProperty("WasDiscovered")] + public bool WasDiscovered { get; set; } + + [JsonProperty("WasMapped")] + public bool WasMapped { get; set; } + } + + public partial class MaterialComposition + { + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("Percent")] + public double Percent { get; set; } + } + + public partial class Composition + { + [JsonProperty("Ice")] + public double Ice { get; set; } + + [JsonProperty("Rock")] + public double Rock { get; set; } + + [JsonProperty("Metal")] + public double Metal { get; set; } + } + + public partial class ParentObject + { + [JsonProperty("Star", NullValueHandling = NullValueHandling.Ignore)] + public long? Star { get; set; } + + [JsonProperty("Null", NullValueHandling = NullValueHandling.Ignore)] + public long? Null { get; set; } + + [JsonProperty("Ring", NullValueHandling = NullValueHandling.Ignore)] + public long? Ring { get; set; } + + [JsonProperty("Planet", NullValueHandling = NullValueHandling.Ignore)] + public long? Planet { get; set; } + } + + public partial class Ring + { + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("RingClass")] + public string RingClass { get; set; } + + [JsonProperty("MassMT", NullValueHandling = NullValueHandling.Ignore)] + public long? MassMT { get; set; } + + [JsonProperty("InnerRad", NullValueHandling = NullValueHandling.Ignore)] + public long? InnerRad { get; set; } + + [JsonProperty("OuterRad", NullValueHandling = NullValueHandling.Ignore)] + public long? OuterRad { get; set; } + } +} diff --git a/EDDisco/ScanReader.cs b/EDDisco/ScanReader.cs new file mode 100644 index 0000000..d1a7394 --- /dev/null +++ b/EDDisco/ScanReader.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EDDisco +{ + class ScanReader + { + private readonly ScanEvent scanEvent; + private readonly Dictionary<(string, long), ScanEvent> scanHistory; + private readonly string currentSystem; + public List<(string,string,string)> Interest { get; private set; } + + public ScanReader (ScanEvent scanEvent, Dictionary<(string,long),ScanEvent> scanHistory, string currentSystem) + { + this.scanEvent = scanEvent; + this.scanHistory = scanHistory; + this.currentSystem = currentSystem; + Interest = new List<(string,string,string)>(); + } + + public bool IsInteresting() + { + bool interesting = DefaultInterest() | CustomInterest(); + if (Interest.Count() == 0) + { + Interest.Add((scanEvent.BodyName, "Uninteresting", string.Empty)); + } + return interesting; + } + + private bool DefaultInterest() + { + // Landable and has a terraform state + if (scanEvent.Landable.GetValueOrDefault(false) && scanEvent.TerraformState.Length > 0) + { + Interest.Add((scanEvent.BodyName, $"Landable and {scanEvent.TerraformState}", string.Empty)); + } + + // Landable with atmosphere. Futureproofing! + if (scanEvent.Landable.GetValueOrDefault(false) && scanEvent.Atmosphere.Length > 0) + { + Interest.Add((scanEvent.BodyName, "Landable with Atmosphere?!", string.Empty)); + } + + // Landable high-g + if (scanEvent.Landable.GetValueOrDefault(false) && scanEvent.SurfaceGravity > 29.4) + { + Interest.Add((scanEvent.BodyName, "Landable with High Gravity", $"Surface gravity: {((double)scanEvent.SurfaceGravity / 9.81).ToString("0.00")}g")); + } + + //Parent relative checks + if ((scanEvent.Parent?[0].Item1 == "Planet" || scanEvent.Parent?[0].Item1 == "Star") && + !scanEvent.BodyName.Contains(" Ring") && + scanHistory.ContainsKey((currentSystem, scanEvent.Parent[0].Item2))) + { + ScanEvent parent = scanHistory[(currentSystem, scanEvent.Parent[0].Item2)]; + + //Close orbit + if (parent.Radius * 3 > scanEvent.SemiMajorAxis) + { + Interest.Add((scanEvent.BodyName, "Close orbit relative to parent body size", $"Orbit: {Math.Truncate((double)scanEvent.SemiMajorAxis / 1000):N0}km, Parent radius: {Math.Truncate((double)parent.Radius / 1000):N0}km")); + } + + //Body inside ring + if (parent.Rings?.Last().OuterRad > scanEvent.SemiMajorAxis && !parent.Rings.Last().Name.Contains(" Belt")) + { + Interest.Add((scanEvent.BodyName, "Orbit closer than outermost ring edge", $"Orbit: {Math.Truncate((double)scanEvent.SemiMajorAxis / 1000):N0}km, Ring radius: {Math.Truncate((double)parent.Rings.Last().OuterRad / 1000):N0}km")); + } + + } + + // Close binary pair + if (scanEvent.Parent?[0].Item1 == "Null" && scanEvent.Radius / scanEvent.SemiMajorAxis > 0.5) + { + var binaryPartner = scanHistory.Where(system => system.Key.Item1 == currentSystem && scanEvent.Parent?[0].Item2 == system.Value.Parent?[0].Item2 && scanEvent.BodyId != system.Value.BodyId); + if (binaryPartner.Count() == 1) + { + if (binaryPartner.First().Value.Radius / binaryPartner.First().Value.SemiMajorAxis > 0.5) + { + if (binaryPartner.First().Value.Radius + scanEvent.Radius >= binaryPartner.First().Value.SemiMajorAxis * (1 - binaryPartner.First().Value.Eccentricity) + scanEvent.SemiMajorAxis * (1 - scanEvent.Eccentricity)) + { + Interest.Add((scanEvent.BodyName, "COLLIDING binary", $"Orbit: {Math.Truncate((double)scanEvent.SemiMajorAxis / 1000):N0}km, Radius: {Math.Truncate((double)scanEvent.Radius / 1000):N0}km, Partner: {binaryPartner.First().Value.BodyName}")); + } + else + { + Interest.Add((scanEvent.BodyName, "Close binary relative to body size", $"Orbit: {Math.Truncate((double)scanEvent.SemiMajorAxis / 1000):N0}km, Radius: {Math.Truncate((double)scanEvent.Radius / 1000):N0}km, Partner: {binaryPartner.First().Value.BodyName}")); + } + } + } + } + + // Moon of a moon + if (scanEvent.Parent?.Count() > 1 && scanEvent.Parent[0].Item1 == "Planet" && scanEvent.Parent[1].Item1 == "Planet") + { + Interest.Add((scanEvent.BodyName, "Nested Moon", string.Empty)); + } + + // Tiny object + if (scanEvent.StarType == null && scanEvent.Radius < 300000) + { + Interest.Add((scanEvent.BodyName, "Small Body", $"Radius: {Math.Truncate((double)scanEvent.Radius / 1000)}km")); + } + + // Fast rotation + if (scanEvent.RotationPeriod != null && !scanEvent.TidalLock.GetValueOrDefault(true) && Math.Abs((double)scanEvent.RotationPeriod) < 28800) + { + Interest.Add((scanEvent.BodyName, "Non-locked body with fast rotation", $"Rotational period: {Math.Abs(Math.Round((decimal)scanEvent.RotationPeriod / 3600, 1))} hours")); + } + + // Fast orbit + if (scanEvent.OrbitalPeriod != null && Math.Abs((double)scanEvent.OrbitalPeriod) < 28800) + { + Interest.Add((scanEvent.BodyName, "Fast orbit", $"Orbital Period: {Math.Abs(Math.Round((decimal)scanEvent.OrbitalPeriod / 3600, 1))} hours")); + } + + // High eccentricity + if (scanEvent.Eccentricity > 0.9) + { + Interest.Add((scanEvent.BodyName, "Highly eccentric orbit", $"Eccentricity: {Math.Round((decimal)scanEvent.Eccentricity, 2)}")); + } + + // Good jumponium material availability + if (scanEvent.Landable.GetValueOrDefault(false)) + { + int jumpMats = 0; + string matsNotFound = "carbongermaniumarsenicniobiumyttriumpolonium"; + foreach (MaterialComposition material in scanEvent.Materials) + { + switch (material.Name.ToLower()) + { + case "carbon": + case "germanium": + case "arsenic": + case "niobium": + case "yttrium": + case "polonium": + jumpMats++; + matsNotFound = matsNotFound.Replace(material.Name.ToLower(), string.Empty); + break; + } + } + if (jumpMats == 6) + { + Interest.Add((scanEvent.BodyName, "One stop jumponium shop", string.Empty)); + } + else if (jumpMats == 5) + { + Interest.Add((scanEvent.BodyName, "5 out of 6 jumponium materials", $"Missing material: {matsNotFound}")); + } + } + + // Add note if multiple checks triggered + if (Interest.Count() > 1) + { + Interest.Add((scanEvent.BodyName, $"{(Interest.Count() > 2 ? "Very":"More")} Interesting Object", string.Empty)); + } + + // Check history to determine if all jumponium materials available in system + if (scanEvent.Landable.GetValueOrDefault(false)) + { + string matsNotFound = "carbongermaniumarsenicniobiumyttriumpolonium"; + foreach (var scan in scanHistory) + { + if (scan.Key.Item1 == currentSystem && scan.Value.Landable.GetValueOrDefault(false)) + { + foreach (MaterialComposition material in scan.Value.Materials) + { + switch (material.Name.ToLower()) + { + case "carbon": + case "germanium": + case "arsenic": + case "niobium": + case "yttrium": + case "polonium": + matsNotFound = matsNotFound.Replace(material.Name.ToLower(), string.Empty); + break; + } + if (matsNotFound.Length == 0) + { + Interest.Add((currentSystem, "All jumponium materials in system", string.Empty)); + break; + } + } + } + } + } + + return Interest.Count > 0; + } + + private bool CustomInterest() + { + return false; + } + } +} diff --git a/EDDisco/packages.config b/EDDisco/packages.config new file mode 100644 index 0000000..581195b --- /dev/null +++ b/EDDisco/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file