feat(launcher): implement verified atomic updates
This commit is contained in:
parent
2198a0cc8e
commit
2d2a5b5046
34 changed files with 6755 additions and 61 deletions
|
|
@ -1,7 +1,9 @@
|
|||
using System.Reflection;
|
||||
using AcDream.Launcher.Core.Installation;
|
||||
using AcDream.Launcher.Core.Launching;
|
||||
using AcDream.Launcher.Core.Orchestration;
|
||||
using AcDream.Launcher.Core.Profiles;
|
||||
using AcDream.Launcher.Core.Updates;
|
||||
using AcDream.Launcher.ViewModels;
|
||||
using AcDream.Platform;
|
||||
using Avalonia;
|
||||
|
|
@ -14,6 +16,8 @@ public sealed partial class App : Application
|
|||
{
|
||||
private LauncherOrchestrator? _orchestrator;
|
||||
private LauncherWindowViewModel? _viewModel;
|
||||
private HttpClient? _updateHttpClient;
|
||||
private ReleaseManifestClient? _manifestClient;
|
||||
|
||||
public override void Initialize() => AvaloniaXamlLoader.Load(this);
|
||||
|
||||
|
|
@ -23,6 +27,7 @@ public sealed partial class App : Application
|
|||
{
|
||||
ApplicationPathSet paths = ApplicationPathSet.Resolve();
|
||||
LauncherProfileStore profiles = LauncherProfileStore.ForApplicationPaths(paths);
|
||||
string rid = LauncherRuntimeIdentity.DetectRid();
|
||||
string executableSuffix = OperatingSystem.IsWindows() ? ".exe" : string.Empty;
|
||||
var installer = new LauncherInstaller(
|
||||
paths,
|
||||
|
|
@ -47,16 +52,38 @@ public sealed partial class App : Application
|
|||
$"Client content verification failed: {ex.Message}");
|
||||
}
|
||||
|
||||
var clientVersions = new ClientVersionStore(paths);
|
||||
_ = clientVersions.LoadAndRecoverAsync(rid)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
_orchestrator = new LauncherOrchestrator(
|
||||
profiles,
|
||||
paths,
|
||||
LauncherExecutableSet.FromDirectory(AppContext.BaseDirectory),
|
||||
LauncherExecutableSet.FromCurrentVersionStore(clientVersions),
|
||||
verification.Record,
|
||||
installationStatus: verification.Status);
|
||||
installationStatus: verification.Status,
|
||||
updateSessionBarrier: clientVersions.Barrier);
|
||||
_updateHttpClient = new HttpClient();
|
||||
_updateHttpClient.Timeout = TimeSpan.FromSeconds(15);
|
||||
_updateHttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(
|
||||
"acdream-launcher/1");
|
||||
_manifestClient = new ReleaseManifestClient(_updateHttpClient);
|
||||
var selfUpdates = new LauncherSelfUpdateManager(paths, _updateHttpClient);
|
||||
var updater = new LauncherUpdater(
|
||||
_manifestClient,
|
||||
_updateHttpClient,
|
||||
clientVersions,
|
||||
selfUpdates,
|
||||
GetLauncherVersion(),
|
||||
rid,
|
||||
AppContext.BaseDirectory,
|
||||
() => _orchestrator.GetSnapshot().Sessions.Any(session => session.IsActive));
|
||||
_viewModel = new LauncherWindowViewModel(
|
||||
_orchestrator,
|
||||
new AvaloniaUiDispatcher(),
|
||||
installer);
|
||||
installer,
|
||||
updater);
|
||||
_viewModel.Initialize();
|
||||
|
||||
desktop.MainWindow = new MainWindow
|
||||
|
|
@ -73,7 +100,25 @@ public sealed partial class App : Application
|
|||
{
|
||||
_viewModel?.Dispose();
|
||||
_orchestrator?.Dispose();
|
||||
_manifestClient?.Dispose();
|
||||
_updateHttpClient?.Dispose();
|
||||
_viewModel = null;
|
||||
_orchestrator = null;
|
||||
_manifestClient = null;
|
||||
_updateHttpClient = null;
|
||||
}
|
||||
|
||||
private static LauncherVersion GetLauncherVersion()
|
||||
{
|
||||
string? informationalVersion = typeof(App).Assembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
|
||||
.InformationalVersion;
|
||||
if (!LauncherVersion.TryParse(informationalVersion, out LauncherVersion? version))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Launcher informational version '{informationalVersion}' is not SemVer 2.0.");
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue