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 Versions { get; set; } = new(); [JsonPropertyName("signature")] public string? Signature { get; set; } [JsonPropertyName("launcher")] public LauncherInfo? Launcher { get; set; } } public sealed class LauncherInfo { [JsonPropertyName("version")] public string Version { get; set; } = string.Empty; [JsonPropertyName("minRequired")] public string? MinRequired { get; set; } [JsonPropertyName("download")] public DownloadDescriptor Download { get; set; } = new(); [JsonPropertyName("releaseNotesUrl")] public string? ReleaseNotesUrl { 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; /// /// Si true, version taggée BÊTA — affichage d'un badge orange dans le /// launcher + filtrage : seules les licenses avec canSeeBetas=true /// voient cette version, les autres l'ignorent (dans RebuildList). /// Default false → comportement standard (visible par tous). /// [JsonPropertyName("isBeta")] public bool IsBeta { get; set; } /// /// Note libre destinée aux testeurs, affichée en tooltip quand on hover le /// badge BÊTA. Optionnel. /// [JsonPropertyName("betaNotes")] public string? BetaNotes { get; set; } [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; /// /// Algo de vérif d'intégrité du ZIP téléchargé. /// Valeurs : "sha256" (défaut, voir ) — "none" (pas de vérif). /// La sécurité est déjà assurée par la signature Ed25519 du manifest et HTTPS ; /// le hash sert surtout à détecter la corruption disque/réseau sur 14 Go. /// Pour les très gros builds où on accepte le compromis, mettre "none" évite /// 30 s à 3 min de calcul à la fin du DL. /// [JsonPropertyName("hashAlgorithm")] public string? HashAlgorithm { get; set; } /// True si on doit vérifier le hash (sha256 non vide, non "REPLACE", algo != "none"). public bool ShouldVerifyHash => !string.IsNullOrEmpty(Sha256) && !Sha256.StartsWith("REPLACE", StringComparison.OrdinalIgnoreCase) && !string.Equals(HashAlgorithm, "none", StringComparison.OrdinalIgnoreCase); }