diff --git a/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs b/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs index 3108bf5fe..bf5206039 100644 --- a/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs +++ b/src/Artemis.UI.Windows/Providers/AutoRunProvider.cs @@ -105,7 +105,7 @@ public class AutoRunProvider : IAutoRunProvider /// public async Task EnableAutoRun(bool recreate, int autoRunDelay) { - if (Constants.CurrentVersion == "development") + if (Constants.CurrentVersion == "local") return; await CleanupOldAutorun(); diff --git a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs index ed241cf62..cd7d5c186 100644 --- a/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs +++ b/src/Artemis.UI.Windows/Providers/WindowsUpdateNotificationProvider.cs @@ -110,7 +110,7 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider // If the main window is not open the user isn't busy, restart straight away if (!_mainWindowService.IsMainWindowOpen) { - _updateService.RestartForUpdate(true); + _updateService.RestartForUpdate("WindowsNotification", true); return; } @@ -165,6 +165,6 @@ public class WindowsUpdateNotificationProvider : IUpdateNotificationProvider else if (action == "cancel") _cancellationTokenSource?.Cancel(); else if (action == "restart-for-update") - _updateService.RestartForUpdate(false); + _updateService.RestartForUpdate("WindowsNotification", false); } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Artemis.UI/Screens/Root/RootViewModel.cs index f97399a7e..141566ff1 100644 --- a/src/Artemis.UI/Screens/Root/RootViewModel.cs +++ b/src/Artemis.UI/Screens/Root/RootViewModel.cs @@ -62,7 +62,6 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv router.SetRoot(this); mainWindowService.ConfigureMainWindowProvider(this); - DisplayAccordingToSettings(); OpenScreen = ReactiveCommand.Create(ExecuteOpenScreen); OpenDebugger = ReactiveCommand.CreateFromTask(ExecuteOpenDebugger); Exit = ReactiveCommand.CreateFromTask(ExecuteExit); @@ -74,10 +73,17 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv .Select(vm => vm ?? _defaultTitleBarViewModel) .ToProperty(this, vm => vm.TitleBarViewModel); + if (ShouldShowUI()) + { + ShowSplashScreen(); + _coreService.Initialized += (_, _) => Dispatcher.UIThread.InvokeAsync(OpenMainWindow); + } + Task.Run(() => { // Before doing heavy lifting, initialize the update service which may prompt a restart - if (_updateService.Initialize()) + // Only initialize with an update check if we're not going to show the UI + if (_updateService.Initialize(!ShouldShowUI())) return; // Workshop service goes first so it has a chance to clean up old workshop entries and introduce new ones @@ -118,17 +124,13 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv OnMainWindowClosed(); } - private void DisplayAccordingToSettings() + private bool ShouldShowUI() { bool autoRunning = Constants.StartupArguments.Contains("--autorun"); bool minimized = Constants.StartupArguments.Contains("--minimized"); bool showOnAutoRun = _settingsService.GetSetting("UI.ShowOnStartup", true).Value; - if ((autoRunning && !showOnAutoRun) || minimized) - return; - - ShowSplashScreen(); - _coreService.Initialized += (_, _) => Dispatcher.UIThread.InvokeAsync(OpenMainWindow); + return (autoRunning && showOnAutoRun) || !minimized; } private void ShowSplashScreen() diff --git a/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsViewModel.cs b/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsViewModel.cs index cf3026879..23d3b9fbb 100644 --- a/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Updating/ReleaseDetailsViewModel.cs @@ -87,7 +87,7 @@ public partial class ReleaseDetailsViewModel : RoutableScreen - diff --git a/src/Artemis.UI/SerilogAvaloniaSink.cs b/src/Artemis.UI/SerilogAvaloniaSink.cs index d47382bf2..f40c83b28 100644 --- a/src/Artemis.UI/SerilogAvaloniaSink.cs +++ b/src/Artemis.UI/SerilogAvaloniaSink.cs @@ -22,8 +22,13 @@ public class SerilogAvaloniaSink : ILogSink { SerilogLogLevel logLevel = GetSerilogLogLevel(level, area); + #if DEBUG // Except with binding errors, ignore anything that is information or lower return (area == "Binding" || logLevel > SerilogLogLevel.Information) && _logger.IsEnabled(logLevel); + #else + // Ignore binding errors in release builds, shoo + return area != "Binding" && logLevel > SerilogLogLevel.Information && _logger.IsEnabled(logLevel); + #endif } /// diff --git a/src/Artemis.UI/Services/Updating/IUpdateService.cs b/src/Artemis.UI/Services/Updating/IUpdateService.cs index 225ecbd97..840253d3f 100644 --- a/src/Artemis.UI/Services/Updating/IUpdateService.cs +++ b/src/Artemis.UI/Services/Updating/IUpdateService.cs @@ -42,12 +42,14 @@ public interface IUpdateService : IArtemisUIService /// /// Restarts the application to install a pending update. /// + /// The source from which the restart is requested. /// A boolean indicating whether to perform a silent install of the update. - void RestartForUpdate(bool silent); + void RestartForUpdate(string source, bool silent); /// /// Initializes the update service. /// + /// /// A boolean indicating whether a restart will occur to install a pending update. - bool Initialize(); + bool Initialize(bool performAutoUpdate); } \ No newline at end of file diff --git a/src/Artemis.UI/Services/Updating/UpdateService.cs b/src/Artemis.UI/Services/Updating/UpdateService.cs index 15e66985e..deb6484ea 100644 --- a/src/Artemis.UI/Services/Updating/UpdateService.cs +++ b/src/Artemis.UI/Services/Updating/UpdateService.cs @@ -104,19 +104,19 @@ public class UpdateService : IUpdateService { ReleaseInstaller installer = _getReleaseInstaller(release.Id); await installer.InstallAsync(CancellationToken.None); - RestartForUpdate(true); + RestartForUpdate("AutoInstallUpdate", true); } private async void HandleAutoUpdateEvent(object? sender, EventArgs e) { if (Constants.CurrentVersion == "local") return; - - // The event can trigger from multiple sources with a timer acting as a fallback, only actual perform an action once per max 59 minutes + + // The event can trigger from multiple sources with a timer acting as a fallback, only actually perform an action once per max 59 minutes if (DateTime.UtcNow - _lastAutoUpdateCheck < TimeSpan.FromMinutes(59)) return; _lastAutoUpdateCheck = DateTime.UtcNow; - + if (!_autoCheck.Value || _suspendAutoCheck) return; @@ -157,7 +157,7 @@ public class UpdateService : IUpdateService public async Task CheckForUpdate() { _logger.Information("Performing auto-update check"); - + IOperationResult result = await _updatingClient.GetNextRelease.ExecuteAsync(Constants.CurrentVersion, Channel, _updatePlatform); result.EnsureNoErrors(); @@ -171,7 +171,7 @@ public class UpdateService : IUpdateService // Unless auto install is enabled, only offer it once per session if (!_autoInstall.Value) _suspendAutoCheck = true; - + // If the window is open show the changelog, don't auto-update while the user is busy if (_mainWindowService.IsMainWindowOpen || !_autoInstall.Value) { @@ -194,8 +194,10 @@ public class UpdateService : IUpdateService } /// - public void RestartForUpdate(bool silent) + public void RestartForUpdate(string source, bool silent) { + _logger.Information("Restarting for update required by {Source}, silent: {Silent}", source, silent); + if (!Directory.Exists(Path.Combine(Constants.UpdatingFolder, "pending"))) throw new ArtemisUIException("Cannot install update, none is pending."); @@ -204,11 +206,11 @@ public class UpdateService : IUpdateService } /// - public bool Initialize() + public bool Initialize(bool performAutoUpdate) { if (Constants.CurrentVersion == "local") return false; - + string? channelArgument = Constants.StartupArguments.FirstOrDefault(a => a.StartsWith("--channel=")); if (channelArgument != null) Channel = channelArgument.Split("=")[1]; @@ -235,7 +237,7 @@ public class UpdateService : IUpdateService _logger.Information("Installing pending update"); try { - RestartForUpdate(true); + RestartForUpdate("PendingFolder", true); return true; } catch (Exception e) @@ -246,9 +248,10 @@ public class UpdateService : IUpdateService } ProcessReleaseStatus(); - + // Trigger the auto update event so that it doesn't take an hour for the first check to happen - HandleAutoUpdateEvent(this, EventArgs.Empty); + if (performAutoUpdate) + HandleAutoUpdateEvent(this, EventArgs.Empty); _logger.Information("Update service initialized for {Channel} channel", Channel); return false; diff --git a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs index e9c46ba11..0721c97f0 100644 --- a/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs +++ b/src/Artemis.WebClient.Workshop/Services/WorkshopService.cs @@ -179,12 +179,26 @@ public class WorkshopService : IWorkshopService { if (_initialized) throw new ArtemisWorkshopException("Workshop service is already initialized"); - - RemoveOrphanedFiles(); - _pluginManagementService.AdditionalPluginDirectories.AddRange(GetInstalledEntries().Where(e => e.EntryType == EntryType.Plugin).Select(e => e.GetReleaseDirectory())); - _initialized = true; + + try + { + if (!Directory.Exists(Constants.WorkshopFolder)) + Directory.CreateDirectory(Constants.WorkshopFolder); + + RemoveOrphanedFiles(); + + _pluginManagementService.AdditionalPluginDirectories.AddRange(GetInstalledEntries() + .Where(e => e.EntryType == EntryType.Plugin) + .Select(e => e.GetReleaseDirectory())); + + _initialized = true; + } + catch (Exception e) + { + _logger.Error(e, "Failed to initialize workshop service"); + } } - + private void RemoveOrphanedFiles() { List entries = GetInstalledEntries();