From 6a8750566edd04d8b8f499f6d05e73a713e83940 Mon Sep 17 00:00:00 2001 From: maj00r Date: Sun, 4 Oct 2026 18:58:29 +0200 Subject: [PATCH] Look for the simulator when the picked one is not in this installation The pick is kept in the per-user eu07.ini, which every installation shares, so a binary chosen in one folder was missing in another and the starter complained although a simulator sat right there. A missing pick now gives way to the search and is logged once. --- StarterNG.Tests/ExecutableLocatorTests.cs | 25 +++++++++++++++++ .../Settings/ExecutableLocator.cs | 28 ++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/StarterNG.Tests/ExecutableLocatorTests.cs b/StarterNG.Tests/ExecutableLocatorTests.cs index 84a4fb9..01f45a1 100644 --- a/StarterNG.Tests/ExecutableLocatorTests.cs +++ b/StarterNG.Tests/ExecutableLocatorTests.cs @@ -68,6 +68,31 @@ public class ExecutableLocatorTests Assert.Equal(ExeProblem.None, problem); } + [Fact] + public void A_pick_from_another_installation_gives_way_to_the_search() + { + var files = new InMemoryFileSystem().WithExecutable(TestInstallation.At("eu07"), Elf); + var installation = new TestInstallation(files); + var settings = new SimulatorSettings { SelectExeAutomatically = false, ExecutablePath = "eu07-elsewhere" }; + + string resolved = installation.Executables.Resolve(settings, out var problem); + + Assert.EndsWith("eu07", resolved); + Assert.Equal(ExeProblem.None, problem); + } + + [Fact] + public void A_missing_pick_is_reported_when_the_installation_has_none_either() + { + var installation = new TestInstallation(); + var settings = new SimulatorSettings { SelectExeAutomatically = false, ExecutablePath = "eu07-elsewhere" }; + + string resolved = installation.Executables.Resolve(settings, out var problem); + + Assert.Equal("eu07-elsewhere", resolved); + Assert.Equal(ExeProblem.NotFound, problem); + } + [Fact] public void Data_files_beside_the_binary_are_never_offered_as_candidates() { diff --git a/StarterNG/Infrastructure/Settings/ExecutableLocator.cs b/StarterNG/Infrastructure/Settings/ExecutableLocator.cs index ddfdb96..cf580d2 100644 --- a/StarterNG/Infrastructure/Settings/ExecutableLocator.cs +++ b/StarterNG/Infrastructure/Settings/ExecutableLocator.cs @@ -21,6 +21,7 @@ public sealed class ExecutableLocator private string? _wine; private bool _wineLookedUp; + private string? _missingPickLogged; public ExecutableLocator(IFileSystem files, IGamePaths paths, IEnvironment environment, IDiagnosticsLog log) { @@ -32,14 +33,39 @@ public sealed class ExecutableLocator public string CanonicalName => _environment.IsWindows ? "eu07.exe" : "eu07"; + /// + /// The simulator to start: the one picked in the settings, or the best one in + /// the installation. A pick that is not there - the settings live per user and + /// are shared by every installation, so it may come from another one - gives + /// way to the search rather than stopping the start. + /// public string Resolve(SimulatorSettings settings, out ExeProblem problem) { if (!settings.SelectExeAutomatically && !string.IsNullOrWhiteSpace(settings.ExecutablePath)) { problem = Validate(FullPath(settings.ExecutablePath)); - return settings.ExecutablePath; + if (problem != ExeProblem.NotFound) + return settings.ExecutablePath; + + string found = Search(out var searched); + if (searched == ExeProblem.NotFound) + return settings.ExecutablePath; + + // Resolved on every start and for the title bar, so said once. + if (_missingPickLogged != settings.ExecutablePath) + { + _log.Log($"The chosen simulator {settings.ExecutablePath} is not in {_paths.Root}, using {found}"); + _missingPickLogged = settings.ExecutablePath; + } + problem = searched; + return found; } + return Search(out problem); + } + + private string Search(out ExeProblem problem) + { string? fallback = null; try {