1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 02:15:17 +08:00

initial implementation

This commit is contained in:
smallketchup82 2024-06-26 15:25:41 -04:00
parent 87f2a23263
commit 0ee89183cc
No known key found for this signature in database
GPG Key ID: 7345B7C561243F1E
4 changed files with 38 additions and 123 deletions

View File

@ -19,7 +19,6 @@ using osu.Desktop.Windows;
using osu.Framework.Allocation;
using osu.Game.IO;
using osu.Game.IPC;
using osu.Game.Online.Multiplayer;
using osu.Game.Performance;
using osu.Game.Utils;
using SDL;
@ -103,36 +102,23 @@ namespace osu.Desktop
if (!string.IsNullOrEmpty(packageManaged))
return new NoActionUpdateManager();
switch (RuntimeInfo.OS)
{
case RuntimeInfo.Platform.Windows:
Debug.Assert(OperatingSystem.IsWindows());
return new SquirrelUpdateManager();
default:
return new SimpleUpdateManager();
}
return new VeloUpdateManager();
}
public override bool RestartAppWhenExited()
{
switch (RuntimeInfo.OS)
try
{
case RuntimeInfo.Platform.Windows:
Debug.Assert(OperatingSystem.IsWindows());
// Of note, this is an async method in squirrel that adds an arbitrary delay before returning
// likely to ensure the external process is in a good state.
//
// We're not waiting on that here, but the outro playing before the actual exit should be enough
// to cover this.
Squirrel.UpdateManager.RestartAppWhenExited().FireAndForget();
Process.Start(Process.GetCurrentProcess().MainModule?.FileName ?? throw new InvalidOperationException());
Environment.Exit(0);
return true;
}
catch (Exception e)
{
Logger.Error(e, "Failed to restart application");
return base.RestartAppWhenExited();
}
}
protected override void LoadComplete()
{

View File

@ -3,7 +3,6 @@
using System;
using System.IO;
using System.Runtime.Versioning;
using osu.Desktop.LegacyIpc;
using osu.Desktop.Windows;
using osu.Framework;
@ -14,7 +13,7 @@ using osu.Game;
using osu.Game.IPC;
using osu.Game.Tournament;
using SDL;
using Squirrel;
using Velopack;
namespace osu.Desktop
{
@ -66,10 +65,10 @@ namespace osu.Desktop
return;
}
}
setupSquirrel();
}
setupVelo();
// NVIDIA profiles are based on the executable name of a process.
// Lazer and stable share the same executable name.
// Stable sets this setting to "Off", which may not be what we want, so let's force it back to the default "Auto" on startup.
@ -177,32 +176,14 @@ namespace osu.Desktop
return false;
}
[SupportedOSPlatform("windows")]
private static void setupSquirrel()
private static void setupVelo()
{
SquirrelAwareApp.HandleEvents(onInitialInstall: (_, tools) =>
VelopackApp
.Build()
.WithFirstRun(v =>
{
tools.CreateShortcutForThisExe();
tools.CreateUninstallerRegistryEntry();
WindowsAssociationManager.InstallAssociations();
}, onAppUpdate: (_, tools) =>
{
tools.CreateUninstallerRegistryEntry();
WindowsAssociationManager.UpdateAssociations();
}, onAppUninstall: (_, tools) =>
{
tools.RemoveShortcutForThisExe();
tools.RemoveUninstallerRegistryEntry();
WindowsAssociationManager.UninstallAssociations();
}, onEveryRun: (_, _, _) =>
{
// While setting the `ProcessAppUserModelId` fixes duplicate icons/shortcuts on the taskbar, it currently
// causes the right-click context menu to function incorrectly.
//
// This may turn out to be non-required after an alternative solution is implemented.
// see https://github.com/clowd/Clowd.Squirrel/issues/24
// tools.SetProcessAppUserModelId();
});
if (OperatingSystem.IsWindows()) WindowsAssociationManager.InstallAssociations();
}).Run();
}
}
}

View File

@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Logging;
@ -10,30 +9,15 @@ using osu.Game;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Screens.Play;
using Squirrel.SimpleSplat;
using Squirrel.Sources;
using LogLevel = Squirrel.SimpleSplat.LogLevel;
using UpdateManager = osu.Game.Updater.UpdateManager;
using osu.Game.Updater;
namespace osu.Desktop.Updater
{
[SupportedOSPlatform("windows")]
public partial class SquirrelUpdateManager : UpdateManager
public partial class VeloUpdateManager : UpdateManager
{
private Squirrel.UpdateManager? updateManager;
private Velopack.UpdateManager? updateManager;
private INotificationOverlay notificationOverlay = null!;
public Task PrepareUpdateAsync() => Squirrel.UpdateManager.RestartAppWhenExited();
private static readonly Logger logger = Logger.GetLogger("updater");
/// <summary>
/// Whether an update has been downloaded but not yet applied.
/// </summary>
private bool updatePending;
private readonly SquirrelLogger squirrelLogger = new SquirrelLogger();
[Resolved]
private OsuGameBase game { get; set; } = null!;
@ -44,13 +28,11 @@ namespace osu.Desktop.Updater
private void load(INotificationOverlay notifications)
{
notificationOverlay = notifications;
SquirrelLocator.CurrentMutable.Register(() => squirrelLogger, typeof(ILogger));
}
protected override async Task<bool> PerformUpdateCheck() => await checkForUpdateAsync().ConfigureAwait(false);
private async Task<bool> checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification? notification = null)
private async Task<bool> checkForUpdateAsync(UpdateProgressNotification? notification = null)
{
// should we schedule a retry on completion of this check?
bool scheduleRecheck = true;
@ -63,27 +45,27 @@ namespace osu.Desktop.Updater
if (localUserInfo?.IsPlaying.Value == true)
return false;
updateManager ??= new Squirrel.UpdateManager(new GithubSource(@"https://github.com/ppy/osu", github_token, false), @"osulazer");
updateManager ??= new Velopack.UpdateManager(new Velopack.Sources.GithubSource(@"https://github.com/ppy/osu", github_token, false));
var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false);
var info = await updateManager.CheckForUpdatesAsync().ConfigureAwait(false);
if (info.ReleasesToApply.Count == 0)
if (info == null)
{
if (updatePending)
// If there is an update pending restart, show the notification again.
if (updateManager.IsUpdatePendingRestart)
{
// the user may have dismissed the completion notice, so show it again.
notificationOverlay.Post(new UpdateApplicationCompleteNotification
{
Activated = () =>
{
restartToApplyUpdate();
return true;
},
}
});
return true;
}
// no updates available. bail and retry later.
// Otherwise there's no updates available. Bail and retry later.
return false;
}
@ -103,33 +85,19 @@ namespace osu.Desktop.Updater
try
{
await updateManager.DownloadReleases(info.ReleasesToApply, p => notification.Progress = p / 100f).ConfigureAwait(false);
await updateManager.DownloadUpdatesAsync(info, p => notification.Progress = p / 100f).ConfigureAwait(false);
notification.StartInstall();
await updateManager.ApplyReleases(info, p => notification.Progress = p / 100f).ConfigureAwait(false);
notification.State = ProgressNotificationState.Completed;
updatePending = true;
}
catch (Exception e)
{
if (useDeltaPatching)
{
logger.Add(@"delta patching failed; will attempt full download!");
// could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959)
// try again without deltas.
await checkForUpdateAsync(false, notification).ConfigureAwait(false);
}
else
{
// In the case of an error, a separate notification will be displayed.
notification.FailDownload();
Logger.Error(e, @"update failed!");
}
}
}
catch (Exception)
{
// we'll ignore this and retry later. can be triggered by no internet connection or thread abortion.
@ -149,32 +117,12 @@ namespace osu.Desktop.Updater
private bool restartToApplyUpdate()
{
PrepareUpdateAsync()
.ContinueWith(_ => Schedule(() => game.AttemptExit()));
if (updateManager == null)
return false;
updateManager.WaitExitThenApplyUpdates(null);
Schedule(() => game.AttemptExit());
return true;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
updateManager?.Dispose();
}
private class SquirrelLogger : ILogger, IDisposable
{
public LogLevel Level { get; set; } = LogLevel.Info;
public void Write(string message, LogLevel logLevel)
{
if (logLevel < Level)
return;
logger.Add(message);
}
public void Dispose()
{
}
}
}
}

View File

@ -23,10 +23,10 @@
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
</ItemGroup>
<ItemGroup Label="Package References">
<PackageReference Include="Clowd.Squirrel" Version="2.11.1" />
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
<PackageReference Include="System.IO.Packaging" Version="8.0.0" />
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageReference Include="Velopack" Version="0.0.359" />
</ItemGroup>
<ItemGroup Label="Resources">
<EmbeddedResource Include="lazer.ico" />