Initial scaffolding: PS_Launcher v0.2
Client (C# / .NET 8 / WPF, MVVM via CommunityToolkit.Mvvm):
- PSLauncher.App: WPF UI dark theme (Epic-style sidebar + hero + big play button)
with UpdateAvailableDialog rendering Markdown release notes via Markdig.Wpf.
- PSLauncher.Core: services for installation registry (scans Proserve v{X.Y.Z}/),
process launcher, manifest fetch, SHA-256 integrity, HTTP download with
progress, ZIP install via .tmp + atomic rename, update orchestrator.
- PSLauncher.Models: RemoteManifest, InstalledVersion, LocalConfig DTOs.
Server (PHP 8 for OVH mutualisé, deployed under www/PS_Launcher/):
- Front controller + routes /manifest and /releasenotes/{version}.
- Static signed-manifest workflow with tools/sign-manifest.php CLI to
recompute SHA-256 and sizeBytes after each ZIP upload.
- .htaccess: HTTPS redirect, rewrite, security headers.
- config.example.php template; real config.php is gitignored.
Cohabiting versions: each release lives in its own Proserve v{version}/ folder
under installRoot. Old versions are never deleted automatically.
Roadmap: v0.3 = HTTP Range resume + Polly retry + state.json,
v0.4 = MySQL license + Ed25519 signatures + DPAPI, v0.5 = settings/UX polish.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
src/PSLauncher.Models/RemoteManifest.cs
Normal file
71
src/PSLauncher.Models/RemoteManifest.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace PSLauncher.Models;
|
||||
|
||||
public sealed class RemoteManifest
|
||||
{
|
||||
[JsonPropertyName("schemaVersion")]
|
||||
public int SchemaVersion { get; set; }
|
||||
|
||||
[JsonPropertyName("product")]
|
||||
public string Product { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("latest")]
|
||||
public string Latest { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("publishedAt")]
|
||||
public DateTime? PublishedAt { get; set; }
|
||||
|
||||
[JsonPropertyName("minLauncherVersion")]
|
||||
public string? MinLauncherVersion { get; set; }
|
||||
|
||||
[JsonPropertyName("versions")]
|
||||
public List<VersionManifest> Versions { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("signature")]
|
||||
public string? Signature { get; set; }
|
||||
}
|
||||
|
||||
public sealed class VersionManifest
|
||||
{
|
||||
[JsonPropertyName("version")]
|
||||
public string Version { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("releasedAt")]
|
||||
public DateTime ReleasedAt { get; set; }
|
||||
|
||||
[JsonPropertyName("executable")]
|
||||
public string Executable { get; set; } = "PROSERVE_UE_5_5.exe";
|
||||
|
||||
[JsonPropertyName("installFolderTemplate")]
|
||||
public string InstallFolderTemplate { get; set; } = "Proserve v{version}";
|
||||
|
||||
[JsonPropertyName("download")]
|
||||
public DownloadDescriptor Download { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("releaseNotesUrl")]
|
||||
public string? ReleaseNotesUrl { get; set; }
|
||||
|
||||
[JsonPropertyName("minLicenseDate")]
|
||||
public DateTime? MinLicenseDate { get; set; }
|
||||
|
||||
[JsonPropertyName("availableForDownload")]
|
||||
public bool AvailableForDownload { get; set; } = true;
|
||||
|
||||
[JsonPropertyName("heroImageUrl")]
|
||||
public string? HeroImageUrl { get; set; }
|
||||
|
||||
public string GetInstallFolderName() => InstallFolderTemplate.Replace("{version}", Version);
|
||||
}
|
||||
|
||||
public sealed class DownloadDescriptor
|
||||
{
|
||||
[JsonPropertyName("url")]
|
||||
public string Url { get; set; } = string.Empty;
|
||||
|
||||
[JsonPropertyName("sizeBytes")]
|
||||
public long SizeBytes { get; set; }
|
||||
|
||||
[JsonPropertyName("sha256")]
|
||||
public string Sha256 { get; set; } = string.Empty;
|
||||
}
|
||||
Reference in New Issue
Block a user