diff --git a/ObservatoryBotanist/Botanist.cs b/ObservatoryBotanist/Botanist.cs index 0540a72..339e66d 100644 --- a/ObservatoryBotanist/Botanist.cs +++ b/ObservatoryBotanist/Botanist.cs @@ -30,7 +30,11 @@ namespace Observatory.Botanist ObservableCollection GridCollection; private PluginUI pluginUI; private bool readAllInProgress = false; - + private Guid? samplerStatusNotification = null; + private BotanistSettings botanistSettings = new() + { + OverlayEnabled = true, + }; public string Name => "Observatory Botanist"; public string ShortName => "Botanist"; @@ -39,7 +43,7 @@ namespace Observatory.Botanist public PluginUI PluginUI => pluginUI; - public object Settings { get => null; set { } } + public object Settings { get => botanistSettings; set { botanistSettings = (BotanistSettings)value; } } public void JournalEvent(TJournal journal) where TJournal : JournalBase { @@ -82,7 +86,7 @@ namespace Observatory.Botanist var systemBodyId = (scanOrganic.SystemAddress, scanOrganic.Body); if (!BioPlanets.ContainsKey(systemBodyId)) { - //Unlikely to ever end up in here, but just in case create a new planet entry. + // Unlikely to ever end up in here, but just in case create a new planet entry. List genus = new(); List species = new(); genus.Add(scanOrganic.Genus_Localised); @@ -98,6 +102,25 @@ namespace Observatory.Botanist { case ScanOrganicType.Log: case ScanOrganicType.Sample: + if (!readAllInProgress && botanistSettings.OverlayEnabled) + { + NotificationArgs args = new() + { + Title = scanOrganic.Species_Localised, + Detail = string.Format("Sample {0} of 3", scanOrganic.ScanType == ScanOrganicType.Log ? 1 : 2), + Rendering = NotificationRendering.NativeVisual, + Timeout = 0, + }; + if (samplerStatusNotification == null) + { + samplerStatusNotification = Core.SendNotification(args); + } + else + { + Core.UpdateNotification(samplerStatusNotification.Value, args); + } + } + if (!bioPlanet.speciesFound.Contains(scanOrganic.Species_Localised)) { bioPlanet.speciesFound.Add(scanOrganic.Species_Localised); @@ -108,12 +131,30 @@ namespace Observatory.Botanist { bioPlanet.speciesAnalysed.Add(scanOrganic.Species_Localised); } + MaybeCloseSamplerStatusNotification(); break; } } UpdateUIGrid(); } break; + case LeaveBody: + case FSDJump: + case Shutdown: + // These are all good reasons to kill any open notification. Note that SupercruiseEntry is NOT a + // suitable reason to close the notification as the player hopping out only to double check the + // DSS map for another location. Note that a game client crash will not close the status notification. + MaybeCloseSamplerStatusNotification(); + break; + } + } + + private void MaybeCloseSamplerStatusNotification() + { + if (samplerStatusNotification != null) + { + Core.CancelNotification(samplerStatusNotification.Value); + samplerStatusNotification = null; } } diff --git a/ObservatoryBotanist/BotanistSettings.cs b/ObservatoryBotanist/BotanistSettings.cs new file mode 100644 index 0000000..edf6018 --- /dev/null +++ b/ObservatoryBotanist/BotanistSettings.cs @@ -0,0 +1,15 @@ +using Observatory.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Observatory.Botanist +{ + class BotanistSettings + { + [SettingDisplayName("Enable Sampler Status Overlay")] + public bool OverlayEnabled { get; set; } + } +} diff --git a/ObservatoryCore/LogMonitor.cs b/ObservatoryCore/LogMonitor.cs index 1a96061..73daf38 100644 --- a/ObservatoryCore/LogMonitor.cs +++ b/ObservatoryCore/LogMonitor.cs @@ -111,6 +111,7 @@ namespace Observatory // Read at most the last two files (in case we were launched after the game and the latest // journal is mostly empty) but keeping only the lines since the last FSDJump. List lastSystemLines = new(); + List lastFileLines = new(); string lastLoadGame = String.Empty; bool sawFSDJump = false; foreach (var file in files.Skip(Math.Max(files.Length - 2, 0))) @@ -125,29 +126,38 @@ namespace Observatory lastSystemLines.Clear(); sawFSDJump = true; } + else if (eventType.Equals("Fileheader")) + { + lastFileLines.Clear(); + } else if (eventType.Equals("LoadGame")) { lastLoadGame = line; } lastSystemLines.Add(line); + lastFileLines.Add(line); } } - // So we didn't see a jump in the recent logs. We could be re-logging, or something. - // Just bail on this attempt. - if (!sawFSDJump) return; - - // If we saw a LoadGame, insert it as well. This ensures odyssey biologicials are properly - // counted/presented. - if (!String.IsNullOrEmpty(lastLoadGame)) + // If we didn't see a jump in the recent logs (Cmdr is stationary in a system for a while + // ie. deep-space mining from a carrier), at very least, read from the beginning of the + // current journal file which includes the important stuff like the last "LoadGame", etc. This + // also helps out in cases where one forgets to hit "Start Monitor" until part-way into the + // session (if auto-start is not enabled). + List linesToRead = lastFileLines; + if (sawFSDJump) { - lastSystemLines.Insert(0, lastLoadGame); + // If we saw a LoadGame, insert it as well. This ensures odyssey biologicials are properly + // counted/presented. + if (!String.IsNullOrEmpty(lastLoadGame)) + { + lastSystemLines.Insert(0, lastLoadGame); + } + linesToRead = lastSystemLines; } - // We found an FSD jump, buffered the lines for that system (possibly including startup logs - // over a file boundary). Pump these through the plugins. readall = true; - ReportErrors(ProcessLines(lastSystemLines, "Pre-read")); + ReportErrors(ProcessLines(linesToRead, "Pre-read")); readall = false; } diff --git a/ObservatoryCore/PluginManagement/PluginManager.cs b/ObservatoryCore/PluginManagement/PluginManager.cs index 628d74c..e0780f7 100644 --- a/ObservatoryCore/PluginManagement/PluginManager.cs +++ b/ObservatoryCore/PluginManagement/PluginManager.cs @@ -250,7 +250,7 @@ namespace Observatory.PluginManagement //Importing Observatory.Framework in the Explorer Lua scripts causes an attempt to reload //the assembly, just hand it back the one we already have. - if (name.Name.StartsWith("Observatory.Framework")) + if (name.Name.StartsWith("Observatory.Framework") || name.Name == "ObservatoryFramework") { return context.Assemblies.Where(a => a.FullName.Contains("ObservatoryFramework")).First(); } diff --git a/ObservatoryFramework/Files/Journal/Startup/Cargo.cs b/ObservatoryFramework/Files/Journal/Startup/Cargo.cs index 68d372a..8742a7d 100644 --- a/ObservatoryFramework/Files/Journal/Startup/Cargo.cs +++ b/ObservatoryFramework/Files/Journal/Startup/Cargo.cs @@ -1,4 +1,5 @@ -using System.Collections.Immutable; +using Observatory.Framework.Files.ParameterTypes; +using System.Collections.Immutable; namespace Observatory.Framework.Files.Journal { @@ -6,6 +7,6 @@ namespace Observatory.Framework.Files.Journal { public string Vessel { get; init; } public int Count { get; init; } - public ImmutableList Inventory { get; init; } + public ImmutableList Inventory { get; init; } } } diff --git a/buildAllComponents b/buildAllComponents new file mode 100755 index 0000000..dfe5b86 --- /dev/null +++ b/buildAllComponents @@ -0,0 +1,8 @@ +#!/bin/bash +dotnet build ./ObservatoryFramework/ObservatoryFramework.csproj "$@" +dotnet build ./ObservatoryExplorer/ObservatoryExplorer.csproj "$@" +dotnet build ./ObservatoryBotanist/ObservatoryBotanist.csproj "$@" +if [ -f ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj ]; then + dotnet build ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj -c Release + dotnet build ./ObservatoryHerald/ObservatoryHerald.csproj "$@" +fi diff --git a/buildAllComponents.cmd b/buildAllComponents.cmd new file mode 100644 index 0000000..0102a06 --- /dev/null +++ b/buildAllComponents.cmd @@ -0,0 +1,7 @@ +dotnet build ./ObservatoryFramework/ObservatoryFramework.csproj %* +dotnet build ./ObservatoryExplorer/ObservatoryExplorer.csproj %* +dotnet build ./ObservatoryBotanist/ObservatoryBotanist.csproj %* +IF EXIST ..\NetCoreAudio\NetCoreAudio\NetCoreAudio.csproj ( + dotnet build ../NetCoreAudio/NetCoreAudio/NetCoreAudio.csproj -c Release + dotnet build ./ObservatoryHerald/ObservatoryHerald.csproj %* +)