diff --git a/osu.Desktop/Overlays/SquirrelUpdateManager.cs b/osu.Desktop/Overlays/SquirrelUpdateManager.cs new file mode 100644 index 0000000000..1c1ba6a3ad --- /dev/null +++ b/osu.Desktop/Overlays/SquirrelUpdateManager.cs @@ -0,0 +1,158 @@ +#if NET_FRAMEWORK +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Logging; +using osu.Game; +using osu.Game.Graphics; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; +using OpenTK; +using OpenTK.Graphics; +using Squirrel; + +namespace osu.Desktop.Overlays +{ + public class SquirrelUpdateManager : Component + { + private UpdateManager updateManager; + private NotificationOverlay notificationOverlay; + + public void PrepareUpdate() + { + // Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here + UpdateManager.RestartAppWhenExited().Wait(); + } + + [BackgroundDependencyLoader] + private void load(NotificationOverlay notification, OsuGameBase game) + { + notificationOverlay = notification; + + if (game.IsDeployedBuild) + Schedule(() => checkForUpdateAsync()); + } + + private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) + { + //should we schedule a retry on completion of this check? + bool scheduleRetry = true; + + try + { + if (updateManager == null) updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); + + var info = await updateManager.CheckForUpdate(!useDeltaPatching); + if (info.ReleasesToApply.Count == 0) + //no updates available. bail and retry later. + return; + + if (notification == null) + { + notification = new UpdateProgressNotification(this) { State = ProgressNotificationState.Active }; + Schedule(() => notificationOverlay.Post(notification)); + } + + notification.Progress = 0; + notification.Text = @"Downloading update..."; + + try + { + await updateManager.DownloadReleases(info.ReleasesToApply, p => notification.Progress = p / 100f); + + notification.Progress = 0; + notification.Text = @"Installing update..."; + + await updateManager.ApplyReleases(info, p => notification.Progress = p / 100f); + + notification.State = ProgressNotificationState.Completed; + } + catch (Exception e) + { + if (useDeltaPatching) + { + Logger.Error(e, @"delta patching failed!"); + + //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) + //try again without deltas. + checkForUpdateAsync(false, notification); + scheduleRetry = false; + } + else + { + Logger.Error(e, @"update failed!"); + } + } + } + catch (Exception) + { + // we'll ignore this and retry later. can be triggered by no internet connection or thread abortion. + } + finally + { + if (scheduleRetry) + { + if (notification != null) + notification.State = ProgressNotificationState.Cancelled; + + //check again in 30 minutes. + Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30); + } + } + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + updateManager?.Dispose(); + } + + private class UpdateProgressNotification : ProgressNotification + { + private readonly SquirrelUpdateManager updateManager; + private OsuGame game; + + public UpdateProgressNotification(SquirrelUpdateManager updateManager) + { + this.updateManager = updateManager; + } + + protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification + { + Text = @"Update ready to install. Click to restart!", + Activated = () => + { + updateManager.PrepareUpdate(); + game.GracefullyExit(); + return true; + } + }; + + [BackgroundDependencyLoader] + private void load(OsuColour colours, OsuGame game) + { + this.game = game; + + IconContent.AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow) + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_upload, + Colour = Color4.White, + Size = new Vector2(20), + } + }); + } + } + } +} +#endif diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index 357cd49a5c..b61603dcc5 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -5,9 +5,7 @@ using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Development; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game; @@ -19,23 +17,13 @@ using osu.Game.Overlays.Notifications; using OpenTK; using OpenTK.Graphics; -#if NET_FRAMEWORK -using System; -using osu.Framework.Logging; -using Squirrel; -#endif - namespace osu.Desktop.Overlays { public class VersionManager : OverlayContainer { -#if NET_FRAMEWORK - private UpdateManager updateManager; -#endif - - private NotificationOverlay notificationOverlay; private OsuConfigManager config; private OsuGameBase game; + private NotificationOverlay notificationOverlay; public override bool HandleKeyboardInput => false; public override bool HandleMouseInput => false; @@ -102,8 +90,7 @@ namespace osu.Desktop.Overlays }; #if NET_FRAMEWORK - if (game.IsDeployedBuild) - checkForUpdateAsync(); + Add(new SquirrelUpdateManager()); #endif } @@ -143,90 +130,6 @@ namespace osu.Desktop.Overlays } } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - -#if NET_FRAMEWORK - updateManager?.Dispose(); -#endif - } - -#if NET_FRAMEWORK - private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null) - { - //should we schedule a retry on completion of this check? - bool scheduleRetry = true; - - try - { - if (updateManager == null) updateManager = await UpdateManager.GitHubUpdateManager(@"https://github.com/ppy/osu", @"osulazer", null, null, true); - - var info = await updateManager.CheckForUpdate(!useDeltaPatching); - if (info.ReleasesToApply.Count == 0) - //no updates available. bail and retry later. - return; - - if (notification == null) - { - notification = new UpdateProgressNotification { State = ProgressNotificationState.Active }; - Schedule(() => notificationOverlay.Post(notification)); - } - - Schedule(() => - { - notification.Progress = 0; - notification.Text = @"Downloading update..."; - }); - - try - { - await updateManager.DownloadReleases(info.ReleasesToApply, p => Schedule(() => notification.Progress = p / 100f)); - - Schedule(() => - { - notification.Progress = 0; - notification.Text = @"Installing update..."; - }); - - await updateManager.ApplyReleases(info, p => Schedule(() => notification.Progress = p / 100f)); - - Schedule(() => notification.State = ProgressNotificationState.Completed); - } - catch (Exception e) - { - if (useDeltaPatching) - { - Logger.Error(e, @"delta patching failed!"); - - //could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959) - //try again without deltas. - checkForUpdateAsync(false, notification); - scheduleRetry = false; - } - else - { - Logger.Error(e, @"update failed!"); - } - } - } - catch (Exception) - { - // we'll ignore this and retry later. can be triggered by no internet connection or thread abortion. - } - finally - { - if (scheduleRetry) - { - //check again in 30 minutes. - Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30); - if (notification != null) - notification.State = ProgressNotificationState.Cancelled; - } - } - } -#endif - protected override void PopIn() { this.FadeIn(1000); @@ -235,47 +138,5 @@ namespace osu.Desktop.Overlays protected override void PopOut() { } - - private class UpdateProgressNotification : ProgressNotification - { - private OsuGame game; - - protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification - { - Text = @"Update ready to install. Click to restart!", - Activated = () => - { - // Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here -#if NET_FRAMEWORK - UpdateManager.RestartAppWhenExited().Wait(); -#endif - game.GracefullyExit(); - return true; - } - }; - - [BackgroundDependencyLoader] - private void load(OsuColour colours, OsuGame game) - { - this.game = game; - - IconContent.AddRange(new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow) - }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_upload, - Colour = Color4.White, - Size = new Vector2(20), - } - }); - } - } } }